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
  • http://www.simonswiss.com Simon

    Wonderful tutorial Jeffrey!

    I love the speech bubble, pretty simple but would have never thought of it this way!

  • http://www.devparadigm.com Noman Zia

    Very Nice and full of Knowledge article.

  • http://georgedina.ro George Dina

    The speech bubble is fantastic.

  • control_C

    Will these all work in older browsers?

  • BakaBak85

    @Jeffrey Way
    Super awesome tutorial.

    I am wondering about cross browser and version support. Perhaps you could add a few words about best practice alternative solution for older versions of IE or other browser that do not support this. Like … “alternatively, you could use JavaScript to detect browser and version and then apply class for that particular browser or version.”

    Well, what do I now, that just popped in my head but you know what I mean.

  • LP

    excelent post jeffrey …

  • http://www.frasesderock.com pancho

    Thanks for the information, has been very useful to me

  • http://www.codehunterbd.wordpress.com Khairul

    Thanks a lot.This tutorial is really hot and very helpful for me.Thanks Jeff.

  • http://www.narendrakeshkar.com/blog Narendra

    Excellent posts explaining use of borders in depth. Loved this post. Thanks for the post.

  • http://babeltekno.com hadinug

    amazing :D

  • Francisc

    Good article but incomplete: no mention of browser compatibility.

  • http://www.sahilmepani.com Sahil

    Very nice tutorial..

  • http://www.clauddiu.com Claudiu

    Great tutorial, thank you!

  • http://www.lotusmarketing.ca Marketing Sherbrooke

    Great work, you have provided a lot of pictures which is always good. I even learnt some stuff and im advanced. I should use radius:50% instead of half of the height for circles .. so it scales up ;)

  • http://www.facebook.com/nafsal Nafsal

    Very nice……I like it………..

  • http://www.webdeveloperblog.co.uk Jamie Murphy

    Great tutorial, covers every aspect of borders I could possibly think of. I had never thought of using the feature to make shapes such as the lemon! Just shows what is possible with an open mind and a little bit of creativity!

  • saravanan

    Nice Article & speech bubble is wonderful.

  • http://www.esylhet.com sylhet

    no doubt great tutorial.But if you explain the psedo css element then it’s much better for novice learner.

  • http://www.menacedesign.pl Artbeard

    A true borders bible!

  • http://markroe.me Mark Roe

    Great tutorial. Really is amazing what you can do with CSS3.

  • http://bretglassett.com Bret

    Thanks for sharing. I feel that allowing older browsers to degrade is the best approach with these new css3 techniques.

  • http://icreateui.com Simon

    Thanks for sharing.

    I made a small tool to build arrows for tooltips etc and speech bubbles using borders: http://cssarrowplease.com/

  • alex

    Thanks for sharing !

  • Mazharul Islam

    Really Awesome !

  • http://hyperlexic.com hyperlexic

    Great tutorial, but I think the topic of supporting IE user experience is too often brought up as an afterthought. It really depends on your sites’ goals and making sure you’re not leaving good, productive traffic in the lurch. Take ‘Adsense revenue’ as a site goal example. I don’t know how my numbers compare to others, but I just quickly glanced at the analytics of a couple of my larger-traffic sites that generate all their revenue from Adsense. (This is NOT some formal analysis, just a small sample to check on browser share and maybe get some comments from others to compare notes).

    While around 80% of my TRAFFIC to these sites now comes from NON-IE browsers and growing (chrome is growing like crazy, as is smartphone traffic), over 50% of my REVENUE is still from IE users. Even many of my smaller sites are showing at least 20% revenue-share from IE users – usually higher. Backtesting these numbers 3 years, IE revenue is remaining consistent while traffic share is dropping to better browsers rapidly. (If my stats are representative at all, does this bode well for Adsense?)

    Almost all traffic is organic search traffic, and almost all of that is from Google.

    Of the overall IE traffic, over half of my users are using 7.0 with version 8 and 9 fighting it out for second place.

    Perhaps the old adage of ‘chrome, safari and firefox users being more web-savvy and less inclined to click an ad’ is in play here, but these are sites with widely diverse content and target-user profiles, so the correlation between IE users and Adsense productivity isn’t totally clear to me. I’ve split tested layouts, site structure, content etc – and the numbers continue to remain consistent over a fairly long period of time. As far as my Adsense-based network of sites, I make sure my IE users are getting a comparable user experience to non IE users (at least while Adsense remains a nice source of revenue).

    Any other Adsense publishers seeing similar trends?

  • http://alicialoh.com Alicia

    What a useful tutorial! I never would have guessed borders could be used this way. I especially love the speech bubble, and my just use it for my new website!

  • jj

    how do you control the size of the actual borderbox

  • sharan

    Brilliant work !! simple but Productive!!! Thanks for sharing!!! i appreciate your work…

  • Ramesh

    hi all are awesome!!! work…..thank you for sharing…..

    I have a doubt…
    can we fill color to half portion of one box (or fill color percentage wise ) using css or any other?
    like this…
    ________
    | |
    | fill color |
    | Red |
    | |
    | fill color |
    | Green |
    |________|

    Thank you….
    Ram..:)

    • http://villekoo.com Ville

      Try using css gradients ;)

  • Aamir

    @Ramesh
    yes you can use it.

  • http://blog.ceddychen.com koukan

    Very creative! Nice :)

  • http://www.graceful-illusion.net Brianna Deleasa

    I learned a lot of interesting border techniques after reading this article! After the last 7+ years of coding websites, I’m surprised to learn that there is an outline property I never knew about. You learn something new every day! Great article, I really enjoyed it.

  • Sara

    Finally!! I’ve seen most of these tricks used in many articles I’ve read and I never really understood as to WHY they’re being used, like the table-cell display, and using box-shadows to create borders. Thank you so much Jeffrey for another excellent article!

  • Joshua

    Very nice tutorial thank you :D

  • http://www.affiliation-france.com Affiliation

    nice !!! finally worked for me ;) way to go !

  • Skyler

    When I try to make the comment bubble and I “make all the other colors transparent” to just show the red border inside the bubble it ends up having a white background. . . . : ( What can I do to fix that?

    • skyler

      just found a quick fix for my problem, if you change the ‘color’ attribute the pseudos element as in ( element:after{ color: purple} ) it also changes the background-color of the pseudos element to that color. so in this case the background-color of the pseudos element would be purple. ^^
      hope this helps anyone who comes across the same issue.

  • bigmeanie8655

    Hi all, dope tutorial Isomething else that i can’t figure out are the containers for the
    various sections. i thought that i could do these last and simply draw
    them inn as containers by using the “Draw AP Div” tool, color them in
    and position then at the bottom of the other div by using the “z-index”
    (CSS rule definitions/positioning) but once again i was wrong. is there a
    way i could do this?

  • Borne

    Great totorial. I don’t mean to get off topic but I haven’t had success getting help with this anywhere else. I’m in the process of designing a website for a client and achieved success as far as the html and css is concerned. I chose to leave the containers for the
    various sections for last as i thought that i could do these by simply drawing
    them inn using the “Draw AP Div” tool, color them in
    and position then at the bottom of the already established content (from other div I’ve done already) by using the “z-index”
    (CSS rule definitions/positioning) but once again i was wrong. When I try this out nothing happens, what am I doing wrong and is there a way I could do this? I can use the “AP div” tool to draw borders that were demonstrated in this tut but I can’t get those borders to fall beneath the intended written content by css positioning?

  • Ranker

    Nice tut. Thanks.
    You forgot about “transparent” argument for this blue arrow border – last code in “CSS Shapes”.

    • mahsa

      thanks ranker

  • Jake

    Best article on that topic in the web ever. Period. Exclamation mark.

  • Swathi

    Really Awesome, mind blowing……

  • kaury1405

    Excelent!!!!

  • Jiten Thapa

    Wow amazing tutorial. I love playing with css

  • triniitgirl

    Great tutorial….I have finally understood the concept with the traingles!! I’m guessing it is only compatable with the latest browsers and not IE

  • KHOKON

    Great (y)

  • http://www.facebook.com/hasanuzzaman.shozib Hasanuzzaman Shozib

    Very nice ……………….

  • http://twitter.com/Frulantis Korelidis Ypsilantis

    +++

  • Алек

    Спасибо за ценный совет.

  • Kumar Amit Ranjan

    Wonderful article.