From 15b88b708700efa06579f390171f61e3997bc101 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Sat, 7 Mar 2026 16:56:59 +0100 Subject: [PATCH] feat: add skeleton loader to prevent FOUC during CSS load Replace unstyled content flash with pulsing gray placeholder shapes while the deferred Tailwind stylesheet loads. Uses a 'loading' class on that critical CSS uses to show skeleton / hide content, removed by the stylesheet's onload handler. Includes noscript fallback to bypass skeleton when JS is disabled. Confab-Link: http://localhost:8080/sessions/edb1b7b0-da66-4486-bd9c-d1cfa7553b88 --- _includes/layouts/base.njk | 25 +++++++++++++++++++++++-- css/critical.css | 8 ++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 67fae63..45c2d6c 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -1,5 +1,5 @@ - + {# OG image resolution handled by og-fix transform in eleventy.config.js to bypass Eleventy 3.x parallel rendering race condition (#3183). @@ -57,7 +57,7 @@ {# Critical CSS — inlined for fast first paint #} {# Defer full stylesheet — loads after first paint #} - + @@ -89,6 +89,9 @@ [x-data] > .flex.border-b { display: none !important; } /* Hide loading spinners and JS-only buttons */ [x-show*="loading"], button[\\@click*="fetch"], button[\\@click*="loadMore"] { display: none !important; } + /* Show content and hide skeleton for no-JS (stylesheet loads synchronously via noscript link) */ + .page-skeleton { display: none !important; } + html.loading main.container > .page-content { display: block !important; } @@ -277,6 +280,23 @@
+ {# Skeleton loader — shown until Tailwind stylesheet loads #} + + +
{% if withSidebar and page.url == "/" and homepageConfig and homepageConfig.sections %} {# Homepage: builder controls its own layout and sidebar #} {{ content | safe }} @@ -301,6 +321,7 @@ {% else %} {{ content | safe }} {% endif %} +