Bevelled box corners with CSS and Sass

Image

Say you’re trying to pull off a design effect where the corner of an element are cut off. Maybe you’re a Battlestar Galactica fan? Or maybe you just like the unusual effect of it, since it avoids looking like a typical rectangle.

[…]

I suspect there are many ways to do it. Certainly, you could use multiple backgrounds to place images in the corners. You could just as well use a flexible SVG shape placed in the background. I bet there is also an exotic way to use gradients to pull it off.

But, I like the idea of simply taking some scissors and clipping off the dang corners. We essentially can do just that thanks to clip-path. We can use the polygon() function, provide it a list of X and Y coordinates and clip away what is outside of them.

Code language: CSS

.box {
  --notch-size: 2em;
 
  clip-path: polygon(
    0% var(--notch-size),
    var(--notch-size) 0%,
    calc(100% - var(--notch-size)) 0%,
    100% var(--notch-size),
    100% calc(100% - var(--notch-size)),
    calc(100% - var(--notch-size)) 100%,
    var(--notch-size) 100%,
    0% calc(100% - var(--notch-size))
  );
}

I’ve written a Sass mixin to make this easier to reuse:

Code language: Sass

///
/// Bevel all four corners of an element by the specified amount.
///
/// This is based on the linked article by Chris Coyier.
///
/// @author Matei "Ambient.Impact" Stanca
///
/// @link https://ambientimpact.com/web/snippets/bevelled-box-corners-with-css-and-sass
///
/// @param {Number} $size - The amount to bevel by.
///
@mixin bevel($size) {
  clip-path: polygon(
    // Top left corner points.
    0%          #{$size},
    #{$size}    0%,
    // Top right corner points.
    calc(100% - #{$size}) 0%,
    100%        #{$size},
    // Bottom right corner points.
    100%        calc(100% - #{$size}),
    calc(100% - #{$size}) 100%,
    // Bottom left corner points.
    #{$size}    100%,
    0%          calc(100% - #{$size})
  );
}

You can use it like so:

Code language: Sass

.box {
  // Really simple version:
  @include bevel(1em);
 
  // If you want to use CSS custom properties for browsers that support them,
  // you can do so. The benefits are that these cascade like other CSS
  // properties, so they can be inherited, and modified in real time. This must
  // come after the simple version.
  --bevel-amount: 1em;
  @include bevel(var(--bevel-amount));
}