Toggle Table Data with CSS

The Problem

You need to design a table that displays its data in two different units. You
want to avoid displaying both sets at once.

I came across this little problem while working on an e-commerce website. The
client wanted to display the measurements in their size guide in both
centimetres and inches.

The user shouldn’t have to convert the measurements to their unit of
preference. And displaying the measurements in both units at once wasn’t a
very desirable option. Why should the user go through both units when they
only need to see the one they prefer? It’s our job to improve their experience
after all.

The Solution

Give the user the option to toggle between both units. If they want to peruse
the size guide in centimetres, they can. If their American friend next to them
needs to see the measurements in inches, they are just a click/tap away.

Using JavaScript is an obvious option. And given many online stores rely on
JavaScript for critical functions (adding items to cart, checkout process,
etc), a non-JavaScript method may not seem necessary here. It is possible
nonetheless.

Update: based on
Heydon Pickering’s tweet, this method is not great for accessibility. Proceed with caution!

The method is really simple. We’ll rely on a checkbox’s state
.mycheckbox:checked and use CSS’s general
sibling selector to target the measurements we want to hide/display.

Here is what we’re after:

See the Pen
Toggle Table Data with CSS (size guide example)
by Hussein Al Hammad (@hus_hmd)
on CodePen.

The Code

A size guide is typically presented in a table. The markup for the table here
is pretty standard. We’ll just include two
spans (one for each measurement unit)
inside the table’s tds.

In order to be able to target these spans with the general sibling selector
and based on the checkbox’s state
.checkbox:checked ~ table span, we need to
make the checkbox and the table siblings (i.e. have the same parent element).
We also need to place the checkbox before the table. The checkbox doesn’t have
to be placed directly before the table though.

“The ~ combinator separates two selectors and matches the second element
only if it is preceded by the first, and both share a common parent.”

Simplified markup

1<input type="checkbox" id="toggle" />
2<table>
3 <tbody>
4 <tr>
5 <td>Small</td>
6 <td>
7 <span class="default">20 cm</span>
8 <span class="alt">8 inch</span>
9 </td>
10 <td>
11 <span class="default">28 cm</span>
12 <span class="alt">11 inch</span>
13 </td>
14 </tr>
15 </tbody>
16</table>

CSS to toggle spans

1table .default {
2 display: inline;
3}
4 
5table .alt {
6 display: none;
7}
8 
9/*checked*/
10.checkbox:checked ~ table .default {
11 display: none;
12}
13 
14.checkbox:checked ~ table .alt {
15 display: inline;
16}

Now it functions as intended. It’s a table with a checkbox that toggles the
table’s data.

By default: we leave the checkbox unchecked and hide
.alt spans with CSS. When checked, we hide
the .default spans and display the
.alt spans

Now all there’s left to do is to customise our checkbox to make it look like a
toggle switch and add clear labelling. We want these elements next to each
other in this order:

  1. Main label
  2. First (default) measurement unit label
  3. Checkbox/custom toggle switch
  4. Alternative measurement unit label

There are many examples of
custom switches on CodePen. That’s a good starting place to get some inspiration.

When coding your own remember this:

Firstly, (as far as I know) you can’t use pseudo elements on
input[type=checkbox]. In my example, I’m
using an empty span for my switch.

The other thing to keep in mind is while you want to hide the checkbox you
need it to remain clickable. You want the user to be actually clicking the
checkbox when they click on the measurement unit label they want to display.
The trick is to set the opacity of the
checkbox to 0 (makes it invisible, but remains clickable) and absolutely
position it to overlap with the measurement units labels. You may also need to
set the checkbox’s z-index to a higher value
to ensure it’s on top (and thus remains clickable).

1<label for="toggle" class="toggle__main-label">Measurements in: </label>
2<label for="toggle" class="toggle__option">CM</label>
3<input type="checkbox" class="toggle__checkbox" id="toggle" />
4<span class="toggle__switch"></span>
5<label for="toggle" class="toggle__option">INCHES</label>
1.toggle__main-label {
2 display: inline-block;
3 vertical-align: middle;
4 margin-right: 10px;
5}
6 
7.toggle__checkbox {
8 opacity: 0; /*invisible but it's there (we need to keep it clickable)*/
9 width: 100%;
10 z-index: 99; /*make sure it's on top so it's clickable*/
11 position: absolute;
12 left: 50%;
13 transform: translateX(-50%);
14 cursor: pointer;
15}
16 
17.toggle__option {
18 display: inline-block;
19 vertical-align: middle;
20 user-select: none;
21}
22 
23.toggle__option:first-child {
24 text-align: right;
25 left: 0;
26}
27.toggle__option:last-child {
28 right: 0;
29}
30 
31.toggle__switch {
32 display: inline-block;
33 vertical-align: middle;
34 position: relative;
35 width: 50px;
36 height: 20px;
37 margin: 0 10px;
38}
39 
40/*focus styles for accessibility*/
41.toggle__checkbox:focus ~ .toggle__switch {
42 outline: 1px solid #19ca2a;
43}
44 
45/*base of toggle switch*/
46.toggle__switch:before {
47 content: "";
48 position: absolute;
49 display: block;
50 left: 50%;
51 top: 50%;
52 transform: translate(-50%, -50%);
53 z-index: 1;
54 background-color: #464646;
55 width: 50px;
56 height: 2px;
57}
58 
59/*move to either side of the base based on checkbox's state*/
60.toggle__switch:after {
61 content: "";
62 position: absolute;
63 display: block;
64 background-color: #171717;
65 z-index: 1;
66 
67 width: 20px;
68 height: 7px;
69 left: 50%;
70 top: 50%;
71 transform: translate(
72 -130%,
73 -50%
74 ); /*position to the left side of the switch base*/
75 transition: transform 0.3s ease-out;
76}
77 
78.toggle__checkbox:checked ~ .toggle__switch:after {
79 transform: translate(
80 30%,
81 -50%
82 ); /*position to the right side of the switch base*/
83}

