Collapsible navigation without any JS

Semantico labs is built using Bootstrap which includes a neat responsive collapsible nav. We use the :target pseudo-class to expand and contract it without using JavaScript

Dan Shearmur 20 May 2013
This is an article from Semantico Labs, the R&D department of the digital publishing solutions company.


When the viewport width is small enough, the links in the nav bar are hidden and a button to expand the list is shown. Bootstrap includes a jQuery plugin to provide the interaction needed when you click the nav expander button and the nav items animate into view.

On labs we are trying to keep the JavaScript to a minimum. We don’t even include jQuery so using the plugin was out of the question. Instead we use the :target CSS pseudo-class to achieve the same thing without using any JavaScript.

The :target pseudo-class represents the unique element, if any, with an ID matching the hash part of the URL of the document. So http://example.com/#some-id would match the imaginary <div id="some-id"></div>.

We include an ID on the body element of “expanded” and include a .btn.btn-navbar link to #expanded. This means we can change any child of the body using the CSS selector #expanded:target. The collapsible nav includes a height of zero by default so we just need to update the .nav-collapse rule:

This lets you expand the nav but provides no easy way of contracting it (other than the back button). We need to introduce a second .btn-navbar linking to #. We can again use :target to show and hide the correct buttons

The main drawback of this approach is that it will add to your browser history. Instead of clicking back and going to the previous page it will scroll to the top of the current page and contract the nav, requiring you to hit back again to actually go to the last page. This isn’t really a problem for us on labs - more an inconvenience.

Browser support for :target is pretty similar to media queries which are used to hide the nav in the first place.