CSS Multicolour border and gradient

Recently I was asked to create a container that had a top border with a gradient applied to fade the border from blue to purple. But, the container also needed a background gradient that matched the border, and also faded out to white before the content started. Like this:

There are lots of ways to apply a gradient to a border, many illustrated in this excellent CSS Tricks article, and it is pretty easy to apply gradients to a background-image by using linear-gradient now as well.

The difficulty came when I realised I wanted to apply three different affects (border gradient, background gradient, and fade to white) to the same container without adding any additional markup.

In the end I achieved this by making use of pseudo elements and applying only two effects in total. Here is my solution:

First I started with my container markup and base styles for that.

<div class="container">
</div>
.container {
   display: block;
   width: 100vw;
   height: 100vh;
}

For the sake of this demo, I have set my container to the full width and height of the screen. Next we set both a :before and an :after pseudo element on the container.

.container {
   [...]

   &::before,
   &::after {
     content: "";
     position: absolute;
     left: 0;
     right: 0;
   }
}

Now that we have the foundations set all that is left to do is apply the effects.

.container {
   [...]

   &::before {
     background-image: linear-gradient( to right, #6a26b5, #007bc2 );
     height: 100px;
     top: 0;
   }

   &::after {
     background-image: linear-gradient( to top, #ffffff, rgba( 255, 255, 255, 0.7 ) );
     height: 90px;
     top: 10px;
   }
}

To break this down, the :before sets the first of two background gradients. This gradient is linear and flows from purple on the left to blue on the right. It is positioned at the top of the container, because we set position: absolute on both, and is 100px in height (you could easily change this to em or whichever unit you are using in your project).

The :after sets the second background gradient. This gradient is also linear but flows from a solid white at the bottom to a white with an opacity of 0.7, using the rgba() colour function, to the top. Which, when overlaid over the top of the colour gradient set on the :before, creates the fade out affect.

The final effect to achieve here is to create the border with the same gradient. To do that, all that is needed is to move the start position of the white gradient so that instead of starting at 0 it starts lower and displays some of the original solid gradient. In this example, the border needed to be 10px so I added:

top: 10px;
height: 90px;

The top value is then subtracted from the value of the height so that both :before and :after effects finish in the some position and preserve the smoothness of the fade out. If you only needed a the border to be 5px, then it would look like:

top: 5px;
height: 95px;

The full CSS Looks like:

.container {
  display: block;
  width: 100vw;
  height: 100vh;

  &::before,
  &::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
  }

  &::before {
    background-image: linear-gradient( to right, #6a26b5, #007bc2 );
    height: 100px;
    top: 0;
  }

  &::after {
    background-image: linear-gradient( to top, #ffffff, rgba( 255, 255, 255, 0.7 ) );
    height: 90px;
    top: 10px;
  }
}

Here it is in action:

Using linear-gradient meant that although three effects were required, only two needed to be created. This gave a really small performance win because we’ve skipped a third effect that would have needed to be painted, and it is well supported by modern browsers as well. Only a few of the more advanced features are not fully supported by Microsoft IE & Edge. Check out the browser compatibility section on MDN for more advanced details.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: