Toggle grid view / list view with just HTML and CSS

Thomas Møller Jørgensen
4 min readMar 20, 2023

--

Grid image

Toggling between grid view and list view is really only a matter of styling. Often you see solutions that involve JavaScript to add or remove classes, but this is really not necessary. Here I will show a solution that relies only on HTML and CSS.

What and how

First I will make a toggle button using only HTML and CSS. Then I will add a list, and make it switch between list view and grid view, based on the state of the toggle button. This will also be only HTML and CSS.

The result is fully useable whether you are using a Frontend JavaScript framework (Angular, React, Vue etc.) or plain HTML, because it is nothing more than a styling of a list.

The toggle button

I will be using a native HTML element that support two states: A checkbox, with a label.

Note that I have marked both as hidden. The switch between list view and grid view only happens if the CSS is loaded; in other cases (search engines, screen readers etc) I don’t want these elements to affect the document structure.

To make the label look like a list/grid toggle button I will add ::beforeand ::afterrules to display the two possible states. Each ‘button’ will get a SVG icon that tells the user what to expect.

By targeting the label adjacent to (+) the checkbox I don’t have to add any class or other stuff to the markup just for the sake of styling.

  1. First I make the label non-hidden, because we are now in a scenario where the visible appearance — the toggle between list and grid view — matters.
  2. I add a bit of common styling to the ‘buttons’: size, border, background and color.
  3. For each button I add some SVG content. I could also just have added the words ‘list’ and ‘grid’.

The last styling of the toggle button is to change the background depending on which of the two states is currently selected. I do this by using the :checkedand :notselectors. The :checkedselector is really the center around which this whole functionality revolves.

To put it in other words: If the checkbox is checked then set the background of the grid viewbutton to white; if it is not checked then set the background of the list view button instead.

Toggle button

Add the list

The toggle button will be toggling the display of a list; therefore I will add a list.

And just to get rid of the default list styling:

Styling the list view

I want the list view to fill the entire width of the container. Horizontal lines should separate the items, and the last paragraph of each item — the imaginary price of the item — should be right-aligned.

I will use the same selector I used for the toggle button, except now I am targeting a following sibling (~) instead of the adjacent sibling.

List view of the list

Styling the grid view

The grid view should display the items as separate ‘cards’, each with a shadow to indicate the card. The cards should also have a width of 16em.

Since I used the not-checked state for the list view I will now use the checked state for the grid view:

Grid view of the list

Conclusion

I created two different views of the same elements, just by using a checkbox (with a label with fancy styling) and some CSS that exploited the :checked state of the checkbox.

The full solution can be seen here: https://github.com/tmj-code/toggle-list-view-grid-view

Currently the default is to show the list view. To change that I would have to either swap the ::checked`and :not(::checked)rules, or add the attribute checkedto the checkbox.

--

--

Thomas Møller Jørgensen

Danish software developer. Fullstack. Tolkien fan. Kayaking. Does not drink coffee.