Samuel Champagne

An improved <hr>

Oh great horizontal rule, how thou art loved. You help us divide up and structure our content. Unfortunately, you aren’t known for having great default styling.

In chromium based browsers the user agent declaration for <hr> is this:

hr {
  display: block;
  margin-inline-start: auto;
  margin-inline-end: auto;
  margin-block-start: 0.5em;
  margin-block-end: 0.5em;
  border-width: 1px;
  border-style: inset;
  overflow: hidden;
  unicode-bidi: isolate;
}

While most of this is fine, the code at fault is the border-style: inset. While seeing it does tickle my nostalgia for the web of the 90s and early 2000s, an inset border is not exactly “good looking” by modern sensibilities. Not a problem though, as we can easily override this with our own css.

Typically a web developer might do something like this:

hr {
  border: none;
  border-top: 1px solid;
}

This is a pretty simple and straight-forward solution, entirely replacing the original border with a 1px wide border-top. That said, while this is perfectly fine in most all cases, there is a better way.

How? By using a background instead of a border.

hr {
  border: none;
  background: currentColor;
  height: 1px;
}

As you can see, we can achieve the same result using a background. A 1px wide line that matches the current text color.

However, it doesn’t stop there! We can of course use a gradient or any other valid background.

hr {
  border: none;
  background: linear-gradient(270deg, #349179, #5789da);
  height: 2px;
}

Another option might be to use an image to create a textured look. You can see an example of this here:

We can also animate our background:

hr {
  animation: AnimationEffect 4s ease infinite;
  border: none;
  background: linear-gradient(
    270deg,
    #349179,
    #5789da,
    #35a4b0,
    #7ca58a,
    #35a4b0,
    #5789da,
    #349179
  );
  background-size: 400% 100%;
  height: 2px;
}

@keyframes AnimationEffect {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

You can see an example of that here:

Hopefully you can see the potential of this method. And while I’m not going to say that everyone needs to switch to using this in all their projects, I personally have chosen to include it in FirstStrike.css, my lightweight and modern alternative to normalize.css.

It’s always fun to find new ways of doing things, especially when it’s something that’s been overlooked by most people. I hope you consider doing the same!

And don’t forget to check me out on twitter at @samuelchampagne