CSS Refreshers: Borders
basix

CSS Refreshers: Borders

Tutorial Details
  • Difficulty: Basix
  • Topic: CSS Borders

Sure, we’re all familiar with borders. Is there anything new that could possibly be introduced? Well, I bet there’s quite a few things in this article that you never knew about!

Not only can CSS3 be used to create rounded corners, but plain-ole’ CSS can also be wrestled into displaying custom shapes. That’s right; in the past, before these techniques were discovered, we might have resorted to using absolutely positioned background images to display circles or arrows. Thankfully – as we gleefully take one more step away from Photoshop – this is no longer the case.


The Basics

You’re likely familiar with the most basic use of borders.

border: 1px solid black;

The above code will apply a 1px border to an element. Plain and simple; but we can also modify the syntax a bit.

border-width: thick;
border-style: solid;
border-color: black;

In addition to passing a specific value to border-width, three keywords may alternatively be used: thin, medium, and thick.

image

While it might initially seem unnecessary to ever make use of the long-hand form, there are a handful of cases when it’s advantageous, such as when you need to update some aspect of a border when a designated event occurs.

Perhaps you need to change the color of a border when the user hovers over a specific element. Using the shorthand form would require that you repeat the pixel values.

.box {
    border: 1px solid red;   
}

.box:hover {
    border: 1px solid green;
}

A more elegant and DRY approach would be to specifically update the border-color property.

.box {
    border: 1px solid red;   
}

.box:hover {
    border-color: green;
}

Additionally, as you’ll find shortly, this long-hand technique is helpful when creating custom shapes with CSS.


Border-Radius

border-radius is the golden child of CSS3 – the first new property to gain widespread use in the community. What this translates to is that, excluding Internet Explorer 8 and below, all browsers can display rounded corners.

Previously, it was necessary to use vendor prefixes for both Webkit and Mozilla, in order for the styling to be correctly applied.

-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;

These days, however, we can slice off the vendor versions without worry, and simply stick with the official form: border-radius.

image

As one might expect, we can also specify custom values for each side of a box.

image
border-top-left-radius: 20px;
border-top-right-radius: 0;
border-bottom-right-radius: 30px;
border-bottom-left-radius: 0;

In the code above, setting border-top-right-radius and border-bottom-left-radius to zero would be superfluous, unless the element is inheriting values which need to be reset.

Much like margin or padding, these settings can be condensed into a single property, if necessary.

/* top left, top right, bottom right, bottom left */
border-radius: 20px 0 30px 0;

As an example (and as web designers do so often), the shape of a lemon can be reproduced with CSS and the border-radius property, like so:

.lemon {
   width: 200px; height: 200px; 

   background: #F5F240;
   border: 1px solid #F0D900;      
   border-radius: 10px 150px 30px 150px;
}
image

Beyond the Basics

Many designers happily stick with the knowledge outlined thus far in this chapter; however, there’s a few ways we can push it further!


Multiple Borders

There’s a variety of techniques that we can refer to, when tasked with applying multiple borders to an element.

Border-Style

While solid, dashed, and dotted are the most frequent values for the border-style property, there’s also a few others that we can make use of, including groove and ridge.

border: 20px groove #e3e3e3;

Or, with the long-hand form:

border-color: #e3e3e3;
border-width: 20px;
border-style: groove;   
image

While this is certainly helpful, a ridge or groove effect isn’t really multiple borders.

Outline

The most popular technique for creating two borders is to take advantage of the outline property.

.box {
   border: 5px solid #292929;
   outline: 5px solid #e3e3e3;
}
image

This method works wonderfully, however, it’s limited to two borders. Should you need to create a layered, gradient-esque, effect, a different approach will be necessary.

Pseudo Elements

When the outline technique doesn’t suffice, an alternate approach is to take advantage of the :before and :after pseudo elements, and apply any necessary additional borders to the generated content.

.box {
  width: 200px; height: 200px;
  background: #e3e3e3;
  position: relative;

  border: 10px solid green;  
}

