From 6b742c459266b18e2b375b35205ce8a6c02f0452 Mon Sep 17 00:00:00 2001 From: Bradley Taunt Date: Thu, 6 Jun 2024 08:05:12 -0400 Subject: Initial commit --- posts/easy-toggle-switches.md | 234 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 posts/easy-toggle-switches.md (limited to 'posts/easy-toggle-switches.md') diff --git a/posts/easy-toggle-switches.md b/posts/easy-toggle-switches.md new file mode 100644 index 0000000..f7b1235 --- /dev/null +++ b/posts/easy-toggle-switches.md @@ -0,0 +1,234 @@ +# Easy Toggle Switches + +2019-02-18 + +Sometimes there is a need to use toggle elements in-place of the default `checkbox` inputs. The problem is, I tend to see a lot of developers reaching for plugins or JavaScript components in order to implement these toggles. + +*This is overkill*. You can create your own custom `input` elements to mimic toggles perfectly with just a small amount of CSS. + +## What we will be building + +![Easy toggle switches](/public/images/easy-toggle-switches.png) + +[Live CodePen Example](https://codepen.io/bradleytaunt/pen/bGgbajY) + +## The HTML + +The build structure for these toggles is really simple, we only need: + +- a parent container to hold all our corresponding elements +- a checkbox `input` element (which we will hide) +- an empty label designed to represent the slider +- a text label that references the `input` + + + /* Main toggle parent container */ +
+ /* Checkbox input, hidden with CSS */ + + /* The toggle slider element */ + + /* The text label to the right of the slider */ + +
+ + +And that's everything we need for the HTML. + +**ProTip:** Don't forget to increment both the `id` and `for` attributes when adding additional toggles. This seems like a no-brainer but it's overlooked more than you think. + +## The CSS + +To get things started we will add the styling to the `.toggle-switch` item directly (using `flexbox` in this demo for easier layout). + +**Sidenote**: You will notice the inclusion of CSS variables in this demo - if you are unfamiliar with how to use root variables in CSS, take a look at one of my previous posts: CSS variables. + + + :root { + --primary-color: #4A90E2; + } + + .toggle-switch { + align-items: center; + display: flex; + font-size: 14px; + justify-content: center; + margin: 20px 0; + } + + +Next we will hide the default browser checkbox element since we won't be needing it: + + + .toggle-input { + position: absolute; + visibility: hidden; + z-index: -1; + } + + +Let's also add some base styling for the `label` containing the text corresponding to it's `input` sibling: + + + .toggle-label { + color: #ccc; + cursor: pointer; + font-weight: bold; + padding-left: 10px; + text-shadow: 1px 1px 0 rgba(255,255,255,0.3); + transition: ease all .3s; + } + + +Now we target the `.toggle-slider` label and add the styling for the main slider base: + + + /* This is just the main slider base */ + .toggle-slider { + background: #eee; + border-radius: 9999px; + box-shadow: inset 0 2px 4px rgba(0,0,0,0.1), + inset 0 4px 8px rgba(0,0,0,0.1), + 0 1px 1px rgba(255,255,255,1); + cursor: pointer; + display: inline-block; + height: 20px; + position: relative; + transition: all ease .3s; + width: 40px; + } + + +We *could* include a separate element for the circle toggle switcher itself, but instead we will use the `:before` pseudo element: + + + .toggle-slider:before { + background: white; + border-radius: 9999px; + box-shadow: 0 4px 8px rgba(0,0,0,0.1), + 0 2px 4px rgba(0,0,0,0.2); + content:''; + height: 16px; + left: 2px; + position: absolute; + top: 2px; + transition: all ease .3s; + width: 16px; + } + + +### Interaction + +Right now we just have a static toggle that does nothing when the user interacts with it. Let's change that by moving the pseudo element's position based on the checkbox `input` state and updating the label text color: + + + .toggle-input:checked + .toggle-slider { + background: var(--primary-color); + } + .toggle-input:checked + .toggle-slider:before { + /* Move 100% of the width minus it's own width plus initial 'left' */ + left: calc(100% - 18px); + } + + .toggle-input:checked ~ .toggle-label { + color: var(--primary-color); + } + + +And because we already included the `transition` property on both the base slider and label text, everything animates nicely between state changes. + +## Final code + +To make things easier, you can find the HTML & CSS is their entirety below: + +### HTML + + +
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+ + +### The CSS + + + :root { + --primary-color: #4A90E2; + } + .toggle-switch { + align-items: center; + display: flex; + font-size: 14px; + justify-content: center; + margin: 20px 0; + } + .toggle-input { + position: absolute; + visibility: hidden; + z-index: -1; + } + .toggle-slider { + background: #eee; + border-radius: 9999px; + box-shadow: inset 0 2px 4px rgba(0,0,0,0.1), + inset 0 4px 8px rgba(0,0,0,0.1), + 0 1px 1px rgba(255,255,255,1); + cursor: pointer; + display: inline-block; + height: 20px; + position: relative; + transition: all ease .3s; + width: 40px; + } + .toggle-slider:before { + background: white; + border-radius: 9999px; + box-shadow: 0 4px 8px rgba(0,0,0,0.1), + 0 2px 4px rgba(0,0,0,0.2); + content:''; + height: 16px; + left: 2px; + position: absolute; + top: 2px; + transition: all ease .3s; + width: 16px; + } + .toggle-input:checked + .toggle-slider { + background: var(--primary-color); + } + .toggle-input:checked + .toggle-slider:before { + left: calc(100% - 18px); + } + .toggle-label { + color: #ccc; + cursor: pointer; + font-weight: bold; + padding-left: 10px; + text-shadow: 1px 1px 0 rgba(255,255,255,0.3); + transition: ease all .3s; + } + .toggle-input:checked ~ .toggle-label { + color: var(--primary-color); + } + + +Enjoy your custom toggles! + + -- cgit v1.2.3-54-g00ecf