CSS beveled corners

Those pesky angled corners in CSS, are not as easy to achieve as rounded ones, but there's few extremely handy methods to do them, other one even works down to IE8.

2013.10.28, see my new article on this including a lot of cool Sass mixins to do all the dirty work.
2013.09.17, added a new technique and better demos.

The a little hacky by still semantic IE8 supporting method

It turns out, we can do trapezoids with CSS. What we’ll do is to place a trapezoid shaped `:before` and `:after` elements on top and under the box.

The HTML:

<div class="module">
    Some content here...
</div>

And the CSS looks like this (Sass again, or SCSS)

$color-gray: #aaa;

.module {
  background: $color-gray;
  position: relative;
  margin: 30px 0;
  padding: 0 20px;
}
.module:before,
.module:after {
  box-sizing: border-box;
  border-style: solid;
  border-color: transparent;
  border-width: 20px;
  content: "";
  display: block;
  left: 0;
  position: absolute;
  width: 100%;
}
.module:before {
  border-top-width: 0;
  border-bottom-color: $color-gray;
  top: -20px;
}
.module:after {
  border-bottom-width: 0;
  border-top-color: $color-gray;
  bottom: -20px;
}

A demo:

See the Pen HcIog by hilja (@hilja) on CodePen

Plusses on this technique:

  • No unsemantic extra elements
  • No images
  • Can be used against a background photo (a big +)
  • Works on IE8

And the minuses:

  • A bit long a hacky (but only a tiny bit)
  • You can’t have border for the whole box. What you can do, is to simulate the `border` with `box-shadow`, but then it’s not anymore IE 8 compatible.

The CSS3 way with gradients and multiple backgrounds

The 4 backgrounds are positioned with background-position to the corners. Then, corners are cut off with angled `(45deg, 135deg, 225deg, 315deg)` gradients.

Very simple and nice HTML

<div class="box">
  <p>
      Some content here... (this <p> is not needed here btw)
  </p>
</div>

And the CSS (add vendor prefixes)

$color-green: #aaa;
.box {
    background: $color-green; /*fallback*/
    background:
        linear-gradient(45deg,  transparent 20px, $color-green 20px),
        linear-gradient(135deg, transparent 20px, $color-green 20px),
        linear-gradient(225deg, transparent 20px, $color-green 20px),
        linear-gradient(315deg, transparent 20px, $color-green 20px);
    background-position:
        bottom left,
        top left,
        top right,
        bottom right;
    background-size:50% 50%;
    background-repeat:no-repeat;
    padding: 20px;
}

Demo time

See the Pen LtpcD by hilja (@hilja) on CodePen

Plusses:

  • No unsemantic extra elements
  • No images
  • Can be used against a background photo (a big +)

Minuses:

  • IE8 and 9 not supported :(

This technique is invented by Lea Verou. See the original article here.

Everything below this point is pretty much irrelevant. Unless you wanna support IE 6 or 7.

The good old browser compilant way with loads of elements and a sprite

There is absolutely nothing new or exiting in this technique, but it works on all browsers, and in the end, is not that heavy or bad. It needs a sprite, but you probably already load a sprite in your theme, right? When saved as png8 with alpha transparency on in Fireworks, it weights 427bytes. If it’s a part of a bigger sprite, not even that. The unsemantic empty divs are of course a drag, but imho, we should not stress over semantics too much, right?

How it works is that we put a div in every corned and apply a background image to that, to diagonally cut half of the div. The background image needs to be same color as the background it is against, white in this case.

Plusses

  • Works on all browser
  • Looks great

Minuses

  • Loads of unsemantic empty elements
  • Uses images
  • Can’t be used against a background photo

The sprite that we’ll put into the divs looks something like this:

The verbose HTML

<div class="box" id="images">
  <p>Beveled corners with god old sliding doors method with sprites.</p>
  <div id="top-left"></div>
  <div id="top-right"></div>
  <div id="bot-right"></div>
  <div id="bot-left"></div>
</div>

And the CSS

#images{background:Pink}
#images div{background:Pink url(sprite.png) no-repeat; height:27px; position:absolute; width:27px}
#images #top-left {left:0; top:0}
#images #top-right{background-position:0 -50px; right:0; top:0}
#images #bot-right{background-position:0 -100px; right:0; bottom:0}
#images #bot-left {background-position:0 -150px; left:0; bottom:0}

See a Demo →

The browser compilant way with CSS tringles

This uses pretty much the same technique as the sprite method. Box corners are cut off with CSS triangels rather than elements with background image.

Plusses

  • Works on all browsers
  • No images
  • Looks great

Minuses

  • Load of unsemantic elements
  • Can’t be used against a background photo

HTML (same as for the sprite method)

<div class="box" id="triangles">
  <div id="top-left"></div>
  <div id="top-right"></div>
  <div id="bot-right"></div>
  <div id="bot-left"></div>
</div>

And the CSS

#triangles{background:#33FFCC}
#triangles div{
  width:0;
  height:0;
  position:absolute;
}
#triangles #top-left {
  border-top:27px solid white; 
  border-right:27px solid transparent;	
  left:0;  top:0;
}
#triangles #top-right{
  border-top:27px solid white; 
  border-left:27px solid transparent;
  right:0; top:0
}
#triangles #bot-right{
  border-bottom:27px solid white; 
  border-left:27px solid transparent;
  right:0; bottom:0
}
#triangles #bot-left {
  border-bottom:27px solid white; 
  border-right:27px solid transparent;
  left:0;  bottom:0
}

See a Demo →

The other, browser compilant way with CSS tringles

I figured out a new way of beveling corners with triangles. This can be on a multicolor background.

See the Pen mGdLy by hilja (@hilja) on CodePen

Here’s the same with different color elements, to better illustrate the structure.

See the Pen ytmAL by hilja (@hilja) on CodePen

Roundup

Where the gradient method is the best of these, lacks it support in lt IE 10 (see the compatibility here). Very small caveat: the bevel is not 100% perfect in Chrome (Mac), look at the left side bevels, looks good on the current Chrome. This is also the only technique that can be applied on non solid color background, added another technique.

The trapezoid method is pretty brilliant! Works on IE8 straight out the box, doesn’t use unsemantic eleents, isn’t too hacky, a tiny bit only. I’d use that possibly.

After these two, all other methods are pretty much useless.

There’s also an editors draft of Border Corner Shape that enables us to do beveled corners as easily as rounded corners. But, it’s just a draft, and nobody knows will it ever make it to the spec.

Banana for scale

Here also will be something. Some day. After this is out of beta, which is never. This is also a hyphenation test. Look, a long word: extracurricular.