5

I remember having read here on SO that pixel fractions should be generally avoided in CSS because browsers tend to round them to full pixels.

And indeed, the below example shows how 0.3 pixels are rounded to a full pixel:

span {
  border: 0.3px solid black;
}
<span>Lorem ipsum.</span>

I am very surprised because I seem to have found a counterexample:

span {
  color: white;
  -webkit-text-stroke: 0.3px black;
}
<span>Lorem ipsum.</span>

Compare with 1px:

span {
  color: white;
  -webkit-text-stroke: 1px black;
}
<span>Lorem ipsum.</span>

I'm not complaining that it happens, on the contrary it's almost a lifesaver for me, but I'd like to understand why does it happen.

  • When are browsers rounding pixel fractions to full pixels? And when are they not? What are the rules here?
  • Can I rely on browsers not rounding 0.3px to 1px in the above example? Is this behavior consistent across browsers? Or is relying on this behavior a recipe for trouble?
  • HOW does this happen at all? On laptops a pixel should be indivisible bc of hardware (monitor) limitations?
  • [Relevant spec](https://www.w3.org/TR/css-cascade-4/#actual) for anyone digging deeper into this. At a glance the spec says it's up to the implementation, but perhaps someone can shine more light on it. – Etheryte Sep 18 '19 at 20:09
  • [Related answer](https://stackoverflow.com/a/5587820/391715) on another question about CSS subpixels – abney317 Sep 18 '19 at 20:25

1 Answers1

1

Well per the Spec rounding is up to the implementor (browser render engine). However, that only appears to apply to layout rules like borders. I think that's intentional since text rendering seems to utilize OS level render systems that include anti-aliasing techniques for HiDPI displays and LCDs.

Rendering Fonts

My guess is that your "working" example only works because it's text. In Webkit based browsers you can tweak the rendering result using CSS text-rendering. Here's Mozilla's documentation

Rendering HTML Elements

However, if you want sub-pixel rendering or better smoothing you can apply a CSS transform: translateZ(0) to elements. At least in Chrome and I believe other modern browsers, this will force subpixel aliasing. But I don't know that it will override the browsers rounding that likely happens before the rendering.

Community
  • 1
  • 1
Bryce Howitson
  • 7,339
  • 18
  • 40