CSS tips and tricks #13 – Design accordion menu in CSS without JavaScript tutorial

Table of Contents

Challenge we will face today is creating an accordion menu only with HTML and CSS. No skills in JavaScript or jQuery will be involved or required from you. Accordion will contain five tabs with content inside each of them. All tabs will be stacked vertically. Content will be shown only after clicking on particular tab. All tabs will be stacked vertically. When no content will not take any space until it will be displayed.

This project / challenge will require only one external resource, which will be font “Ubuntu” hosted on Google CDN. No reset or normalize stylesheet will be used. Below is link to font and also links to live demo on Codepen and code on Github repository.

Resources:

Font Ubuntu:

http://fonts.googleapis.com/css?family=Ubuntu

Links:

Codepen live demo:

https://codepen.io/d3v3r0/pen/ywFnq

Github codes:

https://github.com/d3v3r0/CSS-Accordion-menu

Without further ado let’s start work on our today’s project.

HTML

As always, first and most important part is HTML structure. I will assume that you already have a valid HTML structure with doctype, html, head and body tags, so we can jump right to creating the accordion. As said in introduction, accordion will contain five items along with some content. You can get this done by using elements such as section, article or div and modify their behavior and styling, but the easiest way is to use plain unordered list (<ul></ul>) and list items (<li></li>) for individual sections. Each list item will contain anchor tag (<a></a>) with class “tab” and div with class “content” and id “content-1” (the number will be different for each div). These ids will be used to wire anchor tags together with divs via “href” attribute. Inside the div will be nested paragraph (<p></p>) with random text.

HTML:

<ul class="accordion">
 <li>
  <a href="#content-1" class="tab">First</a>
  <div id="content-1" class="content">
   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
  </div>
 </li>
 <li>
  <a href="#content-2" class="tab">Second</a>
  <div id="content-2" class="content">
   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
  </div>
 </li>
 <li>
  <a href="#content-3" class="tab">Third</a>
  <div id="content-3" class="content">
   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
  </div>
 </li>
 <li>
  <a href="#content-4" class="tab">Fourth</a>
  <div id="content-4" class="content">
   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
  </div>
 </li>
 <li>
  <a href="#content-5" class="tab">Fifth</a>
  <div id="content-5" class="content">
   <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
  </div>
 </li>
</ul>

– note: If you are looking for some Lorem ipsum generator, check lipsum.com.

This is all we need to create the skeleton of accordion. Now, we can move to CSS to style it and add functionality.

CSS

As in every project we will start with setting the default font size for the project to keep ems constant across various browsers, devices and user settings. Let’s use 16px as font size and also set “Ubuntu” as default font with “sans-serif” as fallback.

CSS:

/*=Typography=*/
body { font: 16px 'Ubuntu', sans-serif; }

Next thing, before moving to accordion, is to modify rendering of padding on elements. What we want is to make padding not impact the width and height of the elements. To do this use “box-sizing” property set to “border-box”. We will use this rule on all elements including their “:before” and “:after” pseudo-classes.

CSS:

/*=Layout=*/
*,
*:before,
*:after { box-sizing: border-box; }

Basic setting of the environment is done so let’s move to accordion. First, set the margin to “0 auto”. This means “0px” for top and bottom margin and “auto” for left and right margin. There will remain some white space. We can fix that by setting “padding” to “0”. “width” of accordion will be “20em” and “height” will have value of “auto”. To get rid of bullet points on list items use “list-style-type” set to “none”.

CSS:

.accordion {
 margin: 0 auto;
 padding: 0;
 width: 20em;
 height: auto;
 list-style-type: none;
}

Let’s now focus on anchor tags with class “tab”. First, set the “display” property to “block”. This, with “width” and “height” set to “100%”, will force tag to use whole width and height of list item – whole item will be clickable. Let’s indent the text from sides a bit by setting the “padding” to “.5em”. Background will be set to dark blue – #34495e and color to light grey – #e6e6e6. To remove underline set the “text-decoration” property to “none”. To divide the individual tabs, so we distinguish between them, create a solid bottom border “.1em” thin and dark blue color – #3d566e (it is lighter shade of blue we used for background). Two things are remaining. First is styling “:hover” state by setting background to lighter blue – #415b75 – and then using “transition” set to “background .25s” animate the transition between backgrounds. First part is the property transition will be applied to and second is for duration – time it will take to go from start to end.
CSS:

.tab {
 display: block;
 padding: .5em;
 width: 100%;
 height: 100%;
 background: #34495e;
 color: #e6e6e6;
 text-decoration: none;
 border-bottom: 0.1em solid #3d566e;
 transition: background .25s;
}
.tab:hover { background: #415b75; }

Now it’s time to modify the divs with class “content”. We will start by indenting the text by setting “padding” to “0 .5em” (top-bottom left-right). “max-height” will be set to “0” and “overflow” to “hidden”. This will hide whole content are and the text as well. Since “height” property cannot be animated by “transition”, we used ”max-height” instead. With this setting, we will be able to create sliding effect when user click on tab. Let’s continue by setting the “background” to almost black blue – #272c30 – and color to light greyish blue – #979fa2. As said above, we want to create sliding animation. To get this done let’s use “transition” property and set it to “max-height” with duration of “.25s”.

CSS:

.content {
 padding: 0 .5em;
 max-height: 0;
 background: #272c30;
 color: #979fa2;
 overflow: hidden;
 transition: max-height .25s;
}

We are almost done. The only thing to do is to create a mechanism for showing the content when we click on tab. This will be done through CSS “:target” selector and “max-height” property. In HTML we set “id” attribute on each of divs and then used this “id” in “href” attribute for anchor tags. Thanks to this, “:target” selector will cause that when we click on certain link, the rules for “:target” selector will be applied to div with “id” that is the same as “href” of active (clicked) anchor tag. The “max-height” property can be set to almost whatever value you want because, as the name suggests, the element will take height according to its content up to value specified by you. However, don’t set it to low or it will cut the content and show only part of it. To make sure that all will be shown you can set to, for example, “100em”. Don’t worry height will always be set relatively to the content with the “max-height” used only as a maximal possible value.

CSS:

:target { max-height: 10em; }

Summary

Well, we are done. Great job ladies and gentlemen! Challenge accepted and solved. We created vertical accordion with sliding animation using only HTML and CSS. I hope you enjoyed this tutorial and also learned something new.

Thanks for your mails that led to creating this tutorial.

If you liked this article, please subscribe so you don't miss any future post.

If you'd like to support me and this blog, you can become a patron, or you can buy me a coffee 🙂

By Alex Devero

I'm Founder/CEO of DEVERO Corporation. Entrepreneur, designer, developer. My mission and MTP is to accelerate the development of humankind through technology.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.