Menu Search
Jump to the content X X
SmashingConf London Avatar

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf London, dedicated to all things web performance.

Mobile Navigation For Smashing Magazine: A Case Study

Since we started plodding around on this rock in space, human beings have always been dissatisfied with their environment — which is (mostly) a good thing. Otherwise we might still live in caves, fearful of the weather and worshipping the sun. It’s dissatisfaction and curiosity which drive us to fix things that ain’t broken.

Back in spring 2013, Smashing Magazine sported a <select> menu as its mobile navigation. It wasn’t considered an anti-pattern back then and I still think it’s a viable solution to the complex problem of how to build accessible1 and functional cross-device navigation. Brad Frost wrote a few words about the pros and cons of this pattern2 on his blog and I couldn’t agree more.

Screenshot of the mobile view of Smashing Magazine from 2013
The mobile navigation in early 2013 – not exactly a beauty, but fully functional.

While it worked nicely, it also had a few problems. Mostly, it wasn’t the most beautiful piece of UI on the web and we had to throw some JavaScript on it to make the experience somehow worthwhile. Rebuilding this mobile navigation was one of the early tasks given to me after I started working here in January 2013.

Further Reading on SmashingMag: Link

Replace All The Things Link

My first move towards a new and shiny mobile navigation was to kick the <select> menu in the bin and look around the web for options and best practices. Some articles6 about responsive design7 and a whole lot of round-ups8, code examples9 and Git repos10 later I came to this conclusion:

Write down the underlying HTML to have a solid base, then take care of the styling, and when that’s done you might look for possible JS additions, if needed. And finally: testing, testing, testing!

Still progressive enhancement running the game.

For this article, I went as far as to rebuild one of the prototypes from back then with simplified HTML and CSS in CodePen (no media queries, no reset, just code from the top of my head). The jQuery part came in later on, after we realized that some people were confused when the toggle buttons didn’t become inactive and weren’t replaced after clicking/tapping them. After a short but intense phase of tests and adjustments, we decided to deploy it to the live blog in the middle of June 2013.

See the Pen BNrxLZ11 by Marco (@Nice2MeatU352412) on CodePen362513.

One of the early prototypes for the new mobile navigation.

Note: Feel free to take the code and tinker with it. You can also use it as a starting point for a project of your own or commercially or whatever. There is no license or copyright to it. That being said: No guarantees or support! I wouldn’t recommend copying and pasting the code into a project and simply leaving it there as is.

When Good Is Not Good Enough Link

You might recognize the feeling, creeping up your spine over days or weeks, that some of your work just doesn’t feel 100% right – may be 97% or 98% but definitely not the whole cake. This is what happened to me after some time passed by and I kept interacting with our new navigation. The closing buttons felt out of place and the jQuery part kept bothering me, since while it served its purpose well, it should not have been part of the experience, but just an enhancement. Without JavaScript enabled, the user experience I envisioned crumbled to bits. So I started over, tweaking and adjusting and rewriting and trying out different solutions to the same problem over and over again, whenever I found the time.

While it has been a really time-consuming task, it’s also been a lot of fun to try out so many different solutions to the same problem. It was also worthwhile as now we had options to choose from – options we could test for performance, usability and the overall experience. Just to make this clear: building prototypes early on in a project can save you a whole lot of time later on. Sometimes it’s the slightest change from one version to the next that makes all the difference.

Screenshot of several folders with different versions of a build for a mobile navigation
At some point the folders started to pile up.

In December 2013, just after Christmas and while I was on holiday, Vitaly made a decision and went for a CSS-only solution by following the footer anchor pattern14. He moved the navigation and the mobile search to the footer of the website but kept the buttons on top. That way it wouldn’t be an issue if the buttons looked the same after the click/tap because they would be out of view. As we’d had the “Back to top” links in the Magazine since day one, there already was a solution to the problem that people might want to jump back to the header of the page.

Yes But No But Yes But No Link

