Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/saadeghi/theme-change
Change CSS theme with toggle, buttons or select using CSS custom properties and localStorage
https://github.com/saadeghi/theme-change
css-custom-properties css-theme css-variables javascript localstorage theme theming
Last synced: 3 days ago
JSON representation
Change CSS theme with toggle, buttons or select using CSS custom properties and localStorage
- Host: GitHub
- URL: https://github.com/saadeghi/theme-change
- Owner: saadeghi
- License: mit
- Created: 2020-04-24T11:17:37.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2024-02-19T05:40:34.000Z (11 months ago)
- Last Synced: 2025-01-16T18:19:37.461Z (10 days ago)
- Topics: css-custom-properties, css-theme, css-variables, javascript, localstorage, theme, theming
- Language: JavaScript
- Homepage: https://codepen.io/saadeghi/pen/OJypbNM
- Size: 97.7 KB
- Stars: 1,508
- Watchers: 7
- Forks: 46
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- jimsghstars - saadeghi/theme-change - Change CSS theme with toggle, buttons or select using CSS custom properties and localStorage (JavaScript)
README
# 🎨 CSS Theme Change
- A tiny JS script to handle CSS themes
- Change CSS theme using `button`, `toggle` or a ``
- It saves chosen theme in browser and uses it again when page reloads[![][build]][build-url] [![][install-size]][install-size-url] [![][js]][js-url]
[![][npm]][npm-url] [![][dl]][npm-url] [![][commit]][gh-url]# 🖥 Demo
- See example code on [codepen](https://codepen.io/saadeghi/pen/OJypbNM)
- See Sample site on [Netlify](https://css-theme-changer.netlify.app/)
- See Vue Example on [Vercel](https://vue-3-theme.vercel.app)[![image](https://user-images.githubusercontent.com/7342023/80218042-e3c67e00-8655-11ea-94e8-925d0dcbfd57.gif)](#)
# 💿 Use
## JS
Use CDN:
```html
```
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
---
---
// ☝️ This script prevent the FART effect.
if (localStorage.getItem("theme") === null) {
document.documentElement.setAttribute("data-theme", "light");
} else
document.documentElement.setAttribute("data-theme",localStorage.getItem("theme"));
// "theme" LocalStorage value is set by the package to remember user preference.
// The value is checked and applyed before rendering anything.
import { themeChange } from "theme-change";
themeChange();
// 👆 you could import the CDN directly instead of these two lines
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
---
---
// ☝️ This script prevent the FART effect.
if (localStorage.getItem("theme") === null) {
document.documentElement.setAttribute("data-theme", "light");
} else
document.documentElement.setAttribute(
"data-theme",
localStorage.getItem("theme")
);
// "theme" LocalStorage value is set by the package to remember user preference.
// The value is checked and applyed before rendering anything.
import { themeChange } from 'theme-change';
themeChange();
// 👆 you could import the CDN directly instead of these two lines
My Cool Astro Layout Wraping All My Pages
Home
Posts
Contact
```
`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:
```css
: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
```css
body {
background-color: var(--my-color);
}
```## HTML
There are 3 options:
- ### Using buttons to set a theme
[![btn](https://user-images.githubusercontent.com/7342023/101527827-c0adcc00-39a3-11eb-9e41-24bfa91ea96c.gif)](#)
Clicking on these buttons, sets the chosen theme and also adds the `ACTIVECLASS` to the chosen button
```
```- ### Toggle between two themes
[![toggle](https://user-images.githubusercontent.com/7342023/101527821-bf7c9f00-39a3-11eb-822b-7751265a18a5.gif)](#)
Clicking on this element, toggles between `dark` and `light` theme and also adds the `ACTIVECLASS` to the element
```
```- ### `` menu
[![select](https://user-images.githubusercontent.com/7342023/101527790-b4297380-39a3-11eb-9173-bc909549d160.gif)](#)
```
Default
Dark
Pink
```# 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
```---
[install-size]: https://badgen.net/bundlephobia/minzip/theme-change?label=bundle%20size&color=purple
[js]: https://badgen.net/badgesize/normal/https/unpkg.com/theme-change/index.js?label=file%20size&color=purple
[npm]: https://badgen.net/npm/v/theme-change?label=version&color=purple
[dl]: https://badgen.net/npm/dt/theme-change?icon=npm&color=purple
[commit]: https://badgen.net/github/last-commit/saadeghi/theme-change?icon=github&color=purple
[build]: https://badgen.net/github/checks/saadeghi/theme-change?label=build
[build-url]: https://github.com/saadeghi/theme-change/actions
[install-size-url]: https://bundlephobia.com/result?p=theme-change
[js-url]: https://unpkg.com/theme-change@latest/index.js
[npm-url]: https://www.npmjs.com/package/theme-change
[gh-url]: https://github.com/saadeghi/theme-change