Grow your CSS skills. Land your dream job.

#95: A Tale of Border Gradients

Turns out there is a simple way to accomplish gradients on borders. That took me longer than it should have to arrive at though, this screencast covers all the ways I tried and looked at along the way.

View Demo   Download Files

Links from Video:

Note: In the video, I ended with the sentiment that the border-image plus linear-gradient was the best way. I still think that, but I failed to mention it's only supported in WebKit, despite Firefox and Opera supporting both of these properties (together they fail). The new demo page lists all techniques so you can decide which one might work best for you yourself.

Comments

  1. That was fantastic! i honestly never thought we would be able to do that (with CSS alone) and so easily, keep in mind im still learning the advanced stuff, but i did enjoy how you went over all the ways you can approach this, and in the end, showing the PROPER way of doing it. thank you so much chris! saved me a lot of loading time :P (website) take care , cheers.

  2. Chris-

    just a quick question about trying to add IE support into the mix. I’m assuming that the best method would just be a background-image and conditional stylesheet for IE, yes? Depending on what kind of gradient you are trying to accomplish, I guess that you could just add the background image fallback for IE directly into the normal stylesheet since IE would ignore the border-image declarations.

    Great screencast as always :)

    ~M

  3. Alaa
    Permalink to comment#

    Hey Chris

    am trying to learn here ..so sorry if i am mistaken .. but isnt it possible to get this using just divs ?

    somthing like

    #mid{
    margin:0 auto;
    width:300px;
    padding:10px;
    border-top:5px solid red;
    position:relative;
    }
    #left{
    background-color: red;
    left: 680px;
    position: absolute;
    top: 8px;
    width: 5px;
    }
    #right{
    background-color: red;
    left: 995px;
    position: absolute;
    top: 8px;
    width: 5px;
    }

    and replace red color with red to transsparent in the left and right divs .

    thanks for your effort .

    • @alaa

      yes thats always technically possible, but its going to be consider hackish, since its using extra markup to accomplish styling.

      Generally, combining markup with style is considered bad practice, even though there are still cases where we must resort to those tactics. Its not good practice to have a bunch of empty divs all over the place as it makes your markup/content messier than it needs to be.

      ~M

    • Alaa
      Permalink to comment#

      but still..its the only way that would support all browsers ..
      and the HTML code remains clean

      you have only to add the following HTML code

      Your Text Goes Here

       
       

    • Alaa
      Permalink to comment#

      your text goes here

       
       

  4. Permalink to comment#

    Is is possible to have a gradient along the top boarder? Say starting dark at the top right and getting lighter at the top left??

  5. Permalink to comment#

    On the first idea how come you didn’t just apply a background to the parapgraph instead of having to use after to do it?

  6. vale
    Permalink to comment#

    Thank you, thank you, a thousand times thank you! I was trying to figure this out so to only use CSS3 and get rid of a background image.

  7. vale
    Permalink to comment#

    I don’t know if this is an issue or if it is the spec for the border-image but this (awesome) trick will override any border radius (which will still render on the box-shadow LOL!).

    • :( I’m facing that too, any fixes on that ? And further, if you alter the way they have written the gradient, it does not work.

  8. Permalink to comment#

    Nice video, but gradient borders look kinda weird.

    • Gradient Borders can give you the ability to render perfectly beveled elements with a bit of depth. eg. sharp-edged lightly concave buttons

  9. Permalink to comment#

    I think the borders look really nice. Great job! :)

  10. Awesome tutorial, awesome site, awesome video/speech. BTW, did I say awesome? Tks alot.

  11. Matt Brown

    Hey… is anyone else having trouble with the video cutting Chris off in mid sentence? I feel like there’s supposed to be more to this video than I’m seeing, mostly because it cuts him off in mid sentence. (I’ve been noticing this a lot actually since the switch from the old video player to Youtube)

    I don’t know if it’s something with my browser or what, but I just wanted to call it to someone’s attention if the problem isn’t just localized to me.

  12. Johnny

    This solution doesn’t work if you throw a border radius at it. Any thoughts on how to get this to work with rounded corners?

    • Doug

      Yeah, look at my other comment on this page, and use border-radius on the container div…

    • Doug

      CSS:
      div#c{
      margin: 20px;
      padding: 5px;
      -webkit-border-radius: 5px;
      background-color: #1a82f7;
      background-image: url(images/fallback-gradient.png);
      background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#000), to(#f00));
      background-image: -webkit-linear-gradient(top, #000, #f00);
      background-image: -moz-linear-gradient(top, #000, #f00);
      background-image: -ms-linear-gradient(top, #000, #f00);
      background-image: -o-linear-gradient(top, #000, #f00);
      }
      ​p{
      padding: 20px;
      background-color: #fff
      }​

      HTML:
      ​div id=”c”
      pText/p
      /div​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

  13. Doug

    Why not just use a container div with the gradient that you would want your border to have, as its background, set the div’s padding to be the desired thickness of your “border” and use a child tag with a solid background… ?

    • Permalink to comment#

      Seems like the best cross-browser solution (today) to me… Hadn’t even crossed my mind. Thanks Doug!

  14. Trevor
    Permalink to comment#

    You know Chris, your pseudo code approach you initially showed everyone should take any decent developer the same amount of time to accomplish a gradient border using Nicolas’ version.

    Modern browsers will render both appropriately and with speeds so minute, I doubt a humming bird could tell the difference. One guy running with a ring on and another with a bracelet arrive at their destination at the same time. Should we dissect which ‘style’ is more appropriate? Your approach I believe was solid also.

  15. syd
    Permalink to comment#

    What about gradient borders to an element that has radius. is there any technique for rounded corners objects?

    Thank you

    • Trevor
      Permalink to comment#

      Don’t forget Sid that while you can render certain visual features, you have to consider their level of complexity and time. I don’t think CSS is at the point where adding a gradient border is the most semantic or efficient way. Rather, using imagery which accomplishes the task with less code and effort and no speed drawbacks.

      Remember these CSS tricks though amazing are purely experimental and prove that you can pull off tricks but doesn’t mean they are the best method of achieving such results.

  16. Trevor
    Permalink to comment#

    ….at this point in life of CSS

  17. Christopher King
    Permalink to comment#

    A little late to the comment party, but now by overlaying multiple backgrounds this can be accomplished fairly easily with no pseudo elements at all.

    Here is a simple example ($backgroundColor should obviously be the color you want the background to me mostly):

    background: linear-gradient(to bottom, $backgroundColor, $backgroundColor 98%, transparent 99%, transparent),
    linear-gradient(to right, rgba($gradientColor, 0), rgba($gradientColor, 1), rgba($gradientColor, 0)) ;

  18. Brad S.
    Permalink to comment#

    Anyone know how you might do a gradient fill with a gradient border using Nicolas Gallagher’s Multiple (Sized) Gradient Backgrounds example? I would like to do this using just one element in my markup, preferably a simple:

    <button>Click Here</button
    

    But for the life of me I cannot figure it out as his example is transparent in the middle, and has no fill. Is it possible?

    • Brad S.
      Permalink to comment#

      Obviously I missed the closing tag on my example, but it doesn’t seem I can edit my post.

  19. GCyrillus

    For the fun,
    gradient can be animated too to draw borders : http://codepen.io/gc-nomade/pen/IGliC

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".