1. Code
  2. HTML & CSS

CSS Refreshers: Borders

Scroll to top
Read Time: 11 min

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.

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

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


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.

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

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


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.

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


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


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.

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:


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.


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.

Or, with the long-hand form:


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


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


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.


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.


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.


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…

…is equivalent to:

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.


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…

…and the following base styling:

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:

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

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


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?


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.

Next, some base styling should be applied.


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

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.


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.


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.


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.


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


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.

Next, the modified CSS.


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!



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.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.