SCSS Mixin – Rabbet Border

This border style is achieved by creating four empty divs within the parent container.
Each div needs a class named rabbet--top, rabbet--bottom, rabbet--left, and rabbet--right respectively. As well as a class that specifies your desired border parameters, such as rabbet--20px--4px--primary, later defined by our CSS Mixin.

CodePen

HTML

<div class="content">
  <h2>Heading</h2>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea nulla in commodo consequat. Duis aute irure dolor in aliqua sit.</p>

  <div class="rabbet--20px--4px--primary rabbet--top"></div>
  <div class="rabbet--20px--4px--primary rabbet--bottom"></div>
  <div class="rabbet--20px--4px--primary rabbet--left"></div>
  <div class="rabbet--20px--4px--primary rabbet--right"></div>
</div>

CSS

We must use the following box-sizing: border-box; reset and ensure that the parent div containing the four empty divs is set to position: relative;

*,
*::before,
*::after {
  box-sizing: border-box;
}

.content {
  position: relative;
}

The mixin requires 3 arguments:
$size defines the dimensions of the rabbet shapes
$width defines the border width
$color defines the border color: relative;

@mixin rabbet($size, $width, $color) {
  .rabbet--#{$size}--#{$width}--#{$color} {

    ...

  }
}

All four classes should be set to position: absolute;

&.rabbet--top,
&.rabbet--bottom,
&.rabbet--left,
&.rabbet--right {
  position: absolute;
}

The rabbet--top and rabbet--bottom elements both need to be 100% of the parent element’s width subtracted by the size of both rabbet shapes. We can accomplish this with width: calc(100% - #{$size * 2});

We also need to center both rabbet--top and rabbet--bottom horizontally using margin-inline: auto;

We then create the pseudo classes and give them a width and height. This gives us the elements that will later become the four rabbet shapes in each corner, the borders are defined later.

&.rabbet--top,
&.rabbet--bottom {
  margin-inline: auto;
  width: calc(100% - #{$size * 2});

  &:before,
  &:after {
    content: '';
    position: absolute;
    width: $size;
    height: $size;
  }
}

We do the same for rabbet--left and rabbet--right except both elements need to be 100% of the parent element’s height instead of width, also subtracted by the size of both rabbet shapes.

We also need to center both rabbet--top and rabbet--bottom vertically instead of horizontally using margin-block: auto;

We do not need pseudo classes within rabbet-left and rabbet-right.

&.rabbet--left,
&.rabbet--right {
  margin-block: auto;
  height: calc(100% - #{$size * 2});
}

Using the inset property, the rabbet-top element is placed at the very top of its parent element and has a border-top to draw the entire line.

The before pseudo element will be the top-left corner’s shape, and the after pseudo element will be the top-right corner’s shape. They are already positioned absolutely (see above) within the rabbet--top element. Now we just determine where to place them with the inset property, and also how to draw the borders in order to create the appropriate rabbet shape.

The same applies for rabbet-bottom but adjust as necessary.
We will skip rabbet-bottom in an effort to keep this article concise.

&.rabbet--top {
  inset: 0 0 auto 0;
  border-top: $width solid var(--c-#{$color});

  &:before,
  &:after {
    border-bottom: $width solid var(--c-#{$color});
  }

  &:before {
    inset: -#{$width} auto auto -#{$size};
    border-right: $width solid var(--c-#{$color});
  }

  &:after {
    inset: -#{$width} -#{$size} auto auto;
    border-left: $width solid var(--c-#{$color});
  }
}

The rabbet–left element is placed at the very left of its parent element and has a border-left to draw the entire line. The same applies for rabbet–right. These elements are centered vertically (see above) to fit between the rabbet shapes.

&.rabbet--left {
  inset: 0 auto 0 0;
  border-left: $width solid var(--c-#{$color});
}

&.rabbet--right {
  inset: 0 0 0 auto;
  border-right: $width solid var(--c-#{$color});
}

Now we include as many variations of the mixin as we desire! Simply enter the argument values and then ensure that they match the classes in your HTML markup.

@include rabbet(20px, 4px, primary);
@include rabbet(40px, 8px, secondary);
@include rabbet(80px, 16px, tertiary);

CodePen