Edmundo Santos

CSS Chevron Separator

Recently, I was (re)designing a new feature for the Artillery dashboard that highlights important statistics such as total test runs, success and fail rates, and extra information such as the total number of virtual users created across all tests.

Given that we ship new features pretty fast at Artillery, a considerable amount of my discovery, prototype, and design work is done straight into code — so I tend to look for solutions that can increase the speed of doing those iterations.

For this specific case, I was designing a floating bar that would use a chevron-style separator between its inner elements. I had an overall idea of the style I wanted for this, but I always like to play with different options until I find something that feels right.

The reason why I decided to use CSS for this instead of a SVG file, is that with CSS I can quickly iterate over the style of the chevron, changing the angle, border style, and spacing intervals without needing to go to Figma and re-export SVGs every time I had a new idea.

Below you can see the resulting CSS snippet for this:

:root {
  --chevron-angle: 30deg;
  --chevron-border: 1px solid white;
}

.chevron {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.4rem 0.8rem;

  &::before,
  &::after {
    content: "";
    position: absolute;
    right: 0;
    height: 50%;
    border-right: var(--chevron-border);
  }

  &::before {
    top: 0;
    transform: skewX(var(--chevron-angle));
  }

  &::after {
    bottom: 0;
    transform: skewX(calc(var(--chevron-angle) * -1));
  }

  &:last-of-type::before,
  &:last-of-type::after {
    display: none;
  }
}

The code uses two pseudo-elements that are absolute positioned to the right side of their parent. Each is given half the height of its parent, pushed to opposite sides, and skewed on the X-axis with a predefined --chevron-angle property. The result is a simple chevron separator.

The final version

Artillery’s usage stats
The final version on Artillery’s dashboard uses Tailwind CSS

Although I love PostCSS and CSS modules, on Artillery’s dashboard we prefer using Tailwind CSS. Here’s the code for one of the statistics seen in the image above:

<div className={
  clsx(
    'relative flex items-center gap-1 px-4 py-2', // item styles
    'before:absolute before:right-0 before:top-0 before:h-1/2 before:skew-x-[30deg] before:border-r before:border-white', // top half of chevron
    'after:absolute after:right-0 after:bottom-0 after:h-1/2 after:-skew-x-[30deg] after:border-r after:border-white', // bottom half of chevron
    'last-of-type:before:hidden last-of-type:after:hidden', // remove the last separator
  )}
>
  <b>142</b>
  <span>test runs</span>
</div>

Over the course of this year I grew to actually enjoy writing CSS with Tailwind, and although I don’t particularly like how it reads, it makes for extremely fast prototypes.


Feel free to play around with it, there’s loads more you can create using variations of this technique. For instance, by setting a background and width on the pseudo-elements and changing their angles, you can also create ribbons and arrows, using only CSS.

© 2024 Edmundo Santos
Last updated on