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.scot/tutorials/php/2/1/#extra.
What we want to see
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:
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).
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.