Last Words

If you want to get a bit fancy, you can detect the user’s country (e.g. from
user’s IP address with PHP) and display the unit of choice in their country by
default.

Javascript is still an option; you could display the measurements in both
units by default and hide the alternative with Javascript (if the script
loads). This way users who don’t have Javascript enabled will still be able to
view both sets of measurements, and those who have it enabled will be able to
toggle the measurements as they wish. Progressive Enhancement FTW.

I haven’t done any accessibility testing. The checkbox is still accessible via
the keyboard and the focus styles highlights the custom switch. If you think
the checkbox isn’t fully accessible and know how to fix that, please share
your thoughts.


This content originally appeared on Hussein Al Hammad and was authored by Hussein Al Hammad

The Problem

You need to design a table that displays its data in two different units. You want to avoid displaying both sets at once.

I came across this little problem while working on an e-commerce website. The client wanted to display the measurements in their size guide in both centimetres and inches.

The user shouldn’t have to convert the measurements to their unit of preference. And displaying the measurements in both units at once wasn’t a very desirable option. Why should the user go through both units when they only need to see the one they prefer? It’s our job to improve their experience after all.

The Solution

Give the user the option to toggle between both units. If they want to peruse the size guide in centimetres, they can. If their American friend next to them needs to see the measurements in inches, they are just a click/tap away.

Using JavaScript is an obvious option. And given many online stores rely on JavaScript for critical functions (adding items to cart, checkout process, etc), a non-JavaScript method may not seem necessary here. It is possible nonetheless.

Update: based on Heydon Pickering's tweet, this method is not great for accessibility. Proceed with caution!

The method is really simple. We'll rely on a checkbox's state .mycheckbox:checked and use CSS's general sibling selector to target the measurements we want to hide/display.

Here is what we're after:

See the Pen Toggle Table Data with CSS (size guide example) by Hussein Al Hammad (@hus_hmd) on CodePen.

The Code

A size guide is typically presented in a table. The markup for the table here is pretty standard. We'll just include two spans (one for each measurement unit) inside the table's tds.

In order to be able to target these spans with the general sibling selector and based on the checkbox's state .checkbox:checked ~ table span, we need to make the checkbox and the table siblings (i.e. have the same parent element). We also need to place the checkbox before the table. The checkbox doesn't have to be placed directly before the table though.

"The ~ combinator separates two selectors and matches the second element only if it is preceded by the first, and both share a common parent."

Simplified markup

1<input type="checkbox" id="toggle" />
2<table>
3 <tbody>
4 <tr>
5 <td>Small</td>
6 <td>
7 <span class="default">20 cm</span>
8 <span class="alt">8 inch</span>
9 </td>
10 <td>
11 <span class="default">28 cm</span>
12 <span class="alt">11 inch</span>
13 </td>
14 </tr>
15 </tbody>
16</table>

CSS to toggle spans

1table .default {
2 display: inline;
3}
4 
5table .alt {
6 display: none;
7}
8 
9/*checked*/
10.checkbox:checked ~ table .default {
11 display: none;
12}
13 
14.checkbox:checked ~ table .alt {
15 display: inline;
16}

Now it functions as intended. It's a table with a checkbox that toggles the table's data.

By default: we leave the checkbox unchecked and hide .alt spans with CSS. When checked, we hide the .default spans and display the .alt spans

Now all there's left to do is to customise our checkbox to make it look like a toggle switch and add clear labelling. We want these elements next to each other in this order:

  1. Main label
  2. First (default) measurement unit label
  3. Checkbox/custom toggle switch
  4. Alternative measurement unit label

There are many examples of custom switches on CodePen. That's a good starting place to get some inspiration.

When coding your own remember this:

Firstly, (as far as I know) you can't use pseudo elements on input[type=checkbox]. In my example, I'm using an empty span for my switch.

