aboutsummaryrefslogtreecommitdiff
path: root/build/animated-toggle-tabs/index.html
blob: 599d6c2c2dd6368750d656ec6a8d14a8d1dca0be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="icon" href="data:,">
	<title>Animated Radio Tab Toggles</title>
	<link href="/atom.xml" type="application/atom+xml" rel="alternate" title="Atom feed for blog posts" />
	<link href="/rss.xml" type="application/rss+xml" rel="alternate" title="RSS feed for blog posts" />
<style>*{box-sizing:border-box;}body{font-family:sans-serif;line-height:1.33;margin:0 auto;max-width:650px;padding:1rem;}img{max-width:100%;}pre{border:1px solid;overflow:auto;padding:5px;}table{text-align:left;width:100%;}.footnotes{font-size:90%;}</style>
</head>

<nav>
	<a href="#menu">Menu &darr;</a>
</nav>

<main>
<h1 id="animated-radio-tab-toggles">Animated Radio Tab Toggles</h1>

<p>2021-01-05</p>

<p><em>In this demo tutorial, we are making the assumption</em> that we need to create a radio slide toggle for our made-up payment options. For this we want to display 3 simple payment choices to the user:</p>

<ul>
<li>One-time payment</li>
<li>Recurring payment</li>
<li>Free tier payment</li>
</ul>

<h2 id="the-final-demo">The Final Demo</h2>

<p><a href="https://codepen.io/bradleytaunt/embed/vYXjpLO">Live CodePen</a></p>

<p>Let’s get started with the base skeleton.</p>

<h2 id="the-html">The HTML</h2>

<pre><code>&#60;div class="radio-toggles"&#62;
    &#60;input type="radio" id="option-1" name="radio-options"&#62;
    &#60;label for="option-1"&#62;One-Time&#60;&#47;label&#62;
    &#60;input type="radio" id="option-2" name="radio-options" checked&#62;
    &#60;label for="option-2"&#62;Recurring&#60;&#47;label&#62;
    &#60;input type="radio" id="option-3" name="radio-options"&#62;
    &#60;label for="option-3"&#62;Free&#60;&#47;label&#62;
    &#60;div class="slide-item"&#62;&#60;&#47;div&#62;
&#60;&#47;div&#62;
</code></pre>

<h2 id="the-css">The CSS</h2>

<p>Now for the main event – the CSS. First we want to style the wrapper that holds all of our pieces together. You can tweak this to your liking, but I prefer a simple and clean style:</p>

<pre><code>.radio-toggles {
    align-items: center;
    background: #eee;
    border: 1px solid lightgrey;
    border-radius: 9999px;
    display: flex;
    justify-content: center;
    margin: 20px auto;
    max-width: 400px;
    overflow: hidden;
    padding: 4px;
    position: relative;
}
</code></pre>

<p>Next, we “hide” (only visually) the default <code>radio</code> inputs:</p>

<pre><code>input[type="radio"] {
    left: -9999px;
    position: absolute;
    z-index: -1;
}
</code></pre>

<p>Then we give the corresponding <code>label</code> elements a little spacing and breathing room:</p>

<pre><code>label {
    cursor: pointer;
    padding: 10px 20px;
    text-align: center;
    width: 33.33%;
    z-index: 2;
}
</code></pre>

<p>Remember that <code>.slide-item</code> I referenced earlier? That element will be the visual “slider” that animates between the individual radio options. We style that like so:</p>

<pre><code>.slide-item {
    background: white;
    border-radius: 9999px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.15);
    height: calc(100% - 8px);
    left: calc(33.33% + 4px);
    position: absolute;
    width: calc(33.33% - 8px);
    transition: left .4s;
    z-index: 0;
}
</code></pre>

<p>You&#8217;ll notice the <code>left</code>, <code>height</code>, and <code>width</code> properties utilize the CSS <code>calc</code> attributes – this just gives some much needed padding and visual clean-up to the whole tabbed interface.</p>

<p>For the finishing touches, we just need to tell the <code>.slide-item</code> where to position itself based on which <code>radio</code> input is currently selected:</p>

<pre><code>input[type="radio"]:nth-of-type(1):checked ~ .slide-item {
    left: 4px;
}
input[type="radio"]:nth-of-type(3):checked ~ .slide-item {
    left: calc(66.66% + 4px);
}
</code></pre>

<p>That&#8217;s pretty much it! You now have a fully functional, animated toggle slider with just a set of simple <code>radio</code> inputs and pure CSS.</p>
<footer role="contentinfo">
    <h2>Menu Navigation</h2>
    <ul id="menu">
        <li><a href="/">Home</a></li>
        <li><a href="/projects">Projects</a></li>
        <li><a href="/uses">Uses</a></li>
        <li><a href="/wiki">Wiki</a></li>
        <li><a href="/resume">Resume</a></li>
        <li><a href="/colophon">Colophon</a></li>
        <li><a href="/now">Now</a></li>
        <li><a href="/donate">Donate</a></li>
        <li><a href="/atom.xml">RSS</a></li>
        <li><a href="#top">&uarr; Top of the page</a></li>
    </ul>
    <small>
        Built with <a href="https://git.sr.ht/~bt/barf">barf</a>. <br>
        Maintained with ♥ for the web. <br>
        Proud supporter of <a href="https://usefathom.com/ref/DKHJVX">Fathom</a> &amp; <a href="https://nextdns.io/?from=74d3p3h8">NextDNS</a>. <br>
        The content for this site is <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>.<br> The <a href="https://git.sr.ht/~bt/bt.ht">code for this site</a> is <a href="https://git.sr.ht/~bt/bt.ht/tree/master/item/LICENSE">MIT</a>.
    </small>
</footer>