iOS Style "Back" Button in CSS

You know that button in iOS[foot]Most frequently on the iPhone.[/foot] that takes you up a level in an app? It's like a regular button, but the left side is an arrow? I think that's a wonderful visual cue for what the button does, and I recently implemented it for a web app at work. Here's how I did it.


The idea is to break the link into three parts:
  1. the actionable link,
  2. the main box of the button, and
  3. the triangle/arrow of the button.

The Actionable Link

The HTML for this is simple: [prettyprint lang="html"]<a class="btn-back" href="#">Back</a>[/prettyprint] Of course, you can use a button or whatever element fits your needs. The basic styles for the link are: [prettyprint lang="css"].btn-back { display: inline-block; position: relative; z-index: 1; padding: 0 10px 0 30px; line-height: 44px; }[/prettyprint] Using inline-block allows the button width to size dynamically to the content. The position and z-index are to position our pseudoelements. The padding and line-height are to position our link within the button. This code gets us this:

The Main Box

A pseudoelement is used for the main box of the button: [prettyprint lang="css"].btn-back:before { content: ''; position: absolute; box-sizing: border-box; left: 20px; right: 0; height: 34px; margin-top: 5px; z-index: -1; border: 1px solid #000; border-left-width: 0; border-radius: 5px; }[/prettyprint] The box is positioned absolutely to and behind the link. It's given a border on all sides except for the left side, and the border-radius gives it the familiar "button" look. The button now looks like this:
We could drop a pseudoelement and apply these styles directly to the link, but separating them allows us to separate the size of the target from the visual size of the button. On a touch device, for example, the target area for the link could be bigger than the visual size of the button to allow for less accurate tapping.

The Triangle/Arrow

So far everything's been pretty standard CSS fare. Pseudoelements are rather widely supported. This next bit makes use of CSS transforms which are less well supported. Concessions could be made[foot]via Modernizr or some other form of feature detection[/foot] at this point to allow unsupportive browsers to be shown a standard button by adding back the left border. For browsers that support it, this gets the full effect: [prettyprint lang="CSS"].btn-back:after { content: ''; position: absolute; box-sizing: border-box; left: 11px; height: 27px; width: 26px; top: 8px; z-index: -2; border: 1px solid #000; border-top: 0 transparent; border-right: 0 transparent; border-radius: 7px 5px 5px 7px; -webkit-transform: rotate(45deg); }[/prettyprint] This pseudoelement is just another box rotated 45 degrees. Using a transform instead of a CSS triangle allows for a lot more possibilities. It gets positioned behind everything else to help hide any weird artifacts. Some browsers will show some bits of top and right borders even though they've been removed.[foot]I'm sure it's just a rendering issue[/foot] The border is massaged a little to help mesh with the main box. The final button:


The button is rather skeletal at the moment. At this point it is very versatile and can be dressed up to match the design of it's environment. A few customizations and we have this:
I like this technique. It provides an intuitive fallback for browsers that don't support key properties, and it provides a lot of flexibility for styling and implementation. It does require a fixed height, though, because the measurements for the boxes have to be exact for it to look right.