This is a demonstration of a vertical accordion panel using pure CSS, plus automatical sizing the content panes if Javascript is available.
Hey man, I thought this was suppose to be pure CSS, what gives?
Look, it is the best of both worlds. You want just CSS? Fine. Remove all the Javascript code - the accordion will still work great. The only limitation is the height of all the panels will have to be manually determined.
Features:
|
Limitations:
|
For IE8, the Accordion panels do not work, but the fallback is to simply always show the content. In other words, all the panels will be expanded if using IE8. I have not done much testing, but it does work with these:
Something has to trigger the various CSS styles. Since I wanted touch devices to work, the :hover
pseudo-selector was out. I stole the concept of using a radio button group to trigger the sliding action. The magic that makes this possible is the :checked
pseduo-selector.
ul.accordion > li > div { overflow: hidden; height: 0; } input[type='radio']:checked ~ div { height: 100px; }
When the page is first loaded, the content panes, which are always wrapped in a <div>
, have their height set to zero. When their corresponding radio button is checked, then the <div>
is given some height.
If you want to force a particular panel to always be expanded (opened) then apply the CSS class “expanded” to the panel’s <div>
. You you want to dynamically apply that class via Javascript, call function expandPanel(). For example:
<a href="#thirdPanel" onclick="expandPanel(2);">Show Third Panel</a>
The CSS transitions only work when they can vary numeric values. The accordions open by adjusting the height value from 0 to 200px (for example) and from 200px to 0 when closing the panel. This is great when all the panels have the same height, but if they vary you will have to explicitly define the “opened” height for each panel. In the best case, that is tedious; in the worst case (it may be loaded via AJAX and you have no idea what the content will be) it is impossible.
You could set the “opened” height to auto (height: auto;
), but then the CSS transitions will no longer work. Remember, they need to transition between two numbers and 0 to "auto" is not valid.
After the page is loaded, all the accordion panels are hidden from view and then measured to see how tall they are.
The code will loop through all the panels, calculate their height, and then create a CSS class called “heightXX
” where XX represents the number of pixels talls that panel is.
If the browser window is resized, then that same measurement process is performed again because the panels will very likely be a different height.
The CSS selectors make some assumptions about how the HTML is written. For these accordion panels to work, you must use this style of markup.
<ul class="accordion"> <li> <input type="radio" name="radio" id="radio1" class="visuallyhidden" checked> <label for="radio1">Introduction</label> <div> <p>Content goes here.</p> </div> </li> <li> <input type="radio" name="radio" id="radio2" class="visuallyhidden"> <label for="radio2">The Pure CSS part</label> <div> <p>Content goes here.</p> </div> </li> <li> <input type="radio" name="radio" id="radio3" value="0" class="visuallyhidden" > <label for="radio3">Progressive enhancement when Javascript is turned on</label> <div> <p>Content goes here.</p> </div> </li> <li> <input type="radio" name="radio" id="radio4" value="0" class="visuallyhidden" > <label for="radio4">HTML Structure</label> <div> <p>Content goes here.</p> </div> </li> </ul>
Source code can be found on Github.