/* Create two boxes with the same width of the container */
.box:after, .box:before {
  content: '';
  position: absolute;
  top: 0; left: 0; bottom: 0; right: 0;
}

.box:after {
  border: 5px solid red;
  outline: 5px solid yellow;
}

.box:before {
  border: 10px solid blue;
}
image

This perhaps isn’t the most elegant approach, but it certainly gets the job. One caveat is that it’s easy to confuse the order in which the border colors will be applied. A certain level of “guess and check” is often required to apply the correct sequence.

Box-Shadow

The cool kids way to create an infinite number of borders is to take advantage of the spread parameter in the box-shadow CSS3 property.

.box {
    border: 5px solid red;
     box-shadow: 
       0 0 0 5px green, 
       0 0 0 10px yellow,
       0 0 0 15px orange;
}
image

In this case, we’re being clever and are using box-shadow in a way that might not necessarily have been intended when the specification was originally written.

By setting the x, y, and blur components to 0, we can instead use the spread value to create solid borders at the desired locations. Because box-shadows can be stacked, through the use of a comma, the number of possible levels is infinite.

This technique gracefully degrades quite nicely. In older browsers, which do not recognize the box-shadow property, this will simply render the single red 5px border.

Remember: designs needn’t be identical in all browsers. Write your CSS for the most modern of browsers, and then provide suitable fallbacks, accordingly.


Modifying Angles

In addition to passing a single value to border-radius, we can alternatively provide two – separated by a / – to specify unique values for both the horizontal and vertical radii.

For example…

border-radius: 50px / 100px; /* horizontal radius, vertical radius */

…is equivalent to:

border-top-left-radius: 50px 100px;
border-top-right-radius: 50px 100px;
border-bottom-right-radius: 50px 100px;
border-bottom-left-radius: 50px 100px;

This technique is particularly helpful when you need to mimic a subtle, lengthy curve, rather than a generic rounded corner. For instance, the following code allows us to slightly break away from a square shape, resulting in more of a curled, paper-like effect.

.box {
    width: 200px; height: 200px;
    background: #666;

    border-top-left-radius: 15em 1em;
    border-bottom-right-radius: 15em 1em;

}
image

CSS Shapes

Perhaps the neatest use of borders is when they’re cleverly applied to elements, which have a zero width and height. Confusing, huh? Let’s see a demonstration.

For the next several examples, assume the following markup…

<div class="box"></div>

…and the following base styling:

.box {
   width: 200px;
   height: 200px;
   background: black;
}

The most frequently referenced example, when demonstrating how CSS shapes might be used in a project, is to create the obligatory arrow.

The key to understanding how an arrow might be formed with CSS is to set a unique border-color to each side, and then reduce both the width and height values for the container to 0.

Assuming a div with a class of arrow as the container:

.arrow {
  width: 0; height: 0;

  border-top: 100px solid red;
  border-right: 100px solid green;
  border-bottom: 100px solid blue;
  border-left: 100px solid yellow;  
}

As demonstrated at the beginning of this chapter, a cleaner syntax would be to not use the all-encompassing short-hand version:

.arrow {
  width: 0; height: 0;

  border: 100px solid;  
  border-top-color: red;
  border-right-color: green;
  border-bottom-color: blue;
  border-left-color: yellow;
}

We can even reduce this further, by grouping the color values.

.arrow {
  width: 0; height: 0;

  border: 100px solid;
  border-color: red green blue yellow;
}
image

Interesting, right? It makes perfect sense, though, when we take a step back. That’s the only possible way that the colors could align, assuming a width and height of zero for the container. Now, what if we set all of the border-colors to transparent, except for the blue side?

.arrow {
  width: 0; height: 0;

  border: 100px solid;
  border-bottom-color: blue;
}
image

Excellent! But it doesn’t seem too semantic to create an .arrow div, all for the purpose of adding an arrow to the page. Instead, pseudo elements can be used to apply the arrow after or before the associated element.

Creating a Speech Bubble

To create a 100% CSS speech bubble, we begin with the markup.

<div class="speech-bubble">Hi there!</div>

