January 7, 2016 | 36 Feedbacks

Vertical Fixed Navigation #2

A smart vertical navigation, with round indicators that turn into labelled icons when the user interacts with them.
Browser support
  • ie
  • Chrome
  • Firefox
  • Safari
  • Opera

Our first concept of vertical fixed navigation is one of our most popular resources. This time, we tried to push this concept a little further.

The basic idea behind putting round indicators on the side of a web page, is to give a hint to the user about the number of sections she/he can go through. We think of each dot as a content chapter, with its own title. Usually, users have to hover over a dot to access the title.

In an attempt to simplify this pattern, we decided to transform the dots when the user interacts with them, by scaling them up and showing an icon + label. Users don’t need to select a specific dot/item, but just move to the side, thus showing their willingness to access the navigation.

Here is a quick preview of the final result (created using After Effects):



Creating the structure

Our navigation is an unordered list wrapped in a A is used to open the navigation on small devices.
Besides, a has been created for each navigation item.

Adding style

On small devices (viewport width smaller than 800px), we set a position: fixed for the .cd-nav-trigger and <nav> elements and  placed them at the bottom-right corner of the page; we then scale down the navigation, using the bottom-right corner as transform origin.

When user clicks on the .cd-nav-trigger element, we give the .open class to the navigation to change its scale value from 0 to 1, with a CSS3 transition to achieve a smooth animation.

On bigger devices, we use Modernizr to detect touch and no-touch devices (using.touch and .no-touch classes).
On touch devices, the lateral navigation items (labels and icons) are visible by default, while on no-touch devices they are shown when the user hovers over the lateral navigation.

We set a fixed height and width for the <nav> element, and place it on the right side of the viewport. We use its ::before pseudo-element to create the navigation background; on no-touch devices only, the ::before element is, by default, translated to the right (outside the viewport) and is moved back to its original position when the user hovers over the navigation. The same happens for the span.label elements.

To create the navigation item icons and dots, we use, respectively, the ::after and ::before pseudo-elements of the navigation anchor elements (<a>). On no-touch devices only, the ::after and ::before are scaled down by default and then scaled back up when the user hovers over the navigation.

Now the tricky part: when the navigation dots are scaled down, they are too distant one from the other. We can reduce this distance translating them along the Y axis.

Let’s start from the central dots (in our case, the second and the third); we want to translate down the second one (so we have to use a positive translate value), while we want to translate up the third one (so we have to use a negative translate value). In our case we have:

Then, the translate value for the first dot is gonna be three times the one of the second dot, and the same for the fourth one (three times the translate value of the third dot).

If you have a different number of navigation items, you have to change these translate values accordingly. For example, if you have six items, starting again from the central dots (in this case, the third and the fourth), you can assign them a translateY value of 1.5 em/-1.5em; then to the second and the fifth a translateY value of 4.5em/-4.5em (3*1.5), and finally to the first and sixth a translateY value of 7.5em/-7.5em (5*1.5).

If you have an odd number of items, let’s say 5, you do not translate the central one (in this case the third one). You then assign a translateY value of 3em/-3em(2*1.5) to the second and the fourth dots, and finally a translateY value of 6em/-6em(4*1.5) to the first and fifth dots.

Events handling

When user scrolls through the sections, the updateSections() function evaluates which section is currently being viewed and assigns the .active class to the corresponding navigation item.
Besides, we listen to the click event on the to open/close the navigation on small devices.


Jan 07, 2016
  • Resource released by CodyHouse

Claudia Romano

