Grow your CSS skills. Land your dream job.

Adobe-like Arrow Headers

Published by Chris Coyier

Adobe has some pretty cool header bars for modules on their site. The header bar is divided into left and right sections. The left being an explanatory title and the right being a related link. But let's get super critical of how they did it.

First of all, they use a non-sprited image to do it:

That means an extra HTTP request just for the headers. Worse, the :hover effect is a totally separate image. That means yet another HTTP request and a "flash of black" while the second image loads on your first hover.

We can do it with zero images! Here's our version:


View Demo   Download Files

The markup for the header is just a title with a link inside:

<div class="module">
  <h2>Community <a href="#">Blue</a></h2>
  <!-- stuff in module -->
</div>

Here's the basic setup of the header, with the link on the right with basic coloring, including the straight white line made by a border:

.module h2 {
	background: #ccc;
	padding: 0 0 0 10px;
	font-size: 16px;

	/* Thickness of the bar more easily achieved with line-height
	   since padding would push link inward.  */
	line-height: 2; 
}
.module h2 a {
	float: right;
	position: relative;
	text-decoration: none;
	color: #333;
	padding: 0 10px;
	border-left: 5px solid white;
}

Now the trick to getting the arrow within the line is just using CSS triangles applied via the ever-useful pseudo elements.

.module h2 a:before,
.module h2 a:after {
	content: "";
	position: absolute;
	/* Pushed down half way, will get pulled back up half height of triangle
	   ensures centering if font-size or line-height changes */
	top: 50%;
	width: 0;
	height: 0;
}
.module h2 a:before {
	left: -12px;
	/* Triangle */
	border-top: 8px solid transparent;
	border-bottom: 8px solid transparent;
	border-right: 8px solid white;
	/* Pull-up */
	margin-top: -8px;
}
.module h2 a:after {
	/* Smaller and different position triangle */
	left: -5px;
	border-top: 6px solid transparent;
	border-bottom: 6px solid transparent;
	border-right: 6px solid #a2d6eb;
	margin-top: -6px;
}

One significant difference between ours and theirs is that they have a gradient that goes right through the triangle. That's not possible with ours as it's not practical to apply gradient with the CSS triangle technique. That's not to say gradients are out though, you'd just need to make sure that where the triangle attaches to the main link, the color is solid.

For the demo page I added a few different colors, transitions, and examples where double-triangles could be used to fake an angled line.

View Demo   Download Files