The other thing to keep in mind is while you want to hide the checkbox you need it to remain clickable. You want the user to be actually clicking the checkbox when they click on the measurement unit label they want to display. The trick is to set the opacity of the checkbox to 0 (makes it invisible, but remains clickable) and absolutely position it to overlap with the measurement units labels. You may also need to set the checkbox's z-index to a higher value to ensure it's on top (and thus remains clickable).

1<label for="toggle" class="toggle__main-label">Measurements in: </label>
2<label for="toggle" class="toggle__option">CM</label>
3<input type="checkbox" class="toggle__checkbox" id="toggle" />
4<span class="toggle__switch"></span>
5<label for="toggle" class="toggle__option">INCHES</label>
1.toggle__main-label {
2 display: inline-block;
3 vertical-align: middle;
4 margin-right: 10px;
5}
6 
7.toggle__checkbox {
8 opacity: 0; /*invisible but it's there (we need to keep it clickable)*/
9 width: 100%;
10 z-index: 99; /*make sure it's on top so it's clickable*/
11 position: absolute;
12 left: 50%;
13 transform: translateX(-50%);
14 cursor: pointer;
15}
16 
17.toggle__option {
18 display: inline-block;
19 vertical-align: middle;
20 user-select: none;
21}
22 
23.toggle__option:first-child {
24 text-align: right;
25 left: 0;
26}
27.toggle__option:last-child {
28 right: 0;
29}
30 
31.toggle__switch {
32 display: inline-block;
33 vertical-align: middle;
34 position: relative;
35 width: 50px;
36 height: 20px;
37 margin: 0 10px;
38}
39 
40/*focus styles for accessibility*/
41.toggle__checkbox:focus ~ .toggle__switch {
42 outline: 1px solid #19ca2a;
43}
44 
45/*base of toggle switch*/
46.toggle__switch:before {
47 content: "";
48 position: absolute;
49 display: block;
50 left: 50%;
51 top: 50%;
52 transform: translate(-50%, -50%);
53 z-index: 1;
54 background-color: #464646;
55 width: 50px;
56 height: 2px;
57}
58 
59/*move to either side of the base based on checkbox's state*/
60.toggle__switch:after {
61 content: "";
62 position: absolute;
63 display: block;
64 background-color: #171717;
65 z-index: 1;
66 
67 width: 20px;
68 height: 7px;
69 left: 50%;
70 top: 50%;
71 transform: translate(
72 -130%,
73 -50%
74 ); /*position to the left side of the switch base*/
75 transition: transform 0.3s ease-out;
76}
77 
78.toggle__checkbox:checked ~ .toggle__switch:after {
79 transform: translate(
80 30%,
81 -50%
82 ); /*position to the right side of the switch base*/
83}

Last Words

If you want to get a bit fancy, you can detect the user’s country (e.g. from user’s IP address with PHP) and display the unit of choice in their country by default.

Javascript is still an option; you could display the measurements in both units by default and hide the alternative with Javascript (if the script loads). This way users who don’t have Javascript enabled will still be able to view both sets of measurements, and those who have it enabled will be able to toggle the measurements as they wish. Progressive Enhancement FTW.

I haven’t done any accessibility testing. The checkbox is still accessible via the keyboard and the focus styles highlights the custom switch. If you think the checkbox isn’t fully accessible and know how to fix that, please share your thoughts.


This content originally appeared on Hussein Al Hammad and was authored by Hussein Al Hammad


Print Share Comment Cite Upload Translate Updates
APA

Hussein Al Hammad | Sciencx (2017-02-22T00:00:00+00:00) Toggle Table Data with CSS. Retrieved from https://www.scien.cx/2017/02/22/toggle-table-data-with-css-2/

MLA
" » Toggle Table Data with CSS." Hussein Al Hammad | Sciencx - Wednesday February 22, 2017, https://www.scien.cx/2017/02/22/toggle-table-data-with-css-2/
HARVARD
Hussein Al Hammad | Sciencx Wednesday February 22, 2017 » Toggle Table Data with CSS., viewed ,<https://www.scien.cx/2017/02/22/toggle-table-data-with-css-2/>
VANCOUVER
Hussein Al Hammad | Sciencx - » Toggle Table Data with CSS. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2017/02/22/toggle-table-data-with-css-2/
CHICAGO
" » Toggle Table Data with CSS." Hussein Al Hammad | Sciencx - Accessed . https://www.scien.cx/2017/02/22/toggle-table-data-with-css-2/
IEEE
" » Toggle Table Data with CSS." Hussein Al Hammad | Sciencx [Online]. Available: https://www.scien.cx/2017/02/22/toggle-table-data-with-css-2/. [Accessed: ]
rf:citation
» Toggle Table Data with CSS | Hussein Al Hammad | Sciencx | https://www.scien.cx/2017/02/22/toggle-table-data-with-css-2/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.