Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork0
postcss plugin to handle prefers-color-scheme
License
vnphanquang/postcss-color-scheme
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Postcss plugin for handlingprefers-color-scheme, plusTailwind V4 variants (optional).
Input
.my-class {color: black;@color-scheme dark {color: white;}}
Output
.my-class {color: black;html[data-color-scheme='dark']& {color: white;}@media (prefers-color-scheme: dark) {html:not([data-color-scheme='light'])& {color: white;}}}
Note
Noticepostcss-color-scheme preservesCSS nesting as it has landed in all major browsers as of this writing. If you need to target older browsers, consider adding additional transform withpostcss-nesting (notpostcss-nested).
npm install --save-dev postcss postcss-color-schemeyarn add -D postcss postcss-color-schemepnpm add -D postcss postcss-color-scheme
Add to your postcss config
/*@file: postcss.config.js */importpostcssColorSchemefrom'postcss-color-scheme';exportdefault{plugins:[postcssColorScheme()],};
You might have noticed a couple of opinionated code at the top of this document. These are extracted from my daily work, and currently serve my use cases very well. Should you have concerns, suggestions for improvements, or solution for making this more generic, feel free to open an issue. Thanks!
Rely on
data-color-schemefor explicit theme settings. This requires settingdata-color-schemeon thehtmlelement.Provide fallback when user has not explicitly select a theme. Let's refer to the demo above, with rules enumerated:
/* (1) */.my-class {color: black;}/* (2) */html[data-color-scheme='dark'] .my-class {color: white;}/* (3) */@media (prefers-color-scheme: dark) {html:not([data-color-scheme='light']) .my-class {color: white;}}
Imagine your system provides 3 options:
dark,light, andsystem(default, auto, i.e respect system preferences). There are 4 possible scenarios.User has not explicitly selected a theme (theme =
system), and the system preferslight(prefers-color-scheme=light):--> (1) applies.
User has not explicitly selected a theme (theme =
system), and the system prefersdark(prefers-color-scheme=dark):--> (1) & (3) applies, (3) takes precedence because of its higher specificity.User selected
dark(data-color-themeset todarkonhtml) :--> (1) & (2) applies, (2) takes precedence because of its higher specificity.
User selected
light(data-color-themeset tolightonhtml) :--> (1) applies.
Loadingflowchart TD A[Has user explicitly selected theme?] -->|Yes| B[Which mode?] B --> Light B --> Dark A -->|No| C[prefers-color-scheme?] C -->Light C -->Dark
What about thelight-dark() Function?
As of this writing, thelight-dark() CSS function already has pretty good support across browsers,and is a valid solution to handle light-dark mode. However, colors declared withlight-dark are not as flexible. Consider the following setup:
:root {--regular-color: green;--light-dark-color:light-dark(red, blue);}
We can use utilize the relatively newrelative color syntax with--regular-color...
.regular {/* turn from green to redish while keeping perceived lightness and chroma */color:oklch(fromvar(--regular-color) l ccalc(h-120));}
...while it is not possible today withlight-dark:
.light-dark {/* invalid and ignored by browser */color:oklch(fromvar(--light-dark-color) l ccalc(h-120));}
Althoughcolor-mix does seem towork. Overall, until browser has better support forlight-dark,postcss-color-scheme providesa more universal solution.
This plugin essentially provides a new at-rule,@color-scheme; it requires a parameter with valueof eitherdark orlight.
:root {@color-scheme light {color: black;}@color-scheme dark {color: white;}}
Styling in Svelte is component-scoped by default. From Svelte 5, you can wrap the@color-scheme at-rule in a:global block. For example:
<main></main><stylelang="postcss">:global {main {@color-schemedark {color: white;}}}</style>
Tailwind Support
From Tailwind V4, simply add the following to your CSS:
/* app.css, or any Tailwind-aware context */@import'tailwindcss';@import'postcss-color-scheme/tailwind.css';
This exposes thelight: anddark: variants for usage in markup. For example:
<inputclass="text-white dark:text-black light:border-gray-500"/>
Note that these variants and the@color-scheme at-rule are complementary and not exclusive. Feelfree to use both: the former is for markup, while the latter is for CSS.
Note
For Tailwind V3 and below, please usepostcss-color-scheme v1.
About
postcss plugin to handle prefers-color-scheme
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.