This time we received some emails with feedback on our decision to change the navigation pattern. When I returned to my desk in January 2014, a few users had filed bug reports about feeling completely lost after jumping down a whole page of the Magazine. Other users told us that while the buttons had already rendered on their mobile phone, they tapped them but didn’t go anywhere as the footer hadn’t loaded owing to their slow connection.

Another issue raised was that some users didn’t find the “Back to top” link. They landed in the mobile menu and there was no option visible to simply return to the header: the link was out of view, above the navigation. Again, we had ended up at the point where we had something that wasn’t exactly broken, but it wasn’t the complete solution as well. Two steps forward, one step back.

Mobile navigation collapsed - The look from 2013 until 2015
That’s the way our mobile navigation looked when collapsed.
Mobile Navigation toggled
And here’s the expanded view after adding a “Back to top” link.

So Little Time, So Much To Do Link

During the period between June 2013 and Fall 2014, I was completely occupied with many different tasks15. I don’t want this to sound like an excuse, but being the only developer at Smashing Magazine means I work on a lot of different projects at the same time. I have to stay up to date with external developers and have at least one eye on Trello, one on Basecamp and one in my email inbox, while I always need both my remaining eyes for Skype and Slack (our constant meeting rooms). I think you understand by now that there’s an anatomy-related problem.

That being said, I worked on the Smashing Magazine site and our Conference websites16. We had a redesign for the shop17 behind the scenes, where I had been involved from time to time, and we also had a few projects that never saw the light of day. A few landing18 pages19 needed to be designed and developed, and other sites20 needed a complete revamp.

Long story short: the prototypes for the navigation were left lying around untouched for one and a half years until I was finally able to return to them.

April Showers Bring May Flowers Link

In April this year, Vitaly opened a request on our Trello board to replace the infamous hamburger icon with the word “Menu.” This sounded like an excellent opportunity to finally get my hands on the mobile navigation again.

The first thing I did was the task at hand. The hamburger icon went into the same bin the <select> menu once did and now we had “Menu” displayed as text.

Mobile navigation, collapsed, in 2015
The mobile header of Smashing Magazine now.

The next step was to think of possible improvements and a solution to the closing mechanism. The goal set was: no JavaScript – an easy enough task but having a CSS-only solution is rarely seen as the sexiest one. The last solution built had the closing buttons inside the elements I made visible with the :target technique. For more information on the :target pseudo-selector, I recommend you to read Chris Coyier’s thoughts on the dos, don’ts and possible use cases21. In case you wondered, support for this selector22 is perfect in the mobile landscape.

If you’ve never heard of the :target selector before, here is the most basic example I could think of:

See the Pen ZGRXGw23 by Marco (@Nice2MeatU352412) on CodePen362513.

Very basic example of :target

Web Development Is Never Easy Link

That looks too easy to be true, right? And yes, it is. The technique is simple and effective but there are two issues with it:

  1. You need a second anchor to hide what you revealed.
  2. You add to the browser history with every click.

While the first one might not look like a big deal, I can assure you it is. Let me explain what happens when you click on the “Menu” button in the Magazine. I’ll spare you most of the CSS related to our mobile search, as that follows the same pattern, and show you the parts that differ. I also added a few comments to the CSS to explain my thoughts behind those values.

What I wanted to achieve is a congruent closing button on top of the “Menu” button, covering it when the navigation is visible. The look and feel should be just as if you had a JavaScript toggle in place. The same goes for the search and its related closing button, which has a different size and position.

Here are the inline styles from our <head> section (slightly altered for easier understanding), the so-called critical CSS26 part:

