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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user