Create a notched current-state nav

Ben Everard tweeted last night asking if anyone knew how to build a notched nav, like this. I was in bed at the time, I spotted it about midnight and was on my phone. As soon as I saw this I jumped out of my bed and turned my Mac on. I love stuff like this!

Anyway, this is my solution, and this is its code.

Basically there are two main parts to this technique; the punching-the-hole-through-the-nav and the masking-the-hole-to-be-a-triangle. Both techniques couldn’t be simpler, and we use pseudo elements to do it.

Punching holes through elements

This whole technique can only work by taking advantage of the behaviours of fixed background images. The exact same background:; applied to two elements give an odd result if both are also fixed. It gives the effect of a hole having been punched right through your page to the background…

What we do here, then, is create a pseudo element with .nav .current a:before and sit this at the bottom of the current list item. We then apply the fixed background to this as well as the page. This is our punched hole already sorted, only it’s square… we want a triangle.

Masking the hole

To mask the hole to appear like a triangle we use another pseudo element and the CSS triangle hack to cover things up.

The triangle hack works by selectively applying borders to zero width/height elements, take a look at this version with the triangles highlighted. All we need to do here is make some of them the same colour as the nav and we’re done!

So, by cleverly using a pseudo element we can spoof a hole through elements and then using a second one we can mask the corners off!

The full, commented CSS:

.nav{
	overflow:hidden; /* To clear floats */
	background:#111;
	margin:0;
	padding:0;
	list-style:none;
}
.nav li{
	float:left;
}
.nav a{
	display:block;
	padding:2em /* <-- This is our magic number, this defines how large our notch can be! */ 1em;
	color:#fff;
	text-decoration:none;
}
.nav a:hover{
	text-decoration:underline;
}
.nav .current a{
	position:relative;
	text-decoration:underline;
	cursor:text;
}
.nav .current a:before,
.nav .current a:after{
	content:"";
	display:block;
	width:2em; /* Must match our magic number... */
	height:2em; /* ...our notch will end up being half this size. We define it in ems to scale it up with the text size. */
	position:absolute;
	bottom:0;
	left:50%;
	margin-left:-1em; /* Half of our magic number. */
}
body,
.nav .current a:before{
	background:url(http://farm5.static.flickr.com/4102/4876702379_82fe2bd7a8_b.jpg) top left no-repeat fixed; /* Apply to the notch and the relevant container (this case, body). */
}
.nav .current a:after{
	width:0;
	height:0;
	border:1em solid #111; /* Half of our magic number and same colours as our nav's background. */
	border-bottom-color:transparent;
}

Drawbacks

There are drawbacks here; you have to have a fixed background image and you have to have a solid background colour for your nav, but they are reasonable trade-offs, considering this doesn’t use any extra markup at all and works in IE8+!

By Harry Roberts on Tuesday, November 8th, 2011 in Web Development. Tags: , | 5 Comments »

+

5 Responses to ‘Create a notched current-state nav’


  1. graup said on 8 November, 2011 at 10:44 pm

    Glad you got rid of the masking png ;-) Quite a nice solution.


  2. Josh said on 9 November, 2011 at 12:44 am

    I’m glad you decided to write this up Harry. It’s always much more informative than simply reading through the links you post on Twitter.

    I was convinced there was a way to do this without the drawbacks. I posted one method on Twitter last night but it didn’t work in IE8, but after a fair bit of messing about I think I have come up with a solution.

    It requires the use of an additional pseudo-element, but that is fine considering we have a few spare. I used the :before and :after pseudo-elements on the list item to fill the background of the menu leaving a 20px gap in the center. I then use the :before pseudo-element on the anchor to fill the gap using the triangle borders technique, similar to what you have done in your write-up.

    Here is the coloured version, illustrating the technique: http://jsfiddle.net/sl1dr/bba5M/

    And here is how it would appear in the wild: http://jsfiddle.net/sl1dr/U3KBC/

    I don’t have the level of knowledge that you do Harry so if you wouldn’t mind casting a critical eye over my code I would appreciate it!


  3. Chris said on 9 November, 2011 at 2:43 pm

    Well done! It’s amazing how many different ways we can achieve things.

    I figured out another way of creating notches, without the use of psudo elements, that shows whatever content is beneath it: (And it should work in IE6… I think?)

    I think it’s drawback is it’s reliance on images, but you can make the notch whatever shape you like.

    Step 1:
    You will need to create a background image for the selected tab. Make a transparent notch in it. Next, I positioned the notch so half of it was at the left side of the image, and half on the right side (though in retrospect, I imagine you can have the whole notch at the beginning or end for ease).

    Step 2: Set the image to be the background of the <a> element, repeat-x, and offset it so the notch is in the middle. (this is tricky if your tabs are different sizes)

    Step 3: Offset the <li> and <a> elements so they overhang the content.

    In writing this, I feel like I’m missing something… it sounds “too easy”, but it shouldn’t be much more complex. I think I made it harder on myself because the client’s branding had a red line that needed to be a part of the notch….

    …irregardless, I won’t be able to put it in a JSfiddle for a while, but if you want to see it in action, you can visit it here: http://www.e-streetdirect.com/es/overview.html

    If someone else wants to JSFiddle it, please do so, I’m not associated with that company, and I


  4. felicja said on 14 November, 2011 at 1:55 pm

    It’s nice solution but inflexible. You will want to add a shadow or replace it by icon and then have to change your approach. Small little PNG takes at least 0.5 KB and you can do everything with it. For the sake of flexibility it’s a good price.


  5. Sophie S-K said on 11 May, 2012 at 1:49 pm

    Actually I think the premise of this is pretty darn cool. I had no idea where you wre going with the “magic number” and “50% width” and so on until I read the last snippet of code where you specified the border colours.

    Very smart for what it is, even if it is a little inflexible, but it suits Ben’s original brief I suppose. :-)


Leave a Reply

Respond to Create a notched current-state nav

Hi there, I am Harry Roberts. I am a 21 year old web developer from the UK. I Tweet and write about web standards, typography, best practices and everything in between. You should browse and search my archives and follow me on Twitter, 7,791 people do.

via Ad Packs