To use this website fully, you first need to accept the use of cookies. By agreeing to the use of cookies you consent to the user of functional cookies. For more information read this page.

Design tips: fixed menus and fragment identifiers

11 Sep 2016 at 21:09
Fixed menus (ones that float) are very popular, but they do have issues. Specifically I'm talking about fragment identifiers, since they do not include the offset of the fixed menu. In this article, I'm going to show you a nifty little trick with CSS that fixes this.

Fixed menus (ones that float) are very popular, but they do have issues. Specifically I'm talking about fragment identifiers, since they do not include the offset of the fixed menu. In this article, I'm going to show you a nifty little trick with CSS that fixes this.

What we want is for the browser to appear at the correct place when we use a fragment identifier (e.g. #extra) when the user types a URL such as intro/#extra. With a fixed menu this is not always the case since the menu adds a bit of extra floating content on the screen that the browser does not identify at first. The following two images show what we want to see and what we actually get. In this case the URL I'm demonstrating with is within my PHP tutorial and is https://www.jamiebalfour.com/tutorials/php/2/1/#extra (testing this will not mess up because I've fixed it on my website).

What we want

What we want to see

What we get

What we get

As you can see, the first image, which is what we want, is not the same as the second. This is because the h2 element is behind the fixed menu. So how do we fix this?

I'm going to explain. 

Firstly, let's add a :before pseudo-element to the h2. This element will give some extra padding to the top and it should have the following CSS:

CSS
h2:before{
    content: "";
    display: block;
    height: 60px;
    margin: -60px 0 0 0;
}

This now creates an empty pseudo-element above the h2. This kind of acts as a padding, but really it's just an element with nothing in it. However, the problem is that elements that are directly above the h2 will not be clickable since they are behind the pseudo-element. 

We fix this by ensuring that the h2 itself has the following CSS. This will force the backwards, behind it's container (make sure it's container is transparent just in case).

CSS
h2{
    position:relative;
    z-index:-1;
}

Alternatively you can give the element the CSS attribute pointer-events and give it the value none. Both of these ideas struck me when I was trying to figure out the most effective solution, since I previously used the solution of giving a negative margin and then re-doing the margin by adding a padding but this has the problem of making everything before the element un-clickable or selectable (unless you use the pointer-events attribute). Also, with the main solution provided here the user can still select the item on the screen to copy with.