I’ve wasted enough time re-remembering how to do this now that I figured it was worth documenting the technique for myself.

So, you have an element and you want a border on one or more sides and you want to have a linear-gradient (or indeed any kind of gradient) as the border rather than a solid color.

Something like this:

See the Pen One
sided linear-gradient border
by Ben Frain
(@benfrain) on
CodePen.

The key to the technique is the border-image property. It’s been in browsers for Donkey’s years now. Like iOS 9.3 onwards.

Now I find the shorthand syntax horribly confusing. It’s up there with the grid shorthand where you need decent Backus-Naur chops to understand what’s going on.

The border-image is a shorthand for setting border-image outset, repeat, slice, source and width. Getting all of those correct with in the shorthand syntax can feel like an incantation. 99% of the time, I just want this:

border-image: linear-gradient(to right, red, orange) 1;

That is decepitively to similar to what you likely expect. But what’s with the 1, with no comma before? That’s the value for the slice; how many pieces you need the border-image split into. In the case of our linear border, we don’t need it sliced into more that 1. You can do all sorts of crazy with that value, none of which I have ever used so, I’m not your Huckleberry in that respect!

Now, stick that declaration on your element, see absolutely nothing useful happen and wonder what’s going on. Done that? Cool.

It makes sense when you think about it – you need to set the actual border up too.

border: 1px solid transparent;

Nice, now you got a nice red to orange border all the way around your element. But what if you just want to make a divider of sorts and just need that border on one side?

We just assign the border on the bottom like this:

border-bottom: 1px solid transparent;

Now, suppose you have this applied to a button (there may be other elements too). Ben, what the hell? Why is there still a border on all sides?

You know. Come on.

Yes, some elements have a border by default. In those instances you’ll need to explicitly turn the borders on the other side off.

So, this would do it:

button {
  border: 0;
}

Or, probably more sensibly add it to a class selector for the element in question.

So, let’s get what we know here into a nutshell.

  • You can have a gradient for a border in css
  • You use the border-image property to set the gradient
  • The border-image property is a shorthand for a bunch of properties and is confusing-AF
  • You need a value for the slice of a border-image. If using a simple gradient, just use 1 as the value, with just a space after the gradient
  • You need to have a border set or the border-image won’t show. Think of the border as making a window, the size of which lets more or less of the border-image show through
  • Some elements have borders by default so if you don’t want the gradient on all sides, reset those values

Learn to use CSS effectively, 'Enduring CSS' is out now

Get $5 off HERE ↠

Write and maintain large scale modular CSS and embrace modern tooling including PostCSS, Stylelint and Gulp