Web developer, fan of The Big Bang Theory and good food. Co-founder of CodyHouse and Nucleo. You can follow her on Twitter.

  • Philipp Wüthrich

    I’m using chrome and the navigation is always expanded…

    • Claudia Romano

      Hi Philipp, that’s probably because you’re using a touch device (different user experience for no hover effect)

  • Frank Frick

    Awesome idea! Feels much cleaner than labels directly on top of the page content.

  • Gavin

    What a cool, slick effect. Love it! Works great in Chrome on Ubuntu.

  • josgerrits

    I like the idea but its not really user friendly imo. Whenever i want to click the first label and move to it with my mouse i’ll be selecting the second label since the positions change. Maybe lose the icon and just display a text left of the dots so the positions of the label don’t change? :)

    • Sebastiano Guerriero

      That’s an interesting point. Tweaking the size of the icons/text could prevent such thing. However, while experimenting with the resource, I noticed that when I move to the side and the panel slides in, after a fraction of second I become aware of the whole navigation content (the experience is not a super fast move + click, but more a “display the navigation”). And IMO it doesn’t affect the experience in a bad way. But still it depends by the page content etc…

  • Harri Owen

    the spacing between navigation items to get a bit messy when i add more than 4 items in the vertical navigation? is there a way to fix this?

    • ben

      I would also like to know if there’s a fix for this

      • Harri Owen

        Not ideal but removing some rules in styles.css from 288 to 349 removes the shrinking effect of the first 4 items and makes them evenly spaced. Adding the same rules for extra list elements Li:nth-of-type(5) and 6 ect may help them all to shrink however.

    • Claudia Romano

      Hi Harri, please take a look at the article (specifically the Adding Style section), where we explain how to handle more items. Cheers! @disqus_1rvzEIrlV3:disqus

      • Harri Owen

        Thanks for that! All sorted.

  • humphrey humphries

    Thanks so much for this tutorial. Although am newbie in CSS3 and the jquery. its my hope one day these two brothers wont have to crack my brain to understand them

  • Oliver

    That’s really cool, great work. For me it would be nice to see the Navigation for a short time until the site is fully loaded (and then getting back to small) so you know there is more behind the nav than just the dots and you may use it more often instead of just scrolling down

    And why not set the nav-items on smaller devices on the bottom beside one another (when there are not more than 4 items), at least between 420-800px viewpoint size? I think this would be a nice ‘between’ the super small nav (with the trigger) and the larger one on the right side. Just an idea.

    PS: I love having the nav on the right side (and not left as most times) bc for me my mouse is focusing mainly the right side and the same when using a touch device with the fingers of my right hand.

  • Mariano

    Hello Claudia, beautiful work.
    Can I ask if I can use this example in a Joomla site and you tell me if this is possible and appropriate documentation to figure out how to do?
    Thank you

  • Mark Mathis IV

    As a critique, and I’ll implement this change if I use this great submission, I would place the nav in a more traditional area (ie, left align, top right as a tab, or some sort of bottom/top banner). The latter example would, of course, obfsucate the content so I’d use that with a hide element.

    • jonathanober

      the right nav is good though on mobile devices where users tend to hold in their right hand and that side is just a thumb tap away.

      • Dennis Kummer

        That is what I thought. I don’t understand why menus are mostly on the top. Where it is hardest to reach for the thumb. I like it when UI is made for one hand usage.

  • Hands in the Attic

    Cool I love the effect! Thx

  • gskema

    Hello, could you elaborate your solution to detecting touch? Modernizr only detects if the browsets supprots the API. Some people combine this with agent string matching. Or do you just choose ignore this and display based on APi detection to “be better safe than sorry”?

  • Wil

    I love the effect and i understand the problem its trying to solve. Its clean, shows more info on hover. Issue: having dots and having a hover effect would be like the hamburger button and its hidden navigation issue. If the user would not know that these dots show more after hover, and i am assuming the scroll bar is hidden, then it would be challenging to know the navigation is there.

    • Jason George

      That’s something to be tested against your user base, in my assessment. The argument that certain navigation design patterns confuse users or do not provide enough affordance is totally legit, but I am also of the opinion that as these patterns become more widely accepted, it’s fairly safe to assume that a large number of users identify a line of dots or a hamburger icon as a navigation element, and that navigation content is stored behind it.

  • Borys Sychkov

    It’s really cool decision for mobile, thank! I’ll use your menu immediately))

  • Nigel Wade

    As mentioned by someone earlier, Modernizr does not detect touch/no-touch devices, it detects whether the operating system is touch enabled and the browser supports the API. This is well a documented bug/feature. Unified operating systems like windows 10 (and probably) 8 are touch enabled on all devices, regardless of whether a touch input device is attached or available. It may be worth elaborating on that point as your statement is slightly misleading. On desktop Windows 10 (and I suspect 8) all browsers will get he touch version.

  • Hdeprada

    Great great great. I love it! Thanks!

  • Zexin Li

    a very cool detailed user experience!

  • martian36

    Great! I implemented this to side menu at my client’s WordPress site and he was delighted at it!
    Thanks for share. I love Codyhouse.

    • BADR

      can you please tell me how did you integrate it in you wordpress theme

    • Peter Kulcsár


      It looks great :)!
      Can you please share your code with me? I would likely implement this too on my client webstore :).


  • willobdesign

    This is great – would like to add more pages to this but am a relative newbie. Would anyone care to share their code? :)

  • Alex Rincon

    I am having trouble changing the icons, every time I edit the .svg using illustrator it resizes them so that all of the icons I add are in one circle. Can anyone help me with this?

  • guillermogfer

    Have someone try this with real mobile devices? In my case, the sections are expanded much far from screen dimensions and have to scroll a lot to change between sections. Does this happen to anyone? Possible fix? It’s a pity because I really like to implement this in one of our websites

    • guillermogfer

      Ok, it seems to be the browsers I am using with mobile devices don’t support the viewport section resize with height: 100vh;

  • Robert Zubrycki

    Hi, Claudia, can you explain to me how to change icons in the nav (i got 6 li’s in ul) and fix position of dots, dot 5 and 6 are a lilttle bit lower.

    • Robert Zubrycki

      i’ve sorted out problem with dots, now i wanna fix images, can i use my own icons? And how to do this

  • pixelneco

    i guess this is not working 100% on Firefox anymore or am i wrong? On my Macbook + Firefox 47.0.1 i get the mobile navigation because of the touch event.