Next, some base styling should be applied.

.speech-bubble {
    position: relative;
    background-color: #292929;

    width: 200px;
    height: 150px;
    line-height: 150px; /* vertically center */

    color: white;
    text-align: center;
}
image

The arrow will be applied using the after psuedo-element.

.speech-bubble:after {
    content: '';    
}

The :before and :after psuedo elements can be used to insert generated content either before or after an element’s content.

At this point, it’s simply a matter of reproducing the arrow, and positioning it in the proper location. We start by absolutely positioning the content, resetting the width and height, and applying the border colors.

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 10px solid;
  border-color: red green blue yellow;
}
image

Because we know that we want the arrow to point downward, the image above demonstrates that all but the red (or top) border should either be omitted, or set to transparent.

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 10px solid;
  border-top-color: red;
}
image

When creating CSS shapes, because we can’t use the width property to specify how wide the arrow should be, the border-width property should be used instead. In this case, the arrow should be slightly larger; so the border-width can be increased to 15px. We’ll also position the arrow at the bottom and center of the container, by using the top and left properties, respectively.

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 15px solid;
  border-top-color: red;

  top: 100%;
  left: 50%;
}
image

Almost there; the final step is to update the color of the arrow to be the same as the container’s background. The positioning also needs to be modified to account for the width of the borders (15px). While we’re here, we’ll also apply a subtle border-radius to make the container appear to be more bubble-like.

.speech-bubble { 
   /* … other styles */
   border-radius: 10px;
}

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 15px solid;
  border-top-color: #292929;

  top: 100%;
  left: 50%;
  margin-left: -15px; /* adjust for border width */
}
image

Not bad, ay? Abstract this code away to a few reusable classes, and you’re good to go for all future projects.

/* 
   Speech Bubbles
   Usage: Apply a class of .speech-bubble and .speech-bubble-DIRECTION
   <div class="speech-bubble speech-bubble-top">Hi there</div>
*/

.speech-bubble {
  position: relative;
  background-color: #292929;

  width: 200px;
  height: 150px;
  line-height: 150px; /* vertically center */

  color: white;
  text-align: center;
  border-radius: 10px;

  font-family: sans-serif;
}

.speech-bubble:after {
  content: '';
  position: absolute;

  width: 0;
  height: 0;

  border: 15px solid;
}
/* Position the Arrow */

.speech-bubble-top:after {
  border-bottom-color: #292929;

  left: 50%;
  bottom: 100%;
  margin-left: -15px;   
}
.speech-bubble-right:after {
  border-left-color: #292929;

  left: 100%;
  top: 50%;
  margin-top: -15px;    
}

.speech-bubble-bottom:after {
  border-top-color: #292929;

  top: 100%;
  left: 50%;
  margin-left: -15px;   
}

.speech-bubble-left:after {
  border-right-color: #292929;

  top: 50%;
  right: 100%;
  margin-top: -15px;    
}
image

Bonus: Better Vertical Centering

One downside to using line-height to vertically center text is that you’re limited to a single line. Should the text require two or more lines, each line height will be far too large. A clever solution is to set a display of table to the speech bubble, and a display of table-cell to the paragraph that wraps the text. This then allows us to align the text to the middle, accordingly.

<div class="speech-bubble speech-bubble-top">
    <p>Text goes here.</p>
</div>

Next, the modified CSS.

.speech-bubble {
 /* other styles */

  display: table;
}

.speech-bubble p {
  display: table-cell;
  vertical-align: middle;
}   
image

If references to display: table bring back terrible memories of old-fashioned, table-based layouts, don’t worry. These properties merely refer to the style in which an element should display.

We’re not limited to triangles; CSS is capable of producing all sorts of shapes – even hearts and biohazard signs!

image
.biohazard {
  width: 0; height: 0;

  border: 60px solid;
  border-radius: 50%;

  border-top-color: black;
  border-bottom-color: black;
  border-left-color: yellow;
  border-right-color: yellow;
}

Summary

