Responsive circles with CSS

We recently released a dashboard for the Hire Space venues’ CMS and the layout involves lots of circular badges with numbers in.

Analytics Screenshot

I’m no CSS whizz, but I did have fun styling this and it turns out that creating fully responsive circular badges with nothing but CSS is easy. Here are the classes to create the circles:

.circle {
margin-left: auto;
margin-right: auto;
border-radius: 50%;
width: 100%;
position: relative;
}

.circle-border {
border: 1px solid black;
}

.circle-solid{
background-color: whitesmoke;
}

.circle:before {
content: "";
display: block;
padding-top: 100%;
}

.circle-inner {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
text-align: center;
}

And a class for the text inside the circle:

.score-text {
margin: auto;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
height: 1em;
line-height: 1em;
font-size: 1em;
}

To ensure that the text is vertically aligned in the centre of the circle, the line-height, font-size and height of the containing div need to be the same.

Markup for a circle with a border and some text inside:

<div class="circle circle-border">
     <div class="circle-inner">
         <div class="score-text">
            SOME TEXT
          </div>
     </div>
</div>

Wrapping the circle div in a responsively sized div (like one of the Bootstrap col-* classes) gives a responsively sized circle. The final touch is for the inner text to be responsive as well. Happily, this too is possible with CSS, using the ‘viewport width (vw)’ unit of measurement. 1vw is 1 percent of the viewport width.

.score-text {
height: 3vw;
line-height: 3vw;
font-size: 3vw;
}

The result: responsively sized, vertically centred text for your badge.

Of course browser support for the viewport width units doesn’t extend back as far as you might need, so make sure to include a fallback. Also, a quirk in Chrome is that the text won’t be re-painted when the browser is re-sized, so the text is only responsive to the initial browser size. To get around this, I did break from the pure CSS approach and use a little JQuery fix:

var causeRepaintsOn = $('.score-text');

$(window).resize(function () {
    causeRepaintsOn.css("z-index", 1);
});

And that’s it!

NB: of course, in IE < 9 these will be responsive squares – not quite as pretty!

Advertisements

8 thoughts on “Responsive circles with CSS

  1. This is awesome! Saved my tail today with this solution. I was just needing to center images though – found that I didn’t need any attributes on the .circle-inner div, just needed a div in place for this to work for me. Thank you Alex.

  2. Not sure about back in 2014 but certainly Chrome has no problems with ‘repainting’ vw fonts now a days. Also you say that the line-height for the div containing the text needs to be the same as the line-height of the text itself. That’s not quite what is going on here, it’s more to do with the top, right, bottom left positioning than the line-height, which has been left undeclared in your code other than in the ‘score-text’ class.

    Another way of doing the text would have been to do something like .circle-inner>p{}.

    Good article wot

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s