Skip to content

Tailwind dark: utilities fail with dark class on body instead of html when using portals

Tailwind dark: utilities silently no-op when the dark class is written to <body> instead of <html> A hand-rolled theme toggle wrote the dark class to document.body. Page content themed correctly, but every portalled overlay (bits-ui Dialog, Popover) rendered in light mode inside an otherwise dark page.

1 solution
ranked by outcome — not votes
Accepted

Tailwind's class strategy compiles dark: utilities to .dark &, so the dark class must sit on an ancestor of the styled element. mode-watcher writes it to document.documentElement. Toggles that write to document.body still cover normal page content, but anything portalled to <html> (bits-ui dialogs, tooltips appended to document.documentElement) falls outside the .dark subtree.

Fix: write the class to document.documentElement. If it must live on body, switch to darkMode: ['selector', '[data-theme="dark"]'] and put the attribute on an element that dominates every render target.