fix(cls): Server-side device visibility + aspect-ratio for featured-image

- functions-addon.php: Validacion centralizada con wp_is_mobile()
  Componentes con show_on_mobile=false NO se renderizan en mobile
  Previene CLS de elementos ocultos con CSS

- FeaturedImageRenderer: Agrega aspect-ratio 16/9 para reservar espacio
  Imagen usa object-fit:cover con position:absolute
  Metodo generateCSS() ahora publico para CriticalCSSService

- CriticalCSSService: Agrega featured-image a CRITICAL_RENDERERS
  CSS se inyecta en <head> antes de que cargue contenido

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-12-01 10:43:22 -06:00
parent ee28baafd8
commit c0172467b3
3 changed files with 72 additions and 6 deletions

View File

@@ -47,9 +47,17 @@ final class FeaturedImageRenderer implements RendererInterface
return '';
}
$css = $this->generateCSS($data);
$html = $this->buildHTML($data);
// Si is_critical=true, CSS ya fue inyectado en <head> por CriticalCSSService
$isCritical = $data['visibility']['is_critical'] ?? false;
if ($isCritical) {
return $html; // Solo HTML, sin CSS inline
}
// CSS inline para componentes no críticos
$css = $this->generateCSS($data);
return sprintf("<style>%s</style>\n%s", $css, $html);
}
@@ -84,7 +92,16 @@ final class FeaturedImageRenderer implements RendererInterface
return is_singular() && has_post_thumbnail();
}
private function generateCSS(array $data): string
/**
* Generar CSS usando CSSGeneratorService
*
* Este método es público para que CriticalCSSService pueda
* generar CSS crítico antes de wp_head sin duplicar lógica.
*
* @param array $data Datos del componente
* @return string CSS generado
*/
public function generateCSS(array $data): string
{
$spacing = $data['spacing'] ?? [];
$effects = $data['visual_effects'] ?? [];
@@ -92,6 +109,8 @@ final class FeaturedImageRenderer implements RendererInterface
$marginTop = $spacing['margin_top'] ?? '1rem';
$marginBottom = $spacing['margin_bottom'] ?? '2rem';
// Aspect ratio para prevenir CLS - reserva espacio antes de que imagen cargue
$aspectRatio = $spacing['aspect_ratio'] ?? '16/9';
$borderRadius = $effects['border_radius'] ?? '12px';
$boxShadow = $effects['box_shadow'] ?? '0 8px 24px rgba(0, 0, 0, 0.1)';
@@ -104,7 +123,7 @@ final class FeaturedImageRenderer implements RendererInterface
$cssRules = [];
// Container styles
// Container styles con aspect-ratio para prevenir CLS
$cssRules[] = $this->cssGenerator->generate('.featured-image-container', [
'border-radius' => $borderRadius,
'overflow' => 'hidden',
@@ -112,14 +131,21 @@ final class FeaturedImageRenderer implements RendererInterface
'margin-top' => $marginTop,
'margin-bottom' => $marginBottom,
'transition' => "transform {$transitionDuration} ease, box-shadow {$transitionDuration} ease",
'aspect-ratio' => $aspectRatio,
'position' => 'relative',
'background-color' => '#f0f0f0',
]);
// Image styles
// Image styles - object-fit para llenar el contenedor con aspect-ratio
$cssRules[] = $this->cssGenerator->generate('.featured-image-container img', [
'width' => '100%',
'height' => 'auto',
'height' => '100%',
'object-fit' => 'cover',
'display' => 'block',
'transition' => "transform {$transitionDuration} ease",
'position' => 'absolute',
'top' => '0',
'left' => '0',
]);
// Hover effect