How to fix border-radius rendering

In browsers other than Firefox, there are issues related to rendering elements that have border-radius.

  1. If an element has both background and border specified, then there is a noticeable 1-pixel background-color stroke outside of rounded corners. This is especially noticeable when colors of background, border and parent-element background differ considerably. Until now, this did take place in Chrome, Opera, and IE9, currently — in Opera (11.5) and IE9:

  2. If different sides of an element have different border colors, then there will also be a 1-pixel background-color line at the joint of different border parts in Chrome 13 and IE9:

  3. In Chrome 13, if border width and radius are big, the inner perimeter of the rounded border is rendered roughly, almost polyline-like:

CSS code illustrating the issue:

.buggy {
    background: #fff;
    border: 70px solid #000;
    border-radius: 100px;
    height: 60px;
}

Solution

There is a workaround for these issues: element can be replaced with two nested elements, where the inner element has the desired background color as its background while the outer element’s background color is equal to the desired border color, and the outer element has padding equal to the desired border width.

HTML:
<div class="ok"><div>…</div></div>
CSS:
.ok {
    background: #000; /* Border color */
    border-radius: 100px;
    padding: 70px; /* Border width */
}

.ok > DIV {
    background: #fff; /* Background color */
    border-radius: 30px; /* Radius of outer element minus border width */
    height: 60px; /* For illustration purposes */
}

If, by design, border needs to have different colors for different sides of element, then, instead of padding, border itself can be specified for outer element. At that, possible gap between inner element and border of outer element can be hidden by partial moving inner element to border of outer element by using a negative margin of 1-2 pixels with concurrent increasing of border-width of outer element by the same value to compensate the offset.

Live example

See also the author’s border-radius generator that has a built-in workaround for rounded-corner issues described above.