fix(CLS): Add hero critical CSS to HEAD to prevent layout shift

- Add roi_output_hero_critical_css() function to inject CSS in <head>
- CSS now loads BEFORE hero HTML renders, preventing CLS
- Update min_height from 120px to 260px to match actual content height
- Update title_min_height from 3rem to 3.5rem
- Add responsive breakpoints for mobile (200px min-height)

This fixes CLS in Lighthouse Lab tests (was 0.265, now should be ~0.01)

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankZamora
2025-11-27 12:08:10 -06:00
parent 7a539a498f
commit 7e13678e0b
2 changed files with 61 additions and 2 deletions

View File

@@ -365,3 +365,62 @@ function roi_clear_critical_css_cache() {
}
add_action( 'after_switch_theme', 'roi_clear_critical_css_cache' );
add_action( 'customize_save_after', 'roi_clear_critical_css_cache' );
/**
* Output Hero Section Critical CSS
*
* This CSS is ALWAYS injected in the <head> to prevent CLS (Cumulative Layout Shift)
* by reserving space for the hero section BEFORE it renders.
*
* The min-height values match the actual rendered height (~260px on desktop)
* to prevent any layout shift when the dynamic CSS loads.
*
* @since 1.0.21
* @see Public/Hero/Infrastructure/Ui/HeroRenderer.php
*/
function roi_output_hero_critical_css() {
// Only output on single posts where hero is displayed
if ( ! is_single() ) {
return;
}
// Check if hero is enabled (read from database)
$is_enabled = roi_get_component_setting( 'hero', 'visibility', 'is_enabled', true );
if ( ! $is_enabled ) {
return;
}
$critical_css = '
/* Hero Critical CSS - Prevent CLS */
.hero-section {
min-height: 260px;
background: linear-gradient(135deg, #1e3a5f 0%, #2c5282 100%);
padding: 3rem 0;
margin-bottom: 1.5rem;
box-sizing: border-box;
}
.hero-section__title {
min-height: 3.5rem;
margin-bottom: 0;
}
.hero-section__badge {
min-height: 32px;
display: inline-block;
}
@media (max-width: 767.98px) {
.hero-section {
min-height: 200px;
}
.hero-section__title {
min-height: 2.5rem;
}
}
';
// Minify CSS
$critical_css = preg_replace( '/\s+/', ' ', $critical_css );
$critical_css = trim( $critical_css );
echo '<style id="roi-hero-critical-css">' . $critical_css . '</style>' . "\n";
}
add_action( 'wp_head', 'roi_output_hero_critical_css', 2 );

View File

@@ -224,14 +224,14 @@
"min_height": {
"type": "text",
"label": "Altura mínima del hero",
"default": "120px",
"default": "260px",
"editable": true,
"description": "Altura mínima del contenedor hero para prevenir layout shift (CLS)"
},
"title_min_height": {
"type": "text",
"label": "Altura mínima del título",
"default": "3rem",
"default": "3.5rem",
"editable": true,
"description": "Altura mínima del título para prevenir layout shift (CLS)"
},