Package Exports
- sthemer
- sthemer/Sthemer.svelte
- sthemer/context
- sthemer/hooks
- sthemer/mixins.less
- sthemer/mixins.scss
- sthemer/package.json
Readme
🌓 sthemer
A lightweight yet powerful solution to support multiple color schemes in your Svelte/SvelteKit application.
Advantages
🐤 lightweight (<1kb)
💪 powerful
👌 easy to use
🏃 fast and efficient
⏱️ supports SSR (Server-Side Rendering)
🪆 nested schemes
🦺 best TypeScript support (works with JavaScript projects too)
⛔ no external dependencies
Getting Started
⌨️ Install
sthemeras a dependency.npm install sthemer
🔧 Add the mixin globally.
svelte.config.js
import preprocess from 'svelte-preprocess' /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: preprocess({ scss: { prependData: `@import 'sthemer/mixins';`, }, }), } export default config
This example uses
scssas css preprocessor. Other formats are also supported. See the supported CSS preprocessors section for more details.📁 Wrap your code with the
Sthemer.sveltecomponent and define your preferred strategy.App.svelte or __layout.svelte
<script> import Sthemer from 'sthemer' </script> <Sthemer strategy="auto"> <!-- your application goes here --> </Sthemer>🎨 Define styles for your components.
Button.svelte
<button on:click> <slot /> </button> <style lang="scss"> button { // styles that apply to both schemes font-size: 1.3rem; padding: 10px 20px; border-radius: 8px; // theses styles will apply when the component gets rendered on a 'dark' wrapper @include on-dark { background-color: white; color: black; } // theses styles will apply when the component gets rendered on a 'light' wrapper @include on-light { background-color: black; color: white; } } </style>📖 Thats it. Play around and explore the docs to see some more examples.
⭐ Star this project on GitHub.
Thanks! This helps the project to grow.
Usage
supported CSS preprocessors
sthemer works with the most used CSS preprocessors to provide you with a good user experience. It is recommended to use one of the following options.
sass
Add the mixin globally.
svelte.config.js
import preprocess from 'svelte-preprocess' /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: preprocess({ sass: { prependData: `@import 'sthemer/mixins'`, }, }), } export default config
Define styles for your components.
Component.svelte
<button on:click> <slot /> </button> <style lang="sass"> button // theses styles will apply when the component gets rendered on a 'dark' wrapper @include on-dark background-color: white color: black // theses styles will apply when the component gets rendered on a 'light' wrapper @include on-light background-color: black color: white </style>
scss
Add the mixin globally.
svelte.config.js
import preprocess from 'svelte-preprocess' /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: preprocess({ scss: { prependData: `@import 'sthemer/mixins';`, }, }), } export default config
Define styles for your components.
Component.svelte
<button on:click> <slot /> </button> <style lang="scss"> button { // theses styles will apply when the component gets rendered on a 'dark' wrapper @include on-dark { background-color: white; color: black; } // theses styles will apply when the component gets rendered on a 'light' wrapper @include on-light { background-color: black; color: white; } } </style>
less
Add the mixin globally.
svelte.config.js
import preprocess from 'svelte-preprocess' /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: preprocess({ less: { prependData: `@import 'sthemer/mixins';`, }, }), } export default config
Define styles for your components.
Component.svelte
<button on:click> <slot /> </button> <style lang="less"> button { // theses styles will apply when the component gets rendered on a 'dark' wrapper .on-dark({ background-color: white; color: black; }); // theses styles will apply when the component gets rendered on a 'light' wrapper .on-light({ background-color: black; color: white; }); } </style>
CSS (no preprocessor)
Define styles for your components.
Component.svelte
<button on:click> <slot /> </button> <style> // theses styles will apply when the component gets rendered on a 'dark' wrapper :global(.sthemer-dark) button { background-color: white; color: black; } // theses styles will apply when the component gets rendered on a 'light' wrapper :global(.sthemer-dark) button { background-color: black; color: white; } </style>If you want to support multiple levels of nesting, you need to manually add them if you are not using a preprocessor like
sass,scssorless.// theses styles will apply when the component gets rendered on a 'dark' wrapper // (supports 3 levels of nesting) :global(.sthemer-dark) button, :global(.sthemer-light) :global(.sthemer-dark) button, :global(.sthemer-dark) :global(.sthemer-light) :global(.sthemer-dark) button { background-color: white; color: black; } // theses styles will apply when the component gets rendered on a 'light' wrapper // (supports 3 levels of nesting) :global(.sthemer-light) button, :global(.sthemer-dark) :global(.sthemer-light) button, :global(.sthemer-light) :global(.sthemer-dark) :global(.sthemer-light) button { background-color: black; color: white; }
Schemes
sthemer supports the built-in color schemes 'dark' and 'light'.
- light: The user expects a light background and dark text.
- dark: The user expects a dark background and light text.
Strategies
auto: Auto-detects the user's preferred color scheme.
The prefers-color-scheme media query is used to determine the user's preferred color scheme.
light: Use the light color scheme.
dark: Use the dark color scheme.
inverted: Use the inverted color scheme.
If used on a light color scheme, it will be dark and vice versa. Can be useful when using nested schemes. When used at the root, it uses the inverted color scheme from the 'auto'-strategy.
Server-Side Rendering (SSR)
TODO
Nested Schemes
TODO
Sponsors
Become a sponsor ❤️ if you want to support my open source contributions.
Thanks for sponsoring my open source work!