Skip to content

Fix color flash on page load when setting dark/light mode #2110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function GuideTile({ guide }: { guide: Guide }) {
</h4>
<p className="text-sm leading-6 text-slate-700 dark:text-slate-400">{guide.tile.description}</p>
</div>
<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">
<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">
{LogoDark ? (
<>
<Logo className="block dark:hidden" />
Expand Down
82 changes: 44 additions & 38 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,50 +77,52 @@ const ubuntuMono = localFont({

const js = String.raw;
let darkModeScript = js`
try {
_updateTheme(localStorage.currentTheme)
} catch (_) {}
if (!('_updateTheme' in window)) {
window._updateTheme = function updateTheme(theme) {
let classList = document.documentElement.classList;

try {
if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
document.documentElement.classList.add('os-macos')
}
} catch (_) {}
classList.remove("light", "dark", "system");
document.querySelectorAll('meta[name="theme-color"]').forEach(el => el.remove())
if (theme === 'dark') {
classList.add('dark')

function _updateTheme(theme) {
let classList = document.documentElement.classList;
let meta = document.createElement('meta')
meta.name = 'theme-color'
meta.content = 'oklch(.13 .028 261.692)'
document.head.appendChild(meta)
} else if (theme === 'light') {
classList.add('light')

classList.remove("light", "dark", "system");
document.querySelectorAll('meta[name="theme-color"]').forEach(el => el.remove())
if (theme === 'dark') {
classList.add('dark')
let meta = document.createElement('meta')
meta.name = 'theme-color'
meta.content = 'white'
document.head.appendChild(meta)
} else {
classList.add('system')

let meta = document.createElement('meta')
meta.name = 'theme-color'
meta.content = 'oklch(.13 .028 261.692)'
document.head.appendChild(meta)
} else if (theme === 'light') {
classList.add('light')
let meta1 = document.createElement('meta')
meta1.name = 'theme-color'
meta1.content = 'oklch(.13 .028 261.692)'
meta1.media = '(prefers-color-scheme: dark)'
document.head.appendChild(meta1)

let meta = document.createElement('meta')
meta.name = 'theme-color'
meta.content = 'white'
document.head.appendChild(meta)
} else {
classList.add('system')
let meta2 = document.createElement('meta')
meta2.name = 'theme-color'
meta2.content = 'white'
meta2.media = '(prefers-color-scheme: light)'
document.head.appendChild(meta2)
}
}

let meta1 = document.createElement('meta')
meta1.name = 'theme-color'
meta1.content = 'oklch(.13 .028 261.692)'
meta1.media = '(prefers-color-scheme: dark)'
document.head.appendChild(meta1)
try {
_updateTheme(localStorage.currentTheme)
} catch (_) {}

let meta2 = document.createElement('meta')
meta2.name = 'theme-color'
meta2.content = 'white'
meta2.media = '(prefers-color-scheme: light)'
document.head.appendChild(meta2)
}
try {
if (/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
document.documentElement.classList.add('os-macos')
}
} catch (_) {}
}
`;

Expand Down Expand Up @@ -159,7 +161,11 @@ export default async function RootLayout({
<meta name="application-name" content="Tailwind CSS" />
<meta name="msapplication-TileColor" content="#38bdf8" />
<meta name="msapplication-config" content={v("/favicons/browserconfig.xml")} />

<script type="text/javascript" dangerouslySetInnerHTML={{ __html: darkModeScript }}></script>
{/*
We inject the script via the <Script/> tag again, since we found the regular `<script>`
tag to not execute when rendering a not-found page.
*/}
<Script src={`data:text/javascript;base64,${btoa(darkModeScript)}`} />
</head>
<body>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export default function Example() {
>
<Menu.Items
static
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"
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"
>
<div className="py-1">
<Menu.Item>
Expand Down Expand Up @@ -377,7 +377,7 @@ Here's what one of our dropdown examples looks like in our internal authoring fo
leave-end="transform opacity-0 scale-95"
>
<x-menu-items
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"
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"
>
<div class="py-1">
<x-menu-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default function Example() {
aria-hidden="true"
className={classNames(
enabled ? "translate-x-5" : "translate-x-0",
"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white ring-0 shadow transition duration-200 ease-in-out",
"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out",
)}
/>
</Switch>
Expand Down
2 changes: 1 addition & 1 deletion src/blog/tailwindcss-v4/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ The new `starting` variant adds support for the new CSS [`@starting-style`](http
<div
popover="auto"
id="my-popover"
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"
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"
>
<div>
<div className="mx-auto flex size-12 items-center justify-center rounded-full bg-indigo-50 dark:bg-indigo-600/10">
Expand Down
2 changes: 1 addition & 1 deletion src/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function VersionPicker() {
</MenuButton>
<MenuItems
anchor="bottom start"
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"
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"
>
<MenuItem disabled>
<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">
Expand Down
2 changes: 1 addition & 1 deletion src/components/home/transforms-3d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function Transforms3d() {
src={_3dTransformsImg.src}
className="absolute inset-0 size-82 rounded-2xl shadow-2xl outline outline-gray-950/5 transition duration-300 transform-3d"
/>
<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">
<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">
<div className="size-full rounded-lg outline outline-gray-950/10 outline-dashed"></div>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/components/home/why-tailwind-css-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ export default function WhyTailwindCssSection() {
return (
<div key={name} data-target className="flex snap-center snap-always flex-col items-center gap-2">
<Code>{name}</Code>
<div className="inset-ring ring shadow ring-gray-950/10 inset-ring-white/20">
<div className="shadow ring inset-ring ring-gray-950/10 inset-ring-white/20">
<div className={clsx("size-(--size) bg-white/15", className)} />
</div>
</div>
Expand Down Expand Up @@ -617,7 +617,7 @@ export default function WhyTailwindCssSection() {
</div>
</div>
<div className="@container relative isolate flex h-full items-center justify-center">
<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">
<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">
{[
{ src: avatar4.src, name: "Will Winton", role: "Director of Operations" },
{ src: avatar5.src, name: "Kristin Yardly", role: "Marketing Coordinator" },
Expand All @@ -641,7 +641,7 @@ export default function WhyTailwindCssSection() {
);
})}
</div>
<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">
<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">
{[
{ src: avatar1.src, name: "سارة أحمد", role: "مديرة مشاريع" },
{ src: avatar2.src, name: "علي محمد", role: "مطور برمجيات" },
Expand Down
2 changes: 1 addition & 1 deletion src/components/theme-toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function onChange(theme: Theme, setTheme: (theme: Theme) => void) {
function ThemeToggleButton(props: React.ComponentProps<typeof Radio>) {
return (
<Radio
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"
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"
{...props}
/>
);
Expand Down
8 changes: 7 additions & 1 deletion src/docs/background-position.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,13 @@ Use utilities like `bg-center`, `bg-right`, and `bg-left-top` to control the pos

### Using a custom value

<UsingACustomValue utility="bg" value="center_top_1rem" name="background position" variable="bg-position" dataType="position"/>
<UsingACustomValue
utility="bg"
value="center_top_1rem"
name="background position"
variable="bg-position"
dataType="position"
/>

### Responsive design

Expand Down
6 changes: 3 additions & 3 deletions src/docs/box-shadow.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,15 @@ Use utilities like `inset-shadow-xs` and `inset-shadow-sm` to apply an inset box
<div className="flex items-center justify-around gap-4 bg-white p-6 font-mono font-bold">
<div className="flex flex-col items-center">
<p className="mb-3 text-center font-mono text-sm font-medium text-gray-500">inset-shadow-2xs</p>
<div className="size-24 rounded-lg bg-white inset-shadow-2xs ring-1 ring-black/5"></div>
<div className="size-24 rounded-lg bg-white ring-1 inset-shadow-2xs ring-black/5"></div>
</div>
<div className="flex flex-col items-center">
<p className="mb-3 text-center font-mono text-sm font-medium text-gray-500">inset-shadow-xs</p>
<div className="size-24 rounded-lg bg-white inset-shadow-xs ring-1 ring-black/5"></div>
<div className="size-24 rounded-lg bg-white ring-1 inset-shadow-xs ring-black/5"></div>
</div>
<div className="flex flex-col items-center">
<p className="mb-3 text-center font-mono text-sm font-medium text-gray-500">inset-shadow-sm</p>
<div className="size-24 rounded-lg bg-white inset-shadow-sm ring-1 ring-black/5"></div>
<div className="size-24 rounded-lg bg-white ring-1 inset-shadow-sm ring-black/5"></div>
</div>
</div>
}
Expand Down
4 changes: 2 additions & 2 deletions src/docs/box-sizing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ This means a 100px &times; 100px element with a 2px border and 4px of padding on
</div>
{/* Right chip */}
<div className="w-full">
<div className="absolute top-1/2 right-0 h-2 w-px -translate-y-1 translate-x-px rounded-full bg-sky-400"></div>
<div className="absolute top-1/2 right-0 h-2 w-px translate-x-px -translate-y-1 rounded-full bg-sky-400"></div>
</div>
</div>
</div>
Expand Down Expand Up @@ -121,7 +121,7 @@ This means a 100px &times; 100px element with a 2px border and 4px of padding on
</div>
{/* Right chip */}
<div className="w-full">
<div className="absolute top-1/2 right-0 h-2 w-px -translate-y-1 translate-x-px rounded-full bg-blue-400"></div>
<div className="absolute top-1/2 right-0 h-2 w-px translate-x-px -translate-y-1 rounded-full bg-blue-400"></div>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/docs/colors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ Use the `dark` variant to write classes like `dark:bg-gray-800` that only apply
<div className="grid grid-cols-1 sm:grid-cols-2">
<div className="p-8 pt-7">
<p className="mb-2 text-sm font-medium text-gray-500">Light mode</p>
<div className="rounded-lg bg-white px-6 py-8 ring shadow-xl ring-gray-900/5">
<div className="rounded-lg bg-white px-6 py-8 shadow-xl ring ring-gray-900/5">
<div>
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
<svg
Expand Down Expand Up @@ -386,7 +386,7 @@ Use the `dark` variant to write classes like `dark:bg-gray-800` that only apply
</div>
<div className="bg-gray-900 p-8 pt-7">
<p className="mb-2 text-sm font-medium text-gray-400">Dark mode</p>
<div className="rounded-lg bg-gray-800 px-6 py-8 ring shadow-xl ring-gray-900/5">
<div className="rounded-lg bg-gray-800 px-6 py-8 shadow-xl ring ring-gray-900/5">
<div>
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
<svg
Expand Down
4 changes: 2 additions & 2 deletions src/docs/dark-mode.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ To make this as easy as possible, Tailwind includes a `dark` variant that lets y
<div className="grid grid-cols-1 sm:grid-cols-2">
<div className="p-8 pt-7">
<p className="mb-2 text-sm font-medium text-gray-500">Light mode</p>
<div className="rounded-lg bg-white px-6 py-8 ring shadow-xl ring-gray-900/5">
<div className="rounded-lg bg-white px-6 py-8 shadow-xl ring ring-gray-900/5">
<div>
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
<svg
Expand Down Expand Up @@ -49,7 +49,7 @@ To make this as easy as possible, Tailwind includes a `dark` variant that lets y
</div>
<div className="bg-gray-900 p-8 pt-7">
<p className="mb-2 text-sm font-medium text-gray-400">Dark mode</p>
<div className="rounded-lg bg-gray-800 px-6 py-8 ring shadow-xl ring-gray-900/5">
<div className="rounded-lg bg-gray-800 px-6 py-8 shadow-xl ring ring-gray-900/5">
<div>
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
<svg
Expand Down
2 changes: 1 addition & 1 deletion src/docs/font-family.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Use utilities like `font-sans` and `font-mono` to set the font family of an elem

### Using a custom value

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

### Responsive design

Expand Down
6 changes: 3 additions & 3 deletions src/docs/hover-focus-and-other-states.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ When you need to style an element based on the state of some _parent_ element, m
{
<a
href="#"
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"
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"
>
<div className="flex items-center space-x-3">
<svg className="h-6 w-6 stroke-sky-500 group-hover:stroke-white" fill="none" viewBox="0 0 24 24">
Expand Down Expand Up @@ -1572,7 +1572,7 @@ Use utilities with no variant to target light mode, and use the `dark` variant t
<div className="grid grid-cols-1 sm:grid-cols-2">
<div className="p-8 pt-7">
<p className="mb-2 text-sm font-medium text-gray-500">Light mode</p>
<div className="rounded-lg bg-white px-6 py-8 ring-1 shadow-xl ring-gray-900/5">
<div className="rounded-lg bg-white px-6 py-8 shadow-xl ring-1 ring-gray-900/5">
<div>
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
<svg
Expand Down Expand Up @@ -1601,7 +1601,7 @@ Use utilities with no variant to target light mode, and use the `dark` variant t
</div>
<div className="border-l border-l-transparent bg-black/90 p-8 pt-7 dark:border-l-white/10 dark:bg-transparent">
<p className="mb-2 text-sm font-medium text-gray-400">Dark mode</p>
<div className="rounded-lg bg-gray-800 px-6 py-8 ring-1 shadow-xl ring-gray-900/5">
<div className="rounded-lg bg-gray-800 px-6 py-8 shadow-xl ring-1 ring-gray-900/5">
<div>
<span className="inline-flex items-center justify-center rounded-md bg-indigo-500 p-2 shadow-lg">
<svg
Expand Down
2 changes: 1 addition & 1 deletion src/docs/max-width.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ Use utilities like `max-w-sm` and `max-w-xl` to set an element to a fixed maximu

<Example resizable>
{
<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">
<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">
<img
className="absolute -left-6 h-28 w-28 rounded-full"
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"
Expand Down
Loading