Skip to content

Commit dec331c

Browse files
committed
feat: add skeleton loader for FCP - prevents empty content flash
- Add 8 skeleton cards in grid placeholder - Add skeleton CSS with pulse animation - Hide when .card elements render - Improves FCP/LCP visually
1 parent 4495656 commit dec331c

2 files changed

Lines changed: 60 additions & 5 deletions

File tree

index.html

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<title>CSS Ref</title>
4949

5050
<!-- Preload Critical Assets -->
51-
<link rel="preload" id="preload-css" href="dist/bundle.0f8ba566.css" as="style" crossorigin />
51+
<link rel="preload" id="preload-css" href="dist/bundle.e3fffefb.css" as="style" crossorigin />
5252
<link rel="preload" id="preload-js" href="dist/bundle.40ef2de0.js" as="script" crossorigin />
5353

5454
<!-- Critical CSS (inlined for faster FCP/LCP) -->
@@ -65,9 +65,9 @@
6565
<noscript>
6666
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Varela+Round&display=swap&text=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%20.,!?;:'&quot;()-_@#$%&amp;*+=&lt;&gt;[]{}|\/^~`" />
6767
</noscript>
68-
<!-- Open Props is bundled in dist/bundle.0f8ba566.css -->
69-
<link rel="stylesheet" id="bundle-css" href="dist/bundle.0f8ba566.css" media="print" onload="this.media='all'" />
70-
<noscript><link rel="stylesheet" href="dist/bundle.0f8ba566.css" /></noscript>
68+
<!-- Open Props is bundled in dist/bundle.e3fffefb.css -->
69+
<link rel="stylesheet" id="bundle-css" href="dist/bundle.e3fffefb.css" media="print" onload="this.media='all'" />
70+
<noscript><link rel="stylesheet" href="dist/bundle.e3fffefb.css" /></noscript>
7171
</head>
7272
<body
7373
data-signals="{
@@ -1133,7 +1133,19 @@ <h1 class="visually-hidden">CSS Ref - CSS Properties Reference</h1>
11331133
id="grid"
11341134
class="is-grid"
11351135
data-effect="$viewMode; $selectedProp; $activeCollection; renderGrid(filtered($query, $activeCats, $activeInterops, $activeBrowsers), $selectedProp)"
1136-
></div>
1136+
>
1137+
<!-- Skeleton placeholder for FCP -->
1138+
<div class="grid-skeleton" aria-label="Loading properties...">
1139+
<div class="skeleton-card"></div>
1140+
<div class="skeleton-card"></div>
1141+
<div class="skeleton-card"></div>
1142+
<div class="skeleton-card"></div>
1143+
<div class="skeleton-card"></div>
1144+
<div class="skeleton-card"></div>
1145+
<div class="skeleton-card"></div>
1146+
<div class="skeleton-card"></div>
1147+
</div>
1148+
</div>
11371149
</main>
11381150
</div>
11391151
<!-- End Grid View -->

src/styles/card.css

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,53 @@ main {
4747

4848
#grid.is-grid {
4949
display: grid;
50+
}
51+
52+
/* ── Skeleton Loading State ── */
53+
.grid-skeleton {
54+
display: grid;
5055
grid-template-columns: repeat(4, 1fr);
5156
gap: var(--space-2xs);
5257
}
5358

59+
@media (max-width: 900px) {
60+
.grid-skeleton {
61+
grid-template-columns: repeat(3, 1fr);
62+
}
63+
}
64+
65+
@media (max-width: 640px) {
66+
.grid-skeleton {
67+
grid-template-columns: repeat(2, 1fr);
68+
}
69+
}
70+
71+
.skeleton-card {
72+
background: var(--card);
73+
border: 1px solid var(--border);
74+
border-radius: var(--radius-lg);
75+
padding: var(--space-m);
76+
min-height: 120px;
77+
position: relative;
78+
overflow: hidden;
79+
animation: skeleton-pulse 1.5s ease-in-out infinite;
80+
}
81+
82+
@keyframes skeleton-pulse {
83+
0%, 100% { opacity: 1; }
84+
50% { opacity: 0.5; }
85+
}
86+
87+
/* Hide skeleton when grid has real content (cards) */
88+
.is-grid:has(.card) .grid-skeleton {
89+
display: none;
90+
}
91+
92+
/* Show skeleton when no cards exist yet */
93+
.is-grid:not(:has(.card)) .grid-skeleton {
94+
display: grid;
95+
}
96+
5497
/* Responsive breakpoints for grid columns */
5598
@media (max-width: 900px) {
5699
#grid.is-grid {

0 commit comments

Comments
 (0)