Skip to content

Instantly share code, notes, and snippets.

@EdPike365
Created March 2, 2021 03:31
Show Gist options
  • Save EdPike365/2993931901e4aaadb3340e9a6113307e to your computer and use it in GitHub Desktop.
Save EdPike365/2993931901e4aaadb3340e9a6113307e to your computer and use it in GitHub Desktop.
A CSS based Toggle for switching between Dark and Light Mode
import React from "react"
import styled from "@emotion/styled"
import useDarkMode from "use-dark-mode"
//This widget was based on https://codepen.io/Qvcool/pen/bdzVYW, with some modifications
//A real benefit of this approach is that it can also be used with a radio button set
//A real warning on this is it uses some CSS "tricks".
//Also I have yet to get the unicode sequences (or Font Awesome) references to work for the icons
//In the meantime, just copy and paste unicode characters.
const SliderCheckboxSection = styled.section`
position: relative;
& > input {
margin: 0px;
margin-top: 1px;
cursor: pointer;
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
-moz-opacity: 0;
-khtml-opacity: 0;
opacity: 0;
position: absolute;
z-index: 1;
top: 0px;
left: 0px;
background: red;
background-color: red;
width: 80px;
height: 20px;
}
/* the checked psuedo selector only works with 1 colon here
the content fields are using Unicode chars
*/
& > input:checked + .label {
&::before {
color: #fff;
content: "☾";
background-color: black;
padding-left: 6px;
}
&::after {
left: 21px;
background-color: grey;
}
}
& > .label {
position: relative;
padding-left: 46px;
&::before, &::after {
position: absolute;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
transition: background-color 0.3s, left 0.3s;
}
&::before {
color: black;
content: "☀";
background-color: white;
box-sizing: border-box;
padding-left: 23px;
font-size: 12px;
line-height: 20px;
left: 0px;
top: 0px;
height: 20px;
width: 40px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
&::after {
content: "";
background-color: grey;
letter-spacing: 20px;
left: 1px;
top: 1px;
height: 18px;
width: 18px;
}
}
`
// this is a good demo about using the full powers of use-dark-mode https://codesandbox.io/s/mzj64x80ny?file=/src/Content.js
const DarkModeToggle = () => {
const darkMode = useDarkMode(false);
return (
<SliderCheckboxSection>
<input type="checkbox" id="1" checked={darkMode.value} onChange={darkMode.toggle} />
<label className="label" htmlFor="1"></label>
</SliderCheckboxSection>
)
}
export default DarkModeToggle
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment