Repository navigation
Dark Mode
Henner S edited this page Mar 27, 2023
·
1 revision
Create a "Dark Mode Toggle" widget to switch between light and dark theme.
h-dark-mode
This plugin doesn't provide the CSS and JS since it's intended to be used with Edje Theme.
If you are using this in another theme, add these styles (in Sass format):
body.h-is-dark
filter: invert(100%) hue-rotate(180deg)
// invert back the image
img
filter: invert(100%) hue-rotate(180deg) brightness(1.2)
// image that you want to stay inverted
.wp-block-site-logo img,
.my-icon
filter: none
// Fix weird positioning bug with adminbar when <body> has filter
html[lang]
margin-top: 0 !important
#wpadminbar
position: sticky
body.h-is-dark &
filter: invert(100%) hue-rotate(180deg)
.h-dark-toggle
cursor: pointer
display: flex
align-items: center
row-gap: 0.25rem
column-gap: 0.25rem
span
text-transform: uppercase
font-size: 12px
font-weight: 700
input[type="checkbox"]
display: none
.h-dark-toggle__switch
--width: 44px
--height: 24px
--padding: 4px
display: block
overflow: hidden
position: relative
background-color: black
width: var(--width)
height: var(--height)
border: 1px solid white
border-radius: 1rem
&:focus
box-shadow: 0 0 0 2px white
&::before
content: ""
position: absolute
z-index: 3
display: inline-block
background-color: white
width: calc(var(--height) - var(--padding) - var(--padding))
height: calc(var(--height) - var(--padding) - var(--padding))
top: 50%
left: var(--padding)
border-radius: 50%
transform: translateY(-50%)
transition: all .25s ease-in-out
input:checked + &
transform: translateY(-50%) translateX(calc(var(--width) / 2 - var(--padding) / 2))
// turn the circle into crescent
&::after
content: ""
position: absolute
top: 50%
left: 0
z-index: 2
display: inline-block
background-color: black
transition: all .25s ease-in-out
transform: translateY(-50%)
width: 1px
height: 1px
border-radius: 50%
body.h-is-dark &
z-index: 4
width: calc(var(--width) * 0.7)
height: calc(var(--width) * 0.7)const myDarkMode = {
init() {
this.clickListener();
this.tabindexListener();
},
/**
* Click listener for dark mode toggle
*/
clickListener() {
const $darkToggles = document.querySelectorAll('.h-dark-toggle input[type="checkbox"]');
if ($darkToggles.length <= 0) { return; }
$darkToggles.forEach(($t) => {
$t.addEventListener('change', (e) => {
this.toggle(e.currentTarget.checked);
});
});
},
/**
* Keyboard listener for dark mode toggle
*/
tabindexListener() {
const $darkSwitches = document.querySelectorAll('.h-dark-toggle__switch');
$darkSwitches.forEach(($s) => {
$s.addEventListener('keyup', (e) => {
if (e.key === 'Enter' || e.keyCode === 13) {
const $checkbox = e.currentTarget.closest('.h-dark-toggle').querySelector('input[type="checkbox"]');
$checkbox.checked = !$checkbox.checked;
this.toggle($checkbox.checked);
}
});
});
},
/**
* Toggle the body class and cache the variable
*/
toggle(isChecked) {
document.querySelector('body').classList.toggle('h-is-dark', isChecked);
// the checker for this is outputed into wp_body_open() by Edje WP Library
localStorage.setItem('hDarkMode', isChecked);
},
};
document.addEventListener('DOMContentLoaded', () => {
myDarkMode.init();
});