What happens when you add a shiny new browser to a stack of already-disagreeing citizens? You’ll inevitably find some bugs. This is the story of how we found a rendering quirk and how the Atlassian frontend team found and refined the fix.
The Atlassian User Interface (AUI) library has just finished an IE10 sprint to get our library prepped and ready for the newest member of the browser family. While IE10 seems generally quite good, we found a couple of problems due to IE10 dropping conditional comments; plus some undesirable behaviours.
The most curious of these was IE10 rendering white dots in the corner of AUI buttons:
Jonathan Poh, a frontend developer for Stash, initially suggested this fix:
…as it solves a similar-looking problem on elements with rounded corners.
However this fix didn’t work on the buttons, as it wasn’t a background image extending past the borders of the element – in fact it seemed to be the opposite. For some reason IE10 wasn’t rendering enough pixels for the gradient to cover the whole element.
After playing around with different values of border radius, gradient colours, padding, border-width and others we came to these conclusions:
- This only occurs at a border radius of 3px
- This only occurs when you place a linear gradient as the background
- The bug can only be observed at 100% browser zoom (if you bump up the font-size in the browser you can’t see it)
- The dots aren’t actually white, they’re missing pixels (transparent) that aren’t being rendered by the gradient function.
Since it was such a specific bug that was only visible at normal zoom we concluded it was a problem with the rendering algorithm. We decided to raise a bug in Microsoft’s feedback program for IE10, as well as looking for an immediate fix.
Later that day in a discussion with Ben Buchanan, another AUI developer, we had a brainwave: if the white dots were indeed caused by the algorithm then maybe we could trick it into rounding the way we want it to. What if we gave it a slightly bigger number so that it rounds to a point where it actually renders those missing 4 pixels?
Enter the 3.1px fix.
We changed the border radius on our buttons to:
and voila! No more white dots, with a border radius that is still rendered as 3px in all browsers.
What’s interesting here is that if you compare the border radius of 3px and 3.1px in the different browsers you get the following results:
- Firefox: No difference
- Chrome: No difference
- Safari: No difference
- IE9: Slightly transparent corner pixels
- IE10: Slightly transparent corner pixels (more noticeable than IE9)
Out of curiosity we compared several different sub-pixel values in IE10 (note these boxes all have gradients of #000 to #000):
The slightly transparent pixels gives the rounded edges a very subtle blur that you can’t really see at normal zoom.
Refining to the 3.01 fix
After finding this fix, we mentioned it on our UI HipChat channel – a common collaboration point for Atlassian frontenders. JIRA frontender Sean Curtis suggested we try a smaller number, 3.001px, to defensively account for any changes the other browsers may implement to their algorithms. After some fiddling around with values we found that 3.01px was the smallest number the browser would accept – 3.009px brings the white dots back.
If you’re not happy with the slight blurriness of the 3.01 fix there is another way. Since these are missing pixels, it means the dots are transparent and will show either the element it is sitting on or the background-colour of the element. If you set the background-color to one of the colours of your gradient you can essentially “hide” the dots (although they are still there) by filling them with colour. You can use one of these two ways:
background-image: -ms-linear-gradient(top, #fff 0%, #000 100%);
background: #000 -ms-linear-gradient(top, #fff 0%, #000 100%);
It looks nicer but doesn’t fix the actual problem so much as mask its effects – and it only really works for gradients of similar shade.
It’s a very peculiar bug and it’s so specific we’re lucky to have observed it. Ultimately we decided to use the sub-pixel fix as it actually removes the missing pixels and is less of a workaround. However if you aren’t happy with the slight blurriness this produces you can always set the the background-color and leave the pixels there.