CSS dark mode backgrounds switch automatically with the user system preference when built with CSS custom properties and the prefers-color-scheme media query, and they can also respond to a manual toggle button if you add a small JavaScript helper.
Loading Background Gen…
Generates CSS custom property declarations for light and dark backgrounds
Includes prefers-color-scheme media query for system-level dark mode
Preview light and dark backgrounds side by side in the tool
Supports class-based dark mode toggling for manual override
Drop the Background Gen into any page — blog post, product docs, intranet, school portal — with a single line of HTML. Your visitors get the full tool, processed entirely in their browser. No backend, no uploads, no signup.
Embed code
<iframe
src="https://www.fixtools.io/css-tool/background-gen?embed=1"
width="100%"
height="780"
frameborder="0"
style="border:0;border-radius:16px;max-width:900px;"
title="Background Gen by FixTools"
loading="lazy"
allow="clipboard-write"
></iframe>Attribution-friendly: a small "Powered by FixTools" link appears in the embed footer.
A CSS custom property dark mode system defines background colours as variables on :root and overrides them inside the prefers-color-scheme: dark media query. A minimal setup: :root { --bg-page: #ffffff; --bg-card: #f8fafc; } @media (prefers-color-scheme: dark) { :root { --bg-page: #0f172a; --bg-card: #1e293b; } }. Every element using background: var(--bg-page) automatically switches colour based on the system preference. Adding a new themed element requires only using the existing variable, not creating a new media query rule. This scales to dozens of background colours without duplication.
Class-based dark mode toggling provides user control independent of system settings. Define the dark background overrides under a .dark class on the html or body element: html.dark { --bg-page: #0f172a; } JavaScript toggles the class based on a user preference stored in localStorage. This approach works alongside prefers-color-scheme: use the media query as the default and let JavaScript override it when the user explicitly chooses. A common implementation checks localStorage first, falls back to prefers-color-scheme, and applies the result before the first paint to avoid a flash of the wrong theme.
Background colour selection for dark mode is not simply inverting the light mode palette. Light mode backgrounds are near-white (95-99% lightness in HSL). Dark mode backgrounds work best in the 5-20% lightness range. Surface elevation in dark mode should use progressively lighter backgrounds: #0f172a for the page background, #1e293b for cards, and #334155 for elevated surfaces. Using very dark backgrounds like #000000 creates harsh contrast at the edges of components and makes shadows invisible. The Material Design and Tailwind dark mode palettes both use slate-series greys rather than pure black for this reason.
Text and accent colour contrast must be recalculated for dark backgrounds, not simply darkened or lightened mechanically. The WCAG 2.1 contrast ratio of 4.5:1 for body text and 3:1 for large text applies in both modes, but the colours that hit those ratios in light mode often fail in dark mode and vice versa. Body text on a #0f172a page background should typically land near #e2e8f0 (close to 13:1 contrast) for comfortable reading, while muted text should sit near #94a3b8 (about 5.5:1) to remain accessible without competing for attention. Accent colours often need to shift toward higher lightness in dark mode: a brand blue that reads well at #2563eb on white may need to lighten to #60a5fa on a dark background to maintain visual identity and pass contrast checks at the same time.
Enter light mode and dark mode background colours for each surface level (page background, card background, surface). The tool generates the :root CSS variable declarations, the @media (prefers-color-scheme: dark) overrides, and an optional .dark class toggle pattern for JavaScript-controlled dark mode switching.
Step-by-step guide to css dark mode background generator:
Enter light and dark background colours
Input background colours for page, card, and surface levels for both light and dark modes. The tool accepts hex, rgb, and hsl values. For a coherent palette, start from a single hue and adjust only lightness across the surface scale rather than picking different colours per level, which usually looks accidental.
Choose implementation approach
Select prefers-color-scheme only for a system-driven theme, class-based toggle only for a manual user setting that ignores the OS preference, or both layered so the system preference is the default and the manual toggle overrides it. Both layered is the most accommodating choice for real users.
Preview both modes
Toggle the preview between light and dark to check contrast and surface depth at each elevation level. Look at the borders between adjacent surfaces; if you cannot distinguish a card from the page background at one mode, widen the lightness gap between those two variables before exporting.
Copy the CSS variable block
Copy the :root variable declarations, media query overrides, and the optional .dark class selector. Paste into your global stylesheet at the top of the CSS so the variables are defined before any rule that consumes them, and add the inline anti-flash script to your HTML head if you enabled the class-based toggle.
Common situations where this approach makes a real difference:
Developer adding dark mode to an existing site
A developer is retrofitting dark mode to a site with hardcoded background colours throughout the CSS. They use the tool to generate a CSS variable system with five background levels matching the existing light mode colours. They replace every hardcoded background-color with the corresponding var() call, then add the dark mode media query block. The refactor takes one afternoon and adds full system-aware dark mode support without JavaScript.
Designer building a new dark-first design system
A designer starts a new project with dark mode as the default and adds a light mode toggle. They define dark backgrounds at five elevation levels from #0a0f1e to #2d3748, then derive light equivalents by inverting the lightness values. The tool generates both :root and html.light class declarations. The dark backgrounds are the :root default, and light overrides use the .light class toggled by JavaScript.
Frontend engineer preventing white flash on dark mode page load
A user reports seeing a white flash on every page load when their system is in dark mode. The engineer identifies that the dark class is applied by a deferred JavaScript file that runs after first paint. They move the theme detection to an inline script in the HTML head that reads localStorage synchronously and applies the class before the page renders. The tool provides the minimal inline script pattern alongside the CSS variable declarations.
Accessibility specialist verifying dark mode contrast
An accessibility specialist checks every text-on-background combination in the dark mode palette using the background colour generator contrast checker. They find that muted text at #64748b on the darkest background (#0f172a) falls below AA at 3.2:1. They adjust the muted text colour to #94a3b8, which passes AA at 5.1:1. All verified passing combinations are documented in the design system colour token specification.
Get better results with these expert suggestions:
Define a full surface scale, not just two colours
Define --bg-base, --bg-surface, --bg-elevated, and --bg-overlay as four separate levels. In dark mode, each should be approximately 5-8 lightness points apart. This creates visible depth between components at all levels without resorting to box shadows, which are often invisible on dark backgrounds.
Use color-scheme: light dark on :root
Adding color-scheme: light dark to :root tells the browser to apply system-appropriate scrollbar, form control, and selection colours for both modes automatically. This handles many native UI elements without explicit CSS overrides.
Shadow intensity needs adjustment in dark mode
Box shadows using rgba(0,0,0,0.2) are invisible on dark backgrounds because the shadow colour blends into the dark surface. Increase shadow opacity to rgba(0,0,0,0.5) or switch to rgba(0,0,0,0.8) in dark mode, or use coloured shadows that contrast with the dark surface.
Set transition on background-color for smooth theme switching
Add transition: background-color 0.2s ease, color 0.2s ease to the body or :root. When the dark class is toggled, the background and text colours animate between values rather than switching instantly. Wrap this in @media (prefers-reduced-motion: no-preference) so users who prefer reduced motion get an instant switch.
Use HSL variables for easy dark mode colour derivation
Define --hue and --saturation separately from lightness. In dark mode, change only --bg-lightness from 97% to 8% per surface level. All surfaces share the same hue and saturation, keeping the palette harmonious across both modes.
Avoid the flash of incorrect theme
Apply the theme class to the html element in an inline script block in the head before the body renders. Reading localStorage and applying .dark synchronously prevents the white flash on page load for users in dark mode.
Test dark mode at real device brightness
Dark backgrounds look different at 50% screen brightness than at 100%. Test dark mode backgrounds on a physical device at typical ambient brightness settings to confirm the surface elevation differences remain visible.
More use-case guides for the same tool:
Other tools you might find useful:
Open the full Background Gen — free, no account needed, works on any device.
Open Background Gen →Free · No account needed · Works on any device