Responsive CSS Shapes

Creating simple fixed-size CSS shapes like circles, triangles, and squares is very straightforward. New properties, like border-radius and transform allow creation of a whole array of CSS-only shapes that previously required images. Even though responsiveness adds a level of complexity, all basic shapes require only one div, making them more convenient than SVG vector shapes.

Responsive CSS shapes scale without losing their aspect ratio. They are traditionally achieved in the web using images or Javascript. However, there is a very simple way to create shapes compatible with all major browsers (yes, IE7 too) using CSS only. This article aims to serve as a reference for the creation of basic responsive CSS shapes. It's a review of my three articles on CSS circles/ovals, CSS triangles and CSS squares/rectangles.

What for?

Responsive CSS shapes are usually used for buttons, containers, icons and decoration. I can't think of every possible application. I've used responsive circles for buttons and responsive triangles for arrows in a color picker. However, because each shape introduces markup, these are not suited for applications where you don't know the exact number of shapes you need (unless you are doing something really strange). For backgrounds, using SVG or plain old images is the way to go.

Rectangles and Squares

Rectangles and squares are the most simple of CSS shapes. They are even more straightforward when they have fixed dimensions or at least fixed width. However, when creating something as simple as a responsive square or rectangle, a simple trick must be used. For responsiveness we want both the width and height of the rectangle to be a percentage of parent's width. The question here is how to set height relative to width using CSS only. The height property won't do it as it is relative to parent's height, not width. Padding is the answer because percentages in paddings are calculated against parent's width. With this in mind, creating a responsive square is as simple as:

.square {
    position: relative;
    width: 25%;
    padding-bottom: 25%;
    overflow: hidden;
    background: #4679BD;
}

... and we get:

For details on how to add text to the square, please visit the complete article on CSS squares.

These squares may be customized with CSS3 animations, transforms, shadows, fonts, borders and border-radius to achieve great looking buttons with centered text. Besides, they work even in IE7.

Circles and Ovals

CSS circles are possible thanks to the CSS3 border-radius property. A responsive square with border-radius = 50% looks like a circle. Creating a responsive square is simple using the same idea and code explained above. The code for a responsive circle is extremely similar:

.circle {
    width: 25%;
    height:0;
    padding-bottom: 25%;
    -moz-border-radius: 50%;
    -webkit-border-radius: 50%;
    border-radius: 50%;
    background: #4679BD;
}

Resize the container to see how the circle keeps being a circle:

Adding text to the responsive circle is no simple task. Please see the article on CSS circles for the code. Responsive circles are specially suitable as round buttons. Adding an SVG image creates completely responsive good-looking CSS-only buttons as explained in CSS Round Buttons.
.
Creating ovals is as simple as changing the padding-bottom percentage. The border-radius property needs no change because CSS is intelligent enough to calculate horizontal border-radius against width and vertical border-radius against height. Thus, simply changing the padding-bottom percentage results in an oval.

Triangles

Triangles are the most tricky CSS shape. However, completely responsive triangles with any proportions can be created using a single div and two tricks. The first trick is the one used to create fixed-size triangles, an extremely crazy trick. Take a look at the following CSS:

div.empty-element {
    width: 0;
    height: 0;
    border: 100px solid #1F80AF;
    border-left-color: #0099CC;
    border-right-color: #0099CC;
}

... and the resulting div:

Triangles! That's it, we have four triangles right there. Lets leave just the one at the bottom. It's just a matter of removing the top border and making the left and right borders transparent:

div.fixed-size-triangle {
    width: 0;
    height: 0;
    border: 100px solid #1F80AF;
    border-top: none;
    border-left-color: transparent;
    border-right-color: transparent;
}

... and we get:

Now comes the second trick. What happens if you cover/uncover the triangle from the bottom up? Like this:

Responsive CSS triangle technique

What's left uncovered is a smaller triangle, but with the same proportions of the original one. That's responsive triangle! Now we just need a way to cover the triangle using CSS. The easiest way is to place the triangle inside a responsive rectangle. Then we just use overflow:hidden to cut off the bottom part:

Responsive CSS triangle technique

Thanks to pseudo-elements we can do it all with a single div if we use a before or after pseudo-element for the triangle. The triangle has to be horizontally centered inside the rectangle. This is achieved using plain old margins and paddings. The fixed-width triangle can be made as humongous as you want. The size of the box is solely determined by the rectangle. The code for our final responsive triangle is:

.triangle-up {
    margin: 0 auto;
    width: 25%;
    height: 0;    
    padding-left:25%;
    padding-bottom: 25%;
    overflow: hidden;
}
.triangle-up:after {
    content: "";
    display: block;
    width: 0;
    height: 0;
    margin-left:-500px;
    border-left: 500px solid transparent;
    border-right: 500px solid transparent;
    border-bottom: 500px solid #4679BD;
}

Resize the container to see it work:

That's just the up-pointing triangle. For the down, left, right pointing and tilted triangles it's just a matter of changing a few rules. Take a look at the complete article on CSS triangles for details.

CSS triangles are not flawless. The main problem I've found with this trick is that there's no simple way of adding a border nor a shadow, because, as shown above, they are borders themselves. Until someone finds a way, one is limited to solid color triangles.

The good part is they are compatible with almost every browser. overflow: hidden style is supported by virtually every browser so there's no danger of the triangle overflowing and wrecking your layout. IE7 and below don't support pseudo-elements. To add support use the two-div version of the responsive triangles, which I tested working in IE7.

There are many more fixed-size CSS shapes out there. However, their use is rather specific and making a responsive version has little to no point. Some of them, like diamonds, can be built simply by using two responsive triangles. For anything more complex, using SVG is probably a better idea. Please share your findings and any issues. I'll be glad to help.

3 comments

  1. Nice examples, thanks. But I can't add some text with vertical align into circle. I know some tricks how to do it, one of them is to use css3 flexbox:
    .circle{
    width: 100px;
    height: 100px;
    background: #4679BD;
    display: flex;
    align-items: center;
    justify-content: center;
    }
    It works fine with fixed width and height, but it's not adaptive anymore.
    I also tried to add line-height: 2em into your example and it's not center aligned on some screens.
    Any suggestions?

  2. Is there a way to put the triangle inside a circle with css ?
    I want to create a left arrow and right arrow for an image slide show ,
    but the arrow is in the circle .
    Maybe put the greater > or less than < character inside the circle ?

Leave a Reply

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>