Skip to content

Commit e8a38eb

Browse files
Fix color flash on page load when setting dark/light mode (#2110)
Fixes #2112 Previously, when loading the landing page, the page colors would flash briefly. For light mode the background flashes black before the white background loads. For dark mode, the header would flash white, and the text black, before the correct colors render. This was happening because the script was being executed after the page had finished loading, likely due to how the page is packaged into chunks. To fix this, the dark mode script is now set inline, so will be part of the generated HTML. This fixes #2105 Here's a video showing what was happening before. https://github.com/user-attachments/assets/2019277f-d947-4289-bf41-89fef7aa3c26 --------- Co-authored-by: Philipp Spiess <hello@philippspiess.com>
1 parent 256b4cc commit e8a38eb

File tree

21 files changed

+85
-73
lines changed

21 files changed

+85
-73
lines changed

src/app/(docs)/docs/installation/(tabs)/framework-guides/page.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ function GuideTile({ guide }: { guide: Guide }) {
7979
</h4>
8080
<p className="text-sm leading-6 text-slate-700 dark:text-slate-400">{guide.tile.description}</p>
8181
</div>
82-
<div className="dark:highlight-white/5 flex h-14 w-14 flex-none items-center justify-center overflow-hidden rounded-full bg-white ring-1 shadow ring-slate-900/5 dark:bg-slate-800">
82+
<div className="dark:highlight-white/5 flex h-14 w-14 flex-none items-center justify-center overflow-hidden rounded-full bg-white shadow ring-1 ring-slate-900/5 dark:bg-slate-800">
8383
{LogoDark ? (
8484
<>
8585
<Logo className="block dark:hidden" />

src/app/layout.tsx

+44-38
Original file line numberDiff line numberDiff line change
@@ -77,50 +77,52 @@ const ubuntuMono = localFont({
7777

7878
const js = String.raw;
7979
let darkModeScript = js`
80-
try {
81-
_updateTheme(localStorage.currentTheme)
82-
} catch (_) {}
80+
if (!('_updateTheme' in window)) {
81+
window._updateTheme = function updateTheme(theme) {
82+
let classList = document.documentElement.classList;
8383
84-
try {
85-
if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
86-
document.documentElement.classList.add('os-macos')
87-
}
88-
} catch (_) {}
84+
classList.remove("light", "dark", "system");
85+
document.querySelectorAll('meta[name="theme-color"]').forEach(el => el.remove())
86+
if (theme === 'dark') {
87+
classList.add('dark')
8988
90-
function _updateTheme(theme) {
91-
let classList = document.documentElement.classList;
89+
let meta = document.createElement('meta')
90+
meta.name = 'theme-color'
91+
meta.content = 'oklch(.13 .028 261.692)'
92+
document.head.appendChild(meta)
93+
} else if (theme === 'light') {
94+
classList.add('light')
9295
93-
classList.remove("light", "dark", "system");
94-
document.querySelectorAll('meta[name="theme-color"]').forEach(el => el.remove())
95-
if (theme === 'dark') {
96-
classList.add('dark')
96+
let meta = document.createElement('meta')
97+
meta.name = 'theme-color'
98+
meta.content = 'white'
99+
document.head.appendChild(meta)
100+
} else {
101+
classList.add('system')
97102
98-
let meta = document.createElement('meta')
99-
meta.name = 'theme-color'
100-
meta.content = 'oklch(.13 .028 261.692)'
101-
document.head.appendChild(meta)
102-
} else if (theme === 'light') {
103-
classList.add('light')
103+
let meta1 = document.createElement('meta')
104+
meta1.name = 'theme-color'
105+
meta1.content = 'oklch(.13 .028 261.692)'
106+
meta1.media = '(prefers-color-scheme: dark)'
107+
document.head.appendChild(meta1)
104108
105-
let meta = document.createElement('meta')
106-
meta.name = 'theme-color'
107-
meta.content = 'white'
108-
document.head.appendChild(meta)
109-
} else {
110-
classList.add('system')
109+
let meta2 = document.createElement('meta')
110+
meta2.name = 'theme-color'
111+
meta2.content = 'white'
112+
meta2.media = '(prefers-color-scheme: light)'
113+
document.head.appendChild(meta2)
114+
}
115+
}
111116
112-
let meta1 = document.createElement('meta')
113-
meta1.name = 'theme-color'
114-
meta1.content = 'oklch(.13 .028 261.692)'
115-
meta1.media = '(prefers-color-scheme: dark)'
116-
document.head.appendChild(meta1)
117+
try {
118+
_updateTheme(localStorage.currentTheme)
119+
} catch (_) {}
117120
118-
let meta2 = document.createElement('meta')
119-
meta2.name = 'theme-color'
120-
meta2.content = 'white'
121-
meta2.media = '(prefers-color-scheme: light)'
122-
document.head.appendChild(meta2)
123-
}
121+
try {
122+
if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
123+
document.documentElement.classList.add('os-macos')
124+
}
125+
} catch (_) {}
124126
}
125127
`;
126128

@@ -159,7 +161,11 @@ export default async function RootLayout({
159161
<meta name="application-name" content="Tailwind CSS" />
160162
<meta name="msapplication-TileColor" content="#38bdf8" />
161163
<meta name="msapplication-config" content={v("/favicons/browserconfig.xml")} />
162-
164+
<script type="text/javascript" dangerouslySetInnerHTML={{ __html: darkModeScript }}></script>
165+
{/*
166+
We inject the script via the <Script/> tag again, since we found the regular `<script>`
167+
tag to not execute when rendering a not-found page.
168+
*/}
163169
<Script src={`data:text/javascript;base64,${btoa(darkModeScript)}`} />
164170
</head>
165171
<body>

src/blog/building-react-and-vue-support-for-tailwind-ui/index.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ export default function Example() {
296296
>
297297
<Menu.Items
298298
static
299-
className="ring-opacity-5 absolute right-0 mt-2 w-56 origin-top-right rounded-md bg-white ring-1 shadow-lg ring-black focus:outline-none"
299+
className="ring-opacity-5 absolute right-0 mt-2 w-56 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black focus:outline-none"
300300
>
301301
<div className="py-1">
302302
<Menu.Item>
@@ -377,7 +377,7 @@ Here's what one of our dropdown examples looks like in our internal authoring fo
377377
leave-end="transform opacity-0 scale-95"
378378
>
379379
<x-menu-items
380-
class="ring-opacity-5 absolute right-0 mt-2 w-56 origin-top-right rounded-md bg-white ring-1 shadow-lg ring-black focus:outline-none"
380+
class="ring-opacity-5 absolute right-0 mt-2 w-56 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black focus:outline-none"
381381
>
382382
<div class="py-1">
383383
<x-menu-item>

src/blog/tailwind-ui-now-with-react-and-vue-support/index.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export default function Example() {
6464
aria-hidden="true"
6565
className={classNames(
6666
enabled ? "translate-x-5" : "translate-x-0",
67-
"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white ring-0 shadow transition duration-200 ease-in-out",
67+
"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out",
6868
)}
6969
/>
7070
</Switch>

src/blog/tailwindcss-v4/index.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ The new `starting` variant adds support for the new CSS [`@starting-style`](http
564564
<div
565565
popover="auto"
566566
id="my-popover"
567-
className="relative inset-y-0 mx-auto my-auto transform overflow-hidden rounded-lg bg-white px-4 pt-5 pb-4 text-left opacity-0 ring shadow-xl ring-black/5 transition-all transition-discrete duration-500 sm:w-full sm:max-w-96 sm:p-6 dark:bg-gray-800 dark:inset-ring dark:inset-ring-white/5 [&:is([open],:popover-open)]:opacity-100 [@starting-style]:[&:is([open],:popover-open)]:opacity-0"
567+
className="relative inset-y-0 mx-auto my-auto transform overflow-hidden rounded-lg bg-white px-4 pt-5 pb-4 text-left opacity-0 shadow-xl ring ring-black/5 transition-all transition-discrete duration-500 sm:w-full sm:max-w-96 sm:p-6 dark:bg-gray-800 dark:inset-ring dark:inset-ring-white/5 [&:is([open],:popover-open)]:opacity-100 [@starting-style]:[&:is([open],:popover-open)]:opacity-0"
568568
>
569569
<div>
570570
<div className="mx-auto flex size-12 items-center justify-center rounded-full bg-indigo-50 dark:bg-indigo-600/10">

src/components/header.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ function VersionPicker() {
6161
</MenuButton>
6262
<MenuItems
6363
anchor="bottom start"
64-
className="mt-2 w-28 rounded-xl bg-white p-1 py-1 text-xs/7 font-medium text-gray-950 tabular-nums ring shadow-sm ring-gray-950/5 [--anchor-offset:calc(var(--spacing)*-1)] dark:bg-gray-950 dark:text-white dark:ring-white/10"
64+
className="mt-2 w-28 rounded-xl bg-white p-1 py-1 text-xs/7 font-medium text-gray-950 tabular-nums shadow-sm ring ring-gray-950/5 [--anchor-offset:calc(var(--spacing)*-1)] dark:bg-gray-950 dark:text-white dark:ring-white/10"
6565
>
6666
<MenuItem disabled>
6767
<div className="flex items-center justify-between gap-2 rounded-lg px-2.5 data-active:bg-gray-950/5 dark:data-active:bg-white/10">

src/components/home/transforms-3d.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function Transforms3d() {
2929
src={_3dTransformsImg.src}
3030
className="absolute inset-0 size-82 rounded-2xl shadow-2xl outline outline-gray-950/5 transition duration-300 transform-3d"
3131
/>
32-
<div className="col-start-1 row-start-1 size-82 rounded-2xl bg-gray-950/5 p-2 inset-ring shadow-inner inset-ring-gray-950/5 dark:bg-white/10 dark:inset-ring-white/10">
32+
<div className="col-start-1 row-start-1 size-82 rounded-2xl bg-gray-950/5 p-2 shadow-inner inset-ring inset-ring-gray-950/5 dark:bg-white/10 dark:inset-ring-white/10">
3333
<div className="size-full rounded-lg outline outline-gray-950/10 outline-dashed"></div>
3434
</div>
3535
</div>

src/components/home/why-tailwind-css-section.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export default function WhyTailwindCssSection() {
284284
return (
285285
<div key={name} data-target className="flex snap-center snap-always flex-col items-center gap-2">
286286
<Code>{name}</Code>
287-
<div className="inset-ring ring shadow ring-gray-950/10 inset-ring-white/20">
287+
<div className="shadow ring inset-ring ring-gray-950/10 inset-ring-white/20">
288288
<div className={clsx("size-(--size) bg-white/15", className)} />
289289
</div>
290290
</div>
@@ -617,7 +617,7 @@ export default function WhyTailwindCssSection() {
617617
</div>
618618
</div>
619619
<div className="@container relative isolate flex h-full items-center justify-center">
620-
<div className="absolute bottom-12 -left-2 z-1 w-[60cqw] shrink-0 divide-y divide-gray-950/5 rounded-xl bg-white inset-ring shadow-2xl inset-ring-gray-950/5 dark:divide-white/5 dark:bg-gray-800 dark:inset-ring-white/5">
620+
<div className="absolute bottom-12 -left-2 z-1 w-[60cqw] shrink-0 divide-y divide-gray-950/5 rounded-xl bg-white shadow-2xl inset-ring inset-ring-gray-950/5 dark:divide-white/5 dark:bg-gray-800 dark:inset-ring-white/5">
621621
{[
622622
{ src: avatar4.src, name: "Will Winton", role: "Director of Operations" },
623623
{ src: avatar5.src, name: "Kristin Yardly", role: "Marketing Coordinator" },
@@ -641,7 +641,7 @@ export default function WhyTailwindCssSection() {
641641
);
642642
})}
643643
</div>
644-
<div className="absolute -right-3 bottom-12 w-[50cqw] shrink-0 divide-y divide-gray-950/5 rounded-xl bg-white inset-ring shadow-2xl inset-ring-gray-950/5 dark:divide-white/5 dark:bg-gray-800 dark:inset-ring-white/5">
644+
<div className="absolute -right-3 bottom-12 w-[50cqw] shrink-0 divide-y divide-gray-950/5 rounded-xl bg-white shadow-2xl inset-ring inset-ring-gray-950/5 dark:divide-white/5 dark:bg-gray-800 dark:inset-ring-white/5">
645645
{[
646646
{ src: avatar1.src, name: "سارة أحمد", role: "مديرة مشاريع" },
647647
{ src: avatar2.src, name: "علي محمد", role: "مطور برمجيات" },

src/components/theme-toggle.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function onChange(theme: Theme, setTheme: (theme: Theme) => void) {
3838
function ThemeToggleButton(props: React.ComponentProps<typeof Radio>) {
3939
return (
4040
<Radio
41-
className="rounded-full p-1.5 *:size-7 data-checked:bg-white data-checked:inset-ring data-checked:ring data-checked:ring-gray-950/10 data-checked:inset-ring-white/10 sm:p-0 dark:data-checked:bg-gray-700 dark:data-checked:text-white dark:data-checked:ring-transparent"
41+
className="rounded-full p-1.5 *:size-7 data-checked:bg-white data-checked:ring data-checked:inset-ring data-checked:ring-gray-950/10 data-checked:inset-ring-white/10 sm:p-0 dark:data-checked:bg-gray-700 dark:data-checked:text-white dark:data-checked:ring-transparent"
4242
{...props}
4343
/>
4444
);

src/docs/background-position.mdx

+7-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,13 @@ Use utilities like `bg-center`, `bg-right`, and `bg-left-top` to control the pos
164164

165165
### Using a custom value
166166

167-
<UsingACustomValue utility="bg" value="center_top_1rem" name="background position" variable="bg-position" dataType="position"/>
167+
<UsingACustomValue
168+
utility="bg"
169+
value="center_top_1rem"
170+
name="background position"
171+
variable="bg-position"
172+
dataType="position"
173+
/>
168174

169175
### Responsive design
170176

src/docs/box-shadow.mdx

+3-3
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,15 @@ Use utilities like `inset-shadow-xs` and `inset-shadow-sm` to apply an inset box
182182
<div className="flex items-center justify-around gap-4 bg-white p-6 font-mono font-bold">
183183
<div className="flex flex-col items-center">
184184
<p className="mb-3 text-center font-mono text-sm font-medium text-gray-500">inset-shadow-2xs</p>
185-
<div className="size-24 rounded-lg bg-white inset-shadow-2xs ring-1 ring-black/5"></div>
185+
<div className="size-24 rounded-lg bg-white ring-1 inset-shadow-2xs ring-black/5"></div>
186186
</div>
187187
<div className="flex flex-col items-center">
188188
<p className="mb-3 text-center font-mono text-sm font-medium text-gray-500">inset-shadow-xs</p>
189-
<div className="size-24 rounded-lg bg-white inset-shadow-xs ring-1 ring-black/5"></div>
189+
<div className="size-24 rounded-lg bg-white ring-1 inset-shadow-xs ring-black/5"></div>
190190
</div>
191191
<div className="flex flex-col items-center">
192192
<p className="mb-3 text-center font-mono text-sm font-medium text-gray-500">inset-shadow-sm</p>
193-
<div className="size-24 rounded-lg bg-white inset-shadow-sm ring-1 ring-black/5"></div>
193+
<div className="size-24 rounded-lg bg-white ring-1 inset-shadow-sm ring-black/5"></div>
194194
</div>
195195
</div>
196196
}

src/docs/box-sizing.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ This means a 100px &times; 100px element with a 2px border and 4px of padding on
4343
</div>
4444
{/* Right chip */}
4545
<div className="w-full">
46-
<div className="absolute top-1/2 right-0 h-2 w-px -translate-y-1 translate-x-px rounded-full bg-sky-400"></div>
46+
<div className="absolute top-1/2 right-0 h-2 w-px translate-x-px -translate-y-1 rounded-full bg-sky-400"></div>
4747
</div>
4848
</div>
4949
</div>
@@ -121,7 +121,7 @@ This means a 100px &times; 100px element with a 2px border and 4px of padding on
121121
</div>
122122
{/* Right chip */}
123123
<div className="w-full">
124-
<div className="absolute top-1/2 right-0 h-2 w-px -translate-y-1 translate-x-px rounded-full bg-blue-400"></div>
124+
<div className="absolute top-1/2 right-0 h-2 w-px translate-x-px -translate-y-1 rounded-full bg-blue-400"></div>
125125
</div>
126126
</div>
127127
</div>

src/docs/colors.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ Use the `dark` variant to write classes like `dark:bg-gray-800` that only apply
356356
<div className="grid grid-cols-1 sm:grid-cols-2">
357357
<div className="p-8 pt-7">
358358
<p className="mb-2 text-sm font-medium text-gray-500">Light mode</p>
359-
<div className="rounded-lg bg-white px-6 py-8 ring shadow-xl ring-gray-900/5">
359+
<div className="rounded-lg bg-white px-6 py-8 shadow-xl ring ring-gray-900/5">
360360
<div>
361361
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
362362
<svg
@@ -386,7 +386,7 @@ Use the `dark` variant to write classes like `dark:bg-gray-800` that only apply
386386
</div>
387387
<div className="bg-gray-900 p-8 pt-7">
388388
<p className="mb-2 text-sm font-medium text-gray-400">Dark mode</p>
389-
<div className="rounded-lg bg-gray-800 px-6 py-8 ring shadow-xl ring-gray-900/5">
389+
<div className="rounded-lg bg-gray-800 px-6 py-8 shadow-xl ring ring-gray-900/5">
390390
<div>
391391
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
392392
<svg

src/docs/dark-mode.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ To make this as easy as possible, Tailwind includes a `dark` variant that lets y
1919
<div className="grid grid-cols-1 sm:grid-cols-2">
2020
<div className="p-8 pt-7">
2121
<p className="mb-2 text-sm font-medium text-gray-500">Light mode</p>
22-
<div className="rounded-lg bg-white px-6 py-8 ring shadow-xl ring-gray-900/5">
22+
<div className="rounded-lg bg-white px-6 py-8 shadow-xl ring ring-gray-900/5">
2323
<div>
2424
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
2525
<svg
@@ -49,7 +49,7 @@ To make this as easy as possible, Tailwind includes a `dark` variant that lets y
4949
</div>
5050
<div className="bg-gray-900 p-8 pt-7">
5151
<p className="mb-2 text-sm font-medium text-gray-400">Dark mode</p>
52-
<div className="rounded-lg bg-gray-800 px-6 py-8 ring shadow-xl ring-gray-900/5">
52+
<div className="rounded-lg bg-gray-800 px-6 py-8 shadow-xl ring ring-gray-900/5">
5353
<div>
5454
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
5555
<svg

src/docs/font-family.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Use utilities like `font-sans` and `font-mono` to set the font family of an elem
6666

6767
### Using a custom value
6868

69-
<UsingACustomValue utility="font" name="font family" value="Open_Sans" element="p" dataType="family-name"/>
69+
<UsingACustomValue utility="font" name="font family" value="Open_Sans" element="p" dataType="family-name" />
7070

7171
### Responsive design
7272

src/docs/hover-focus-and-other-states.mdx

+3-3
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ When you need to style an element based on the state of some _parent_ element, m
744744
{
745745
<a
746746
href="#"
747-
className="group mx-auto block max-w-xs space-y-3 rounded-lg bg-white p-4 ring-1 shadow-lg ring-gray-900/5 hover:bg-sky-500 hover:ring-sky-500 dark:bg-white/5 dark:ring-white/10"
747+
className="group mx-auto block max-w-xs space-y-3 rounded-lg bg-white p-4 shadow-lg ring-1 ring-gray-900/5 hover:bg-sky-500 hover:ring-sky-500 dark:bg-white/5 dark:ring-white/10"
748748
>
749749
<div className="flex items-center space-x-3">
750750
<svg className="h-6 w-6 stroke-sky-500 group-hover:stroke-white" fill="none" viewBox="0 0 24 24">
@@ -1572,7 +1572,7 @@ Use utilities with no variant to target light mode, and use the `dark` variant t
15721572
<div className="grid grid-cols-1 sm:grid-cols-2">
15731573
<div className="p-8 pt-7">
15741574
<p className="mb-2 text-sm font-medium text-gray-500">Light mode</p>
1575-
<div className="rounded-lg bg-white px-6 py-8 ring-1 shadow-xl ring-gray-900/5">
1575+
<div className="rounded-lg bg-white px-6 py-8 shadow-xl ring-1 ring-gray-900/5">
15761576
<div>
15771577
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
15781578
<svg
@@ -1601,7 +1601,7 @@ Use utilities with no variant to target light mode, and use the `dark` variant t
16011601
</div>
16021602
<div className="border-l border-l-transparent bg-black/90 p-8 pt-7 dark:border-l-white/10 dark:bg-transparent">
16031603
<p className="mb-2 text-sm font-medium text-gray-400">Dark mode</p>
1604-
<div className="rounded-lg bg-gray-800 px-6 py-8 ring-1 shadow-xl ring-gray-900/5">
1604+
<div className="rounded-lg bg-gray-800 px-6 py-8 shadow-xl ring-1 ring-gray-900/5">
16051605
<div>
16061606
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
16071607
<svg

src/docs/max-width.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Use utilities like `max-w-sm` and `max-w-xl` to set an element to a fixed maximu
158158

159159
<Example resizable>
160160
{
161-
<div className="dark:highlight-white/5 relative mx-auto flex max-w-md items-center gap-6 overflow-hidden rounded-xl bg-white ring-1 shadow-lg ring-black/5 dark:bg-gray-800">
161+
<div className="dark:highlight-white/5 relative mx-auto flex max-w-md items-center gap-6 overflow-hidden rounded-xl bg-white shadow-lg ring-1 ring-black/5 dark:bg-gray-800">
162162
<img
163163
className="absolute -left-6 h-28 w-28 rounded-full"
164164
src="https://images.unsplash.com/photo-1501196354995-cbb51c65aaea?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=facearea&facepad=4&w=256&h=256&q=80"

0 commit comments

Comments
 (0)