header {
  width: 38.2%;
  margin-left: 5.5%;
  padding: 1.25em 0;

  /* To make the logo clickable when the navigation or the
     search are overlaid */
  z-index: 3;

.mobile-toggle-buttons-container {
  position: absolute;
  top: 1.5em;
  right: 1.5em;

  /* Again, to keep the buttons clickable when the closing
     button is overlaid. That way you can either just
     close the nav or switch to the search or click the logo. */
  z-index: 4;

.search-toggle-button {

  /* This makes it easier to match the width and height with
     the closing buttons */
  box-sizing: border-box;

  float: right;

  border: .08em solid #C73A11;

  border-radius: .25em;
  box-shadow: 0 .08em .08em rgba(0,0,0,0.25);

.search-toggle-button {
  /* If you wanted to hide the text but keep it accessible */
  text-indent: 150%;
  overflow: hidden;
  white-space: nowrap;

  /* Sweet technique to serve SVG to all capable browsers
     and leave the rest with PNG */
    url(search-icon.png) no-repeat 50% 50%,
    url(search-icon.svg) no-repeat 50% 50%,
    -webkit-linear-gradient(to bottom, #e95c33, #e95c33);
    url(search-icon.svg) no-repeat 50% 50%,
    linear-gradient(to bottom, #e95c33, #e95c33);

  /* You need to declare the background-size for WebKit
     otherwise it will do funny things to your SVG image */
  background-size: 1.875em auto;
  -webkit-background-size: 1.875em;

  padding: .4em;
  width: 2.9375em;

/* Nothing special from here on */
.navigation-toggle-button {
  text-transform: uppercase;

  margin-left: 1em;
  padding: .4em;

  color: #fff;
  background: #e95c33;

.mobile-search {
  width: 100%;
  height: 0;
  max-height: 0;
  padding-top: 0;
  opacity: 0;
  transition: none;

.mobile-navigation ul,
.mobile-search form,
.mobile-search-closing-button {
  display: none;

I don’t think any of the CSS needs a lot of explanation apart from what I gave away in the comments. If you still have trouble with one or a few selectors, attributes or values, hit the comment section and fire those questions!

If you want to get a deeper insight into the gradient-svg-png technique, I will gladly send you over to Pau Giner’s blog, where I found his article27 on the subject. The text replacement28 technique for the search button by Scott Kellum is one of many ways29 to come to such a result. In case you’re wondering why I am working with such an odd value of .08em, there is a very good reason for that: browsers are very bad at rounding – they just don’t get it right. Here’s a very basic CodePen example of the issue30.

Overwriting The Critical CSS Part Link

Now for the part that overwrites what we declared in the above-the-fold styles after a button has been clicked or tapped. All the following CSS is in the main style sheet (again, this is not the actual code but optimized for this context):

.mobile-search-closing-button {
  /* Again, this is for a bit of ease when we want
     to match the height and width of the "show" buttons */
  box-sizing: border-box;

  /* Here we already have the closing button for the nav in
     position */
  top: 1.5em;
  right: 1.5em;

  text-align: center;
  padding: .4em;
  width: 2.9375em;
  background: #e95c33;
  border: .08em solid #C73A11;

  border-radius: .25em;
  box-shadow: 0 .08em .08em rgba(0,0,0,0.25);

/* Width needs to match the nav button */
.mobile-navigation-closing-button {
  width: 3.8em;

/* Position needs to match with the search button */
.mobile-search-closing-button {
  right: 6.3em;

/* If one of the containers becomes targeted */
.mobile-search:target {
  /* The z-index is lower than anything in the header */
  z-index: 2;

  /* To prevent the browser window from scrolling
     down so the buttons in the header would become un-
     clickable without scrolling back up, we have to use
     this not so beautiful hack */
  top: -10em;
  padding-top: 10em;
  margin-bottom: -8em;

  /* This transition ensures a nice animation when
     opening the navigation or search */
    opacity .4s ease-out,
    max-height .4s ease-out;

  height: 100%;
  max-height: 62.5em;
  opacity: 1;

/* By using the adjacent sibling combinator (only works with a
   certain markup, of course) I have full control over my closing
   buttons */
.mobile-navigation:target + .mobile-navigation-closing-button,
.mobile-search:target + .mobile-search-closing-button {
  /* Closing buttons have the highest z-index as they have to
     sit on top of the "show" buttons */
  z-index: 5;

  display: block;

Again, I tried to use the comments to explain my way of thinking. I hope it all makes sense to you.

Finally, here is the underlying markup, the basis of our mobile navigation:

<body id="top">
  <div class="mobile-nav-buttons">
    <a href="#mobile-navigation" role="button" title="Jump to the main navigation">Menu</a>
    <a href="#mobile-search" role="button" title="Jump to the search">Search</a>
  <a href="#content">Jump to the content</a>
  <header role="banner">
    <h1><a href="/">
      <span>Smashing Magazine</span>
      <img src="logo.png" alt="The logo of Smashing Magazine" /></a></h1>
  <nav class="mobile-navigation" id="mobile-navigation" role="navigation">
    <ul class="mobile-nav-ul">
      <li>Smashing Pages</li>
      <li><a href="#">Nav Item One</a></li>
      <li><a href="#">Nav Item Two</a></li>
      <li><a href="#">Nav Item Three</a></li>
      <li><a href="#">Nav Item Four</a></li>
    <ul class="mobile-nav-ul">
      <li>Smashing Categories</li>
      <li><a href="#">Nav Item Five</a></li>
      <li><a href="#">Nav Item Six</a></li>
      <li><a href="#">Nav Item Seven</a></li>
      <li><a href="#">Nav Item Eight</a></li>
  <a class="mobile-nav-closing-button" role="button" href="#top" title="close the navigation">X</a>
  <div class="mobile-search" id="mobile-search">
      <label for="mobile-search-input">Search on Smashing Magazine</label>
      <input id="mobile-search-input" type="text" />
      <button type="submit">Search</button>
  <a class="mobile-search-closing-button" role="button" href="#top" title="Close the Search">X</a>

By using the adjacent sibling combinator31 to hide and show the closing buttons, the markup needs to be exactly as it is in the example HTML here, with the link for closing the navigation directly following the nav container. As I am currently working my way through the W3C accessibility tutorials32 to learn more on best practices with accessibility33, the jump links to the navigation, search and content had to come first in the DOM tree. That way, people with a screen reader have a few options to skip content they don’t need or want to read over and over again.

Takeaway For You Link

Now that you’ve come this far I want to give you something practical. I reduced the code to its bare bones and made a CodePen out of it. Take it, play with it, use it for any project and improve it where possible. There is no license, no copyright, no warranty, no guarantee and no support for the code provided. Handle with care!

See the Pen Bare Bones CSS Only Toggle Navigation34 by Marco (@Nice2MeatU352412) on CodePen362513.

The bare-bones CSS toggle navigation

I also put together a little ZIP package for you. You can download it37 right away.

Finishing Touches Link

Currently, Christian Brückner from Inpsyde38 and I are trying to progressively enhance the experience a little further. We are looking into ways to work against the second issue. You remember? Every time you click the nav button or the closing button, you’re adding an entry to your browser history. To prevent this we are looking at the HTML5 History API39 and other possible solutions like using window.location.hash.

In terms of accessibility we will switch from <li> to <label> for the navigation headlines Smashing Pages and Smashing Categories.

All of the above being said, I think the way we built this is very personal and works for us. I don’t want to proclaim anything like this is it, and I still think we could do better, too. We have ongoing discussions about different ways to integrate the search on mobile which could render the current solution obsolete. Another issue I have with this build is the positioning of the closing buttons not being right on all mobile devices out there because browsers are pretty bad at math!


Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11 ''
  12. 12 ''
  13. 13 ''
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23 ''
  24. 24 ''
  25. 25 ''
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34 ''
  35. 35 ''
  36. 36 ''
  37. 37
  38. 38
  39. 39

↑ Back to top Tweet itShare on Facebook

Marco Hengstenberg is a former front-end developer at Smashing Magazine, and currently works as a Pixelpusher & Websitewrangler at NIMIUS. He was previously a web-administrator, a web designer, a digital media designer, a barista, a book-seller and was called some other names he does not want us to mention here. You can find some of his work on Github.

  1. 1

    Thank you for sharing this in full detail. I’ll play around with your solution.

  2. 2

    thanks Marco,it’s great.
    your Github link is invalid.

    • 3

      Thanks for pointing out and thanks for the positive critique on the article.

      I got married this year and changed my last name, hence I had to change it everywhere on the web as well. Seems that one link slipped.

  3. 4

    Md. Shohel Rana

    September 21, 2015 11:34 am

    At IE, white background does not come.

    • 5

      What version of Internet Explorer are we talking about here? =)

      • 6

        Every IE up to version 10 have issues with white background (It doesn’t recognize “” tag).

        And in Firefox Smashing Magazine menu have issue only in mobile mode (ctrl + m) – the closing buttons don’t work at all.

        • 7

          ‘Main’ tag

          • 8

            Ah. I see, now.
            Of course the HTML5 shiv or some CSS normalization will help to get that problem fixed.

            Yet, as I wrote just before the first example Codepen:

            (no media queries, no reset, just code from the top of my head)

            I did not aim for wide browser-support when providing these examples. Those were meant to be tinkered with.

        • 9

          Can you tell me what OS and version of Firefox you are using?

          I’m developing firstly and mainly in Firefox and it worked in this browser since day one, hence I’m wondering what went wrong.

          • 10

            Firefox 40.0.3 on Windows 7 I run into the same issue, can open the menu but not close it when viewing the site in responsive mode (Ctrl + Shift + M) and even when just reducing the size of the main browser window.

        • 11

          Heya Qbin2001 and Danny,

          I just fired up a Win7 machine and installed the current Firefox version.
          Unfortunately I wasn’t able to recreate the behaviour you described.

          When I make the viewport thin enough to make the mobile navigation buttons show up they function as expected: one click -> Closing Button appears, nav appears -> second click -> nav shut and closing button gone (same with the responsive view enabled).

          Unfortunately that means: won’t fix for you. =(

          • 12

            Windows 7 x64 Firefox 40.0.3 had problem with closing in responsive mode. I updated to version 40.1 and there is no problem anymore. Strange…

  4. 13

    Hey, what’s wrong with worshipping the sun?

  5. 14

    > You remember? Every time you click the nav button or the closing button, you’re adding an entry to your browser history. To prevent this we are looking at the HTML5 History API and other possible solutions like using window.location.hash.

    You can use `event.preventDefault()` to prevent adding a entry to the history:

    • 15

      Just realised I had to add “active” classes when disabling the default event – so you need :target and .active selector – maybe not the cleanest solution.

      • 16

        Where and why would you have to add a class and what “default event” do you want to disable?

        Have you had a look at the source of the “Bare Bones” example I provided at the end of the article?

        From my experience the whole thing works without any classes. The only thing you need is to provide an ID for the :target selector to jump to.

    • 17

      Oh my. Sorry. The comments showed up in reversed order.

      My view on this (noone has to agree to):
      When enhancing with JS things will surely get more complicated but as we are talking enhancements (not default behaviour) this should not interfere with the experience originally built/thought out for the user. Adding a class to the source-code and then deleting it again is not that bad for the UX, right?

  6. 18

    Fantaaaaastic article, Marco! o/

  7. 20

    What’s the reasoning for moving from an to a for the category caps? Wouldn’t or potentially make more sense?

    “The label element represents a caption for a form control.” —

    • 21

      Well, we were still in discussion about this subject as the article was in the making.

      We will definitely take the headlines out of the <ul> elements and make them real headlines. That way they won’t appear as list-items.

      Thanks for pointing out, Mike! =)

  8. 22

    Let me start by saying that the solution in itself and the article are great.

    The question in my mind is, is it even the right solution?

    There’s increasing evidence that hamburger menus, or any other menu that toggles and hides all menu items by default, perform very poorly. Whether this is true for SM or not I do not know, but I’m hoping you researched this?

    • 23

      Heya Ferdy,

      thanks for the critique, much appreciated! =)

      For your question – yes, we did some research and I’ll happily share a few things we found out along the way:

      1. The first task most people perform when coming to the blog is reading the newest article (surprise, surprise).
      2. Our main navigation (Books, eBooks and so on and so forth) isn’t used as much as we would like it to be,
      3. whereas the mobile navigation and search perform quite nicely and are often used in order to jump to certain categories in the Magazine or to search for specific fields of interest.

      So, yes, you are right with the claim that a toggle menu is widely regarded as an anti-pattern (especially when it comes to apps and more or less on websites) and yet, when your visitors’ main goal is to click a headline, an image or a “Read More” button, why should you shove them your navigation in the way on each and every page?
      Especially when following a link to an article you don’t want to be greeted with 12 links in a navigation but with the precious contents you wanted to digest, right?

      All of the above being said: there’s always room for improvements and we are constantly on the look-out for best practices. Thanks for sharing the link to this article, it gives a nice overview on the whole problem with mobile toggle navigations. =)

  9. 24

    Nice article, and a great technique, haven’t heard about the :target before,..
    Thanks for sharing

  10. 25

    Phillip Gruneich

    September 22, 2015 3:45 am

    Did you try a “checkbox hack” navigation?

    1. It achieves the same visual result;
    2. Is CSS only;
    3. Doesn’t pollute the browser history.

    • 26

      Hello Phillip,

      funnily enough another developer approached me with the same question yesterday and we had a short but intense discussion about “what approach is the better approach”. We settled on: “it depends”.

      If you care more about semantics, you won’t go for the checkbox solution. Then there’s the issue about the progressive enhancement of things: what if CSS fails? The HTML base (form, checkbox, label) you have to create won’t help you get things right, where the standard HTML5 <nav> element with an unordered list of links inside will always do its job.

      I will also have to find some data on the accessibility layer of things as I’m wondering if the checkbox solution could create some issues with that but I know that the anchor-jump-to-navigation-pattern won’t cause any irritiation with screenreaders or other assistive technology as it is baked into browsers from the very beginning of the web itself.

      What a long sentence this is. Anyways, I hope I was able to explain the way of thinking behind my solution a little better. May be I should have included that in the article already.

      • 27

        Phillip Gruneich

        September 22, 2015 7:31 pm

        Great explanation, Marco. I agree that your solution has better semantics and won’t raise accessibility issues, although there may be a way to avoid the latter with aria-labels (big question mark since those are still wizardry to me).

        What I’ve been doing lately is an anchor tag linking to a select navigation in the footer for non-js/non-css users and I enhance the menu with Javascript (event.preventDefault() to avoid the jump) and hide the footer .

        I think it is a reasonable approach to the problem, I don’t think the issue demands a radical solution, just some progressive enhancement.

        • 28

          Aria-* Attributes will definitely help users in that case. It’s like you are telling (e.g. a screenreader) an assistive technology:”Hey, here’s a radio button but it is just a button. You see, there is this role="button" attribute on it.” and the same goes with all the other elements inside that checkbox-hack-nav.

          I could also think of a Flexbox-solution, where the values are thusly changed so the Navigation will jump to the top when triggered – using CSS or JS that is. Using Flexbox the source-order would be irrelevant and you could go with a navigation-first approach or nav-last or in between.
          But yeah, with Flexbox come the Flexbugs:

  11. 29

    Lately I’ve been reading the trend of losing the hamburger icon or menu because of semantics and mobile navigation issues involving common and repetitive tasks (such as using the thumb as “mouse”).

    You should expand this way of thinking to frameworks. That would be great

  12. 30

    This was really helpful and thorough, thanks!

  13. 31

    The (only) downside I see in here: double markup (at least in SMs case), besides that: a really nice solution.


↑ Back to top