Coder Social home page Coder Social logo

ezdub / theme-change Goto Github PK

View Code? Open in Web Editor NEW

This project forked from saadeghi/theme-change

0.0 0.0 0.0 94 KB

Change CSS theme with toggle, buttons or select using CSS custom properties and localStorage

Home Page: https://codepen.io/saadeghi/pen/OJypbNM

License: MIT License

JavaScript 100.00%

theme-change's Introduction

๐ŸŽจ CSS Theme Change

  • A tiny JS script to handle CSS themes
  • Change CSS theme using button, toggle or a <select>
  • It saves chosen theme in browser and uses it again when page reloads


๐Ÿ–ฅ Demo

image

๐Ÿ’ฟ Use

JS

Use CDN:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/index.js"></script>
Or use NPM:

Install: npm i theme-change --save and use it in your js file:

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:

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:

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:

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:

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:

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 problem. To prevent this we will use the is:inline astro directive.

If you want to apply themes on a single astro page (remember Astro is an MPA framework) :

src/pages/mypage.astro

---
---

<html lang="en">
  <head>
  <script is:inline>
      // โ˜๏ธ 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.
  </script>
  <script>
      import { themeChange } from "theme-change";
      themeChange();
       // ๐Ÿ‘† you could import the CDN directly instead of these two lines
    </script>
    <title>My crazy credit page</title>
  </head>
  <body>
    <h1>Welcome to my credit page!</h1>
  </body>
</html>

If you want to apply themes to all your astro pages, you need to execute both scripts in a Astro layout, it would need to wrap all your astro pages like so:

src/layouts/MyCrazyLayout.astro

---
---

<html lang="en">
  <head>
    <script is:inline>
      // โ˜๏ธ 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.
    </script>
    <script>
      import { themeChange } from 'theme-change';
      themeChange();
      // ๐Ÿ‘† you could import the CDN directly instead of these two lines
    </script>
    <meta charset="utf-8" />
    <title>My Cool Astro Layout Wraping All My Pages</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <nav>
      <a href="#">Home</a>
      <a href="#">Posts</a>
      <a href="#">Contact</a>
    </nav>
    <article>
      <slot />
      <!-- your content from src/pages/index.astro is injected here -->
    </article>
  </body>
</html>

src/pages/index.astro

---
import MyCrazyLayout from '../layouts/MyCrazyLayout.astro';
---
<MySiteLayout>
  <p>My page content, wrapped in a layout!</p>
</MySiteLayout>

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:

  • Using buttons to set a theme

    btn

    Clicking on these buttons, sets the chosen theme and also adds the ACTIVECLASS to the chosen button

    <button data-set-theme="" data-act-class="ACTIVECLASS"></button>
    <button data-set-theme="dark" data-act-class="ACTIVECLASS"></button>
    <button data-set-theme="pink" data-act-class="ACTIVECLASS"></button>
    
  • Toggle between two themes

    toggle

    Clicking on this element, toggles between dark and light theme and also adds the ACTIVECLASS to the element

    <button data-toggle-theme="dark,light" data-act-class="ACTIVECLASS"></button>
    
  • <select> menu

    select

    <select data-choose-theme>
      <option value="">Default</option>
      <option value="dark">Dark</option>
      <option value="pink">Pink</option>
    </select>
    

Advance use

Set theme based on OS color-scheme
@media (prefers-color-scheme: dark){
  :root{
    --my-color: #252b30;
  }
}
Use with PurgeCSS

If you're using Purge CSS, you might need to safe list your CSS using the comments below because your secondary themes will be purged

  • Safelist [data-theme] on postcss config

    module.exports = {
      purge: {
        options: {
          safelist: [/data-theme$/],
        },
      },
    }
  • Safelist inside CSS file

    /*! purgecss start ignore */
    
    [data-theme='dark'] {
      --my-color: #252b30;
    }
    
    /*! purgecss end ignore */

theme-change's People

Contributors

1bitbool avatar aramlr avatar dranovsk avatar ezdub avatar julienqnn avatar kidonng avatar masumcity avatar masumonline avatar saadeghi avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.