Though it’s true that the simple border: 1px solid black syntax goes a long way, if we’re clever, we can create a variety of helpful effects, icons, and shapes. Who would have thought that borders could be so powerful? The key is to remember that the styling for common shapes or speech bubbles should only be created once, and then abstracted away to utility classes for future usage.

Tags: basixcss3
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • chris

    nice, i didnt know you could apply a horizontal and a vertical radius

  • Mahfuz

    Awesome Tutorial !! Thanks Jeffrey.

  • https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash3/548891_3307565604583_1131333544_3162607_1634655969_n.jpg Rakesh

    This is just awesome.. Jeffrey’s tuts always rock!

  • Albert Yu

    Nice, very useful and delightful tutorial. I wish THIS could be a one of a serials, and next one…how about table related styles? I’m expecting this!

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      Sure!

      • alireza

        hello jeffrey.

  • artuross

    Wow, great idea with doing Lamon in CSS :P

  • http://mattrheault.com Matt

    Thanks Jeff! Sometimes we forget just how important it is to take a look back over the basics. Keep up the good work my man, always a fan!

  • http://net.tutsplus.com/tutorials/html-css-techniques/css-refreshers-borders/ Nuril

    Nice one, like i have to try the last part, make a hearth shape with css3 :D
    thanks :D

  • http://www.michielbruggenwirth.nl Michiel Bruggenwirth

    Wow great. I didn’t know that this all was possible with borders. This will come in handy sometime

  • http://www.webbanditten.dk Webbanditten

    This is truly amazing

  • Ganeswar

    awesome…

  • http://webarto.com/ webarto

    Great tutorial, nicely explained :)

  • http://wouterj.nl/ Wouter J

    I recently figured out that Safari doesn’t support percentage values: http://jsfiddle.net/peFnV/embedded/result,css,html/

  • http://jawbfl.blogspot.com Jaw,B

    Fantastic tutorial , that’s like the summary of all css border tricks !!

  • Joey Parshley

    Nice tut thanks. Do you know if there are any of these techniques to create a trapezoidal or complex rectangular shape with some angular borders?

  • http://wouterj.nl Wouter J

    You can do some really funny and nice things with CSS borders.

    Yesterday I was thinking how to make a transparent border along an element. When I was trying to get it, I got something really special and nice: http://jsfiddle.net/bMsDP/1/embedded/result,css,html/

  • Akshay

    Glad to see you back with tuts Jeffrey. I hope this premium course stuff doesn’t keep Nettuts away from cutting edge web technologies.

    Would love to see some Math and WebGL tuts. Can I see it anytime soon?

    P.S – Thanks for the neat border tricks!

  • http://toptopgames.com Cyrus

    I didn’t know about the CSS3 tricks with borders. I guess, I am getting quite old. This was a a great article.

  • રંગીલો ગુજરાતી

    મોટા મોજ પડી ગઈ

  • Joe

    Thanks Jeffrey! Great stuff as usual. Very helpful.

  • Prabhakar

    For me it is easier to do this on Photoshop than CSS, and then just add a background statement in css. Nice tutorial anyway.

    • http://www.jeffrey-way.com Jeffrey Way
      Author

      But you’d only do this one. After that, for every future project, you simply add a class.

      • Drasko

        Totally agreed with you, it’s far more better to do it in css than to make http request for some image.

      • Nathan

        Also, if/when you change your CSS color, you’ll have to update all your images, now, using LESS or SASS you can change the color in one spot

  • Neto

    Nice!

  • http://coder-design.com/ coder-design

    Great tutorial. Thanks for sharing.

  • Fionn

    I agree with Prabhakar, It’s a lot easier, And backwards compatible to just do it in Photoshop or GIMP etc. , I can’t really see this getting wide spread usage.

  • dj

    @jeffery… Glad to see you visit the non-premium side again… you always have a way of turning pablum into steak. Well thought out and delivered tut.

  • Omid

    Thanks Jeffrey, it was a surprise for me and can`t ignore it!

  • http://techbrij.com Brij

    Nice tut !!! All in one related to Borders CSS.

  • Hamid

    Damit!, that’s why we LIKE Jeffery Way, aren’t you?

    thQ once again J-W

  • Asheesh

    Jeffrey,
    you might be web developer professionally, but at heart you are a passionate teacher for sure. Having seen your video tuts and read online tutorials, I really like the way you present complex concepts in simple words. You have mastered this art. Kudos! and God Bless :)

  • http://www.rafiqislam.wordpress.com rafiq_islam

    best css borders post. a lot of thanks…

  • Johan

    Very cool tutorial Jeffrey !
    Thanks for sharing your knowledge, it’s always impressing !

  • http://cansurmeli.com C@N

    Nicely done. :D

  • Rhonda

    Thanks Jeff, I never would have gotten how to center the text in the speech bubbles.

    When I play with the speech bubble in JsFiddle, the hidden border sides are defaulting to white, not transparent. Put a body background color on and you’ll see this.

    To get it working, I changed this line.:

    border: 15px solid;

    to:

    border: 15px solid transparent;

  • http://www.coroflot.com/joshhumble Josh Humble

    VERY cool, in-depth look into the CSS border property, Jeffrey – love it, and thanks! In creating arrows, how about using the “transparent” color keyword to preserve the background, declaring it for all border sides in the shorthand, and then overriding only one side with the color of choice to create the arrow?

    div {
    position:relative;
    margin:20px 0 0 20px;
    width:0;
    height:0;
    border:50px solid transparent;
    border-bottom-color:#000
    }​

    ex: http://jsfiddle.net/joshhumble/UChaz/16/

  • http://www.iuditg.com Udit Goenka

    Another powerful post by Jeffery. Nettuts is incomplete without you. :D

    Now regarding the post, I knew few of these technique but the double border was quite interesting. I might use that in one of my future projects maybe.

    Thanks Jeffery, would be waiting for more such tips, tricks and hacks .

  • http://reconnect-inc.com David D’hont

    Amazing article Jeffrey, like always…

  • http://www.villagranstudio.com Leandro

    Thanks man, This is the first time that I saw the use of the outline property I always wonder what would you need it for if you have the border property, now I know. I guess the only way to really find out how a property works is to experiment huh!

    Thanks Again!

  • Chans

    this tutorial was amazing, Thanks Jeff !! you are the best

  • http://www.pixeldeveloped.co.za Meelan

    Great tutorial, I especially liked the speech bubble technique. Always wondered hows that done.

  • Potado

    Nice tutorial for reference!

  • Abhijit

    Wow, great! I have been doing CSS for quite some time, but never thought about creating shapes using it. This is really very interesting.

  • http://www.harshadkhandare.com Harshad Khandare

    Thanks Jeffrey Way It’s really interesting and helpful to me.

  • http://twitter.com/drale2k Drazen Mokić

    This is a good one, thanks. I find myself spending very little time on nettuts since you stopped doing regularly screencasts yourself.

  • http://www.jagadishwor.com Jagadish

    Great!!! Catch them soon… Thanks lol

  • Peter

    In what world does biohazard look like that?
    Anyway, wonderful post! I especially liked the lemon!

  • Vijay

    U r awesome man…!!!

    Loved it :)

  • http://melvinsoldia.info Melvin

    Very clever Jeff. Amazing…

  • Tam

    Very helpful… thanks for sharing us this great tus

  • Drasko

    Great tut, most of it is familiar, but trick with speech bubble is speechless :)

  • Sergey

    Nice post! It is actually very interesting subject, I find myself experimenting with borders and gradients a lot. Here is one of my experiments related to the post: http://sergeylukin.com/css-pyramid-infographic/

  • Scott

    This is an excellent tutorial, but it doesn’t offer any alternatives for doing rounded corners in IE8 or below. What are your suggestions for doing that? I tried CSS3 PIE, but couldn’t get it to work.

    • BakaBak85

      @Scott
      Check the path (absolute or relative) in to the “PIE.htc” file. It’s almost always that. CSS PIE is great. You just need to be careful with ajax injected content that floats, it gets messy at certain point.