Fractional border width sometimes causes a 1px "padding", how to fix?

Viewed 183

To create a rounded rectangle with a 3D-like effect, I have a div inside a div, as follows:

* {
  box-sizing: border-box;
}
body {
  font-size: 0.948px;
}
.outer {
  font-size: inherit;
  width: 20em;
  height: 26em;
  background: #fc6;
  border: 1.4em solid #bad9d9;
  border-radius: 3.98em;
  line-height: 20.8em;
  text-align: center;
}
.inner {
  font-size: 8.64em;
  height: 87%;
  background: #fff;
  border-radius: 2.844px;
}
<div class="outer">
  <div class="inner">768</div>
</div>

In this code, I am trying to create this, but depending on the exact value of div.outer's font-size (set via JavaScript), a 1-pixel padding sometimes develops at the top and/or sides of the outer rectangle, as shown here. I believe this is caused by the browser rounding the fractional border width up for positioning elements, but rounding it down when drawing it on the screen. This effect (bug?) occurs in Chrome and Edge, but not Firefox.

Edit: I would like to clarify that almost all the styles are dynamically updated via JavaScript (this is part of a larger project). The border-width could shrink to 0em or expand to 4em, and I am looking for a workaround to this bug (I believe it is a rendering bug) that works for any border-width.

My question: is there a way to fix this without

  • Using JavaScript to convert from em values to rounded px values?
  • Using a third element to draw the border (pseudo- or otherwise)?

Gallery:

original - original

at 500% zoom - at 500% zoom

with the border-width at 1.0em - with the border-width at 1.0em

with the border-width at 0.8em - with the border-width at 0.8em (what I want)

with the border removed - with the border removed

(all screenshots scaled up using Chrome's trackpad pinch-zoom)

3 Answers

I would prefer not to mix different types of Units use em everywhere. In addition, make the inner width 100% so it always fills the outer and does not have extra space of the outer visible.

I would say that .outer should have the border like :

border: 0.7em solid #bad9d9;

and the .inner should also have these stylings :

  border-radius: 50.844px;
  text-align:center;

That may solve your problem.

Related