saadeghi / theme-change

Change CSS theme with toggle, buttons or select using CSS custom properties and localStorage
https://codepen.io/saadeghi/pen/OJypbNM
MIT License
1.33k stars 48 forks source link
css-custom-properties css-theme css-variables javascript localstorage theme theming

🎨 CSS Theme Change


🖥 Demo

image

💿 Use

JS

Use CDN:

<script src="https://cdn.jsdelivr.net/npm/theme-change@2.0.2/index.js"></script>
Or use NPM: Install: `npm i theme-change --save` and use it in your js file: ```js import { themeChange } from 'theme-change' themeChange() ```
or if it's a React project: Install: `npm i theme-change --save` and use it in your js file: ```js import { useEffect } from 'react' import { themeChange } from 'theme-change' useEffect(() => { themeChange(false) // 👆 false parameter is required for react project }, []) ```
or if it's a Vue 3 project (using composition API): Install: `npm i theme-change --save` and use it in your js file: ```js import { onMounted } from 'vue' import { themeChange } from 'theme-change' export default { setup() { onMounted(() => { themeChange(false) }) }, } ```
or if it's a Vue 2 project (using options API): Install: `npm i theme-change --save` and use it in your js file: ```js import { themeChange } from 'theme-change' export default { mounted: function () { themeChange(false) }, } ```
or if it's a Svelte project: Install: `npm i theme-change --save` and use it in your svelte component that uses one theme-change attributes: ```js import { onMount } from 'svelte' import { themeChange } from 'theme-change' // NOTE: the element that is using one of the theme attributes must be in the DOM on mount onMount(() => { themeChange(false) // 👆 false parameter is required for svelte }) ```
or if it's a SolidJS project: Install: `npm i theme-change --save` and use it in your js/jsx/tsx file: ```js import { onMount } from 'solid-js' import { themeChange } from 'theme-change' onMount(async () => { themeChange(); }) ```
or if it's a Astro project: Install: `npm i theme-change --save` and use it in your .astro file(s): Astro is a bit tricky because of how is rendering html page as a MPA (Multiple Pages Application) Astro projects are therefore subject to [FART](https://css-tricks.com/flash-of-inaccurate-color-theme-fart/) problem. To prevent this we will use the [is:inline](https://docs.astro.build/en/reference/directives-reference/#isinline) astro directive. If you want to apply themes on a single [astro page](https://docs.astro.build/en/core-concepts/astro-pages/) (remember Astro is an MPA framework) : `src/pages/mypage.astro` ```js --- --- My crazy credit page

Welcome to my credit page!

``` If you want to apply themes to all your [astro pages](https://docs.astro.build/en/core-concepts/astro-pages/), you need to execute both scripts in a Astro [layout](https://docs.astro.build/en/core-concepts/layouts/#sample-layout), it would need to wrap all your astro pages like so: `src/layouts/MyCrazyLayout.astro` ```html --- --- My Cool Astro Layout Wraping All My Pages
``` `src/pages/index.astro` ```js --- import MyCrazyLayout from '../layouts/MyCrazyLayout.astro'; ---

My page content, wrapped in a layout!

```

CSS

Set your themeable style as custom properties in CSS like this:

:root {
  --my-color: #fff;
  /* or any other variables/style */
}
[data-theme='dark'] {
  --my-color: #000;
}
[data-theme='pink'] {
  --my-color: #ffabc8;
}

then use your variables on any element

body {
  background-color: var(--my-color);
}

HTML

There are 3 options:

Advance use

Set theme based on OS color-scheme ```css @media (prefers-color-scheme: dark){ :root{ --my-color: #252b30; } } ```
Use with PurgeCSS If you're using [Purge CSS](https://purgecss.com/), you might need to [safe list](https://purgecss.com/safelisting.html#in-the-css-directly) your CSS using the comments below because your secondary themes will be purged - Safelist `[data-theme]` on postcss config ```js module.exports = { purge: { options: { safelist: [/data-theme$/], }, }, } ``` - Safelist inside CSS file ```css /*! purgecss start ignore */ [data-theme='dark'] { --my-color: #252b30; } /*! purgecss end ignore */ ```
Using custom localStorage key If you want to use a custom localStorage key, you can add it to the `data-key` attribute like this: ```html