A bite of bits

Have a seat and enjoy the madewithlove team's development stories.

How to make a graphic-rich poll with CSS

I think that every front-end developer, at one point or another, has come across a project with some really fancy-designed polls. With nice rounded bars, with a great texture inside.

I recently came across one of those said polls, and instead of relying on anything I’d built in the past, I decided to try build something fresh, yet compatible with even the oldest browsers we still support. Yes, even the one with the big blue E whose name I will not pronounce here.

The design I was given to build had this type of poll:


If this was 2003, I’d probably slap a sliding doors around the number, align the text to the right, and call it a day. It would be relatively accurate in terms of size, and pretty bulletproof. Why isn’t this technique ideal? Let’s suppose we had built it with the following markup:

<div class="poll-result">
   <div class="result">
      <div class="result-inner">25%</div>
   </div>
</div>

So, according to this markup, the poll-result would be our empty background, and the result and result-inner would compose the sliding doors. One of the problems with using this technique, is that at low percentage values, you would get that wonderful overflowing of the percentage.

Another problem is that your result div would also overflow the poll-result because it would have it’s own padding. If you have 100% and a div with a certain horizontal padding, the width of that element, as we all know, would be 100% + horizontal padding.

The overflow of the result div has two viable solutions I can quickly think-of. If you’d like to use the most modern code available, this is the perfect situation to use box-sizing property, and set it’s value to border-box.

For those who don’t know, this changes the way the box model work, and makes it much easier to use, instead of the real “width” of an element being it’s width + padding and border width, it’s real width becomes whatever value you give it. With box-sizing: border-box 100% width + horizontal padding = 100% width.

Since this is a CSS3, we have to, unfortunately, add each browser’s corresponding prefix ( -webkit-, -moz-, etc ).

The past-proof solution is slightly less elegant, though incredibly simple. Outside of the result div, we make another one, and we give it an inline style with the width property in percentage. Yes, it’s that simple.

This method doesn’t make really low percentage values infallible, that problem will vary according to to the width of the poll’s container (the wider it is, the less noticeable the problem becomes).

As for the percentage number overflow problem, it also still occurs, however, since we are dealing with paddings, when a div with a horizontal padding becomes short enough, instead of overflowing it’s content immediately, it starts “eating away” the padding, to try to make the content fit as much as possible. The wider the padding is on your result-inner the less overflow the text will have, however, it’s a double edge’d sword, as the lower percentage values won’t differ from each other in terms of width.

Here is the final code extracted straight from the project:

.poll-percentage {

    position: relative;

    height: 20px;

    background: url(images/background/poll-back.png) 0 0 no-repeat;

}

    .poll-percentage .result {

        height: 20px;
        padding-left: 9px;

        background: url(images/background/poll-result-l.png) 0 0 no-repeat;

    }

        .poll-percentage .result-bg {

            position: relative;

            height: 20px;
            line-height: 20px;

            padding-right: 12px;

            text-align: right;

            color: #FFF;

            text-shadow: 0 1px rgba(0, 0, 0, 0.2);

            background: url(images/background/poll-result-r.png) top right no-repeat;

        }

I wish there was a better solution than this, but after a while coding, this is the best solution I could come up with. I hope it serves you well in the future.

Filed under HTML/CSS. Tagged with .

Leave a Reply