Comments

  1. Ghufran
    Permalink to comment#

    Thank you sir you are doing a great job, I have seen your training on Lynda.com and you are a very good teacher. Thank you so much…

  2. Scott
    Permalink to comment#

    For newer browsers, you could use the transform property and rotate a square by 45 degrees. Although I suppose you’d need to make sure the square is positioned above the left header panel but below the right header panel with some z-index trickery.

    • Permalink to comment#

      yes – plus, you could do this with the :before and apply a border to it (or box-shadow with spread) and still have the :after to do something else with.

  3. Make sure to put this in snippets!

  4. Permalink to comment#

    Very nice – perfect for some breadcrumbs. I’ll need to check to see what our friend IE thinks of this.

  5. Jimmy
    Permalink to comment#

    very cool, thank you!

  6. Permalink to comment#

    Two words, kick and ass…

    Thank you…

    • tom10s
      Permalink to comment#

      I agree with your enthusiam Daniel, just not your addition.

  7. Using the same concept, I recently added an arrow within a link/button. Works great … except I can’t get rid of a second 1px border on the transparent sides. Your demo has the same ghost border in my browser. Seems to be related to FF8 and the font color, I think.

    Unfortunately I still haven’t found a solution.

    • Amos Vryhof
      Permalink to comment#

      Try changing the border style to “inset” on the transparent sides of the element.

    • See my comment below about transparent and how it’s the wrong value. Setting the border-style to “inset” is the wrong solution.

  8. Andy Doyle
    Permalink to comment#

    You could rotate a pseudo element by 45deg and (i guess only in webkit) assign a diagonal gradient to it.

  9. Permalink to comment#

    Very nice!

    Two comments:

    1) I see the same border Jeremy mentioned with FF 7

    2) What does the above response have to do with this demo? Another damn SPAMMER! (Editor’s note: removed)

  10. Please don’t use transparent! People who use a Superior Browser (e.g. Firefox) which do antialiasing suffer, because transparent isn’t what you meant. Remember that transparent is equivalent to rgba(0,0,0,0) (transparent black). Look at the demo page in Firefox and you’ll see why you need to not use transparent, but instead values like rgba(255,255,255,0) (transparent white).

    • JK
      Permalink to comment#

      I don’t see a difference between “transparent” and rgba(255,255,255,0) in Firefox. What do you mean?

    • Permalink to comment#

      Ahh… I finally figure the antialiasing stuff. The black shadow has been annoying me for so long on Firefox.

      Thanks a lot Chris!

    • @JK: it’s in the antialiasing. If you’re going from color X to no colour, you need the other side to be transparent X, not transparent black. It’s only along the diagonal edges that it will show. In an area of solid fill, rgba(255,255,255,0) will always look the same as rgba(0,0,0,0)—transparent. One way to help you think about it is taking a larger gradient (the antialiasing is basically a gradient of up to 3px length) from #ccc to transparent and comparing it with a gradient from #ccc to rgba(204,204,204,0). The result is very different.

      In the demo as it stands the diagonal edges are very ugly in Firefox while they’re merely suboptimal in Chrome or IE (by dint of their not being antialiased).

      I’ve almost finished a verbose blog post on the topic, I’ll try to remember to post a link here when I’ve started said blog and posted it.

    • Brilliant. That did the trick. Thanks

  11. Kelly Cook
    Permalink to comment#

    This is how the back button is styled in SenchaTouch. Confusing, but once you get the hang of it, makes perfect sense! Great article!

  12. Enrique
    Permalink to comment#

    It’s great but I was just wondering… What font do you use for the part where it says the before and after pseudo element?

    • Permalink to comment#

      Great article Chris. I like all the extra stuff to be learned from reading the comments, like the FF anti–aliasing thing.

      Enrique, the font looks like it’s Light up the World.

  13. Great Article… Still confusing for me… but i will give it few more reads to understand the functionality at before and after…

    Thanks !

    • Ryan
      Permalink to comment#

      Yeah, I’m still working on wrapping my mind around :before and :after. I think I just need to practice with some pseudo elements, rather than just read articles about them.

  14. Permalink to comment#

    This one I just love! Great work!

  15. Permalink to comment#

    Couldn’t you just add a 45-degree linear gradient to imitate any gradient that would occur in the middle section of the link, and have it line up once rotated? It would involve a bit of math, but otherwise, it seems a trivial solution to that problem.

  16. shlomy
    Permalink to comment#

    use a picture , much easier , and you dont have to do so many brosers support.

    but this is a great technique

    • Browser support for pseudo elements are excellent. IE6 & IE7 will not see the arrow but will have a sufficient fallback.

      Using images means more http requests and longer loading times (yes, it will be tiny differences, but still).

      So it comes down to what’s more important and appropriate for the current project, speed and resources or backwards compatibility.

    • cnwtx
      Permalink to comment#

      That difference gets much bigger on a internet connection like mine, at 0.6 mbps.

    • T.J. Crowder
      Permalink to comment#

      @Ludwig: The demo page doesn’t degrade nicely on IE6 at all, the links end up below the banners and just generally things don’t look good. But if you’re designing for IE6, you know you’re facing some challenges. :-) Fortunately, most people don’t have to design for IE<8 anymore, and even big corporations and government departments are finally phasing in at least IE8 so even that niche will soon be free of the IE6/7 shackles. Designers for sites targeting China, though, look like still being stuck with them a while longer. But we’re nearly there!

  17. Bacha
    Permalink to comment#

    this is realy nice tutorial thanx any body tell me bout best javascript book or tutorials website……thanx in advance

  18. Felix
    Permalink to comment#

    Wow! Awesome work. I feel very lucky for accidentally coming across your website today. Definitely won’t be the last time.
    Greetings from Germany :)

  19. Permalink to comment#

    These are great, thanks for the tutorial!

  20. Such an amazing post. Thanks!

  21. Permalink to comment#

    Nice touch. Added your site to my morning coffee list :)

  22. Tapiochre
    Permalink to comment#

    As far as gradients go couldn’t you make the arrow transparent and the none arrow elements white then place it in a div with a background gradient? I’m looking into this myself, and really liked your example. Thanks

  23. Tapiochre
    Permalink to comment#

    The following may not be as neat but it provides a gradient arrow. Is this any use to anyone?

    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
       "http://www.w3.org/TR/html4/loose.dtd">
    
    <html lang="en">
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    	<title>untitled</title>
    	<meta name="generator" content="TextMate http://macromates.com/">
    	<meta name="author" content="Web Developer">
    	<!-- Date: 2011-12-22 -->
    	<style>
    	
    	* {margin:0; border:0; padding:0}
    	
    	.left-arrow-bottom {
    	  border-color: transparent transparent #cacaca #cacaca;
    	  border-style: solid;
    	  border-width:5px;
    	  width:0;
    	  height:0;
    	}
    	
    	.left-arrow-top {
    	  border-color: #cacaca transparent transparent #cacaca;
    	  border-style: solid;
    	  border-width:5px;
    	  width:0;
    	  height:0;
    	}
    
    	.link-left{
    		float:left;
    		width:8px;
    		margin-left:2px;
    		}
    		
    	.link{
    		float:left;
    		color:white;
    		margin-top:8px;
    		background-color:transparent;
    		background-image:url("images/vgradient.gif");
    		background-position:2px;
    		background-repeat: y-repeat;
    		width:120px;
    		}
    
    	.link-right{
    		float:right;
    		width:8px;
    		}
    		
    	.button {
    		background-color:transparent;
    		margin-left:2px;
    		padding-left:2px;
    		padding-right:4px;
    		}
    	</style>
    </head>
    <body bgcolor="#cacaca">
    <div class="link">
    	<div class="link-left">
    		<div class="left-arrow-top"> </div>
    		<div class="left-arrow-bottom"> </div>
    	</div>
    	<span class="button">Home</span>
    	</div>
    </div>
    <div class="link">
    	<div class="link-left">
    		<div class="left-arrow-top"> </div>
    		<div class="left-arrow-bottom"> </div>
    	</div>
    	<span class="button">About Us</span>
    	</div>
    </div>
    <div class="link">
    	<div class="link-left">
    		<div class="left-arrow-top"> </div>
    		<div class="left-arrow-bottom"> </div>
    	</div>
    	<span class="button">Contact</span>
    	</div>
    </div>
    </body>
    </html>
    
  24. Paul
    Permalink to comment#

    FYI

    The demo doesn’t work in IE8
    ( it’s sad but true)

  25. I have to say, I truly dig this sort of stuff. @Paul does it fallback gracefully in IE8? I’d have to fire up a VM to check that out for sure but I’m certain that could be handled through conditionals, or maybe even employing Modernizer?

  26. Robert
    Permalink to comment#

    @Chris Morgan
    You’re my hero! I was having the firefox anti aliasing issue when I was creating a CSS speech bubble. I couldn’t figure out for the life of me why firefox was adding extra lines. Using rgba(255,255,255,0) did the trick!

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".