Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do float font-size values on CSS render among browsers?

The CSS em unit is great, but there are things that always annoyed me, probably because I don't understand them completely.

Fonts don't render equally right at every size, and especially bad at inexact values. That is why, if you want to give using em exact pixel values to fonts, you have to do things like (assuming you didn't change the 16px font size of the body):

font-size: 0.875em; /* 14px */
font-size: 1.25em; /* 18px */

Maybe you just wanted to increase the size a little, but then realised that 0.9em = 14.4px, and then you got scared your font may look blurry! In any case, if you give a paragraph a font-size of 1.25em (18px), and then, change the body size from 16px to 14px, then the paragraph would be 17.5px. Blurry again!

Assuming we are working on common 1x ration screens like desktop ones, how would, for example, a 11.5px font render? I've printed them on a test HTML file and they seem to look exactly like a 12px font.

Is this the recommended behaviour among all browsers? And what about sizes like padding and margin that may be determined by font-size when using ems? Do they get rounded up as well?

I made a comparison between the renderings on 3 mayor browsers. Here it is:

enter image description here

I scaled it up (200%) a little, so that it is easier to see the details. At the top, you can see how the same text renders at 14px (left) and 14.4px (right). Below, I overlayed them on photoshop using Difference blendmode to see if there is any difference at all. As you can see, Chrome rounds the font-size, and renders it at the same size, meanwhile, the height of the box, is different. Firefox has same height but the font renders slightly different on the x axis, while the height of the font seems equal. IE result is kind of a mix. In any case, I'm really surprised because the 14.4px font doesn't seem to be blured at all.

like image 926
Vandervals Avatar asked Mar 14 '16 10:03

Vandervals


People also ask

How are fonts rendered?

Font rasterization is the process of converting text from a vector description (as found in scalable fonts such as TrueType fonts) to a raster or bitmap description. This often involves some anti-aliasing on screen text to make it smoother and easier to read.

Which property of CSS controls the size of the font?

The font-size CSS property sets the size of the font.

How do I automatically adjust font-size in CSS?

The font-size-adjust property of CSS tells the browser to adjust the font size of the text to the same size regardless of font family. When the first chosen font is not available, the font-size-adjust property allows you more control over the font size.


2 Answers

It's not a simple question and does not apply "exactly" to the browser. It's more a question about the whole rendering systems used and about "continuous spaces vs. discrete spaces" or "draw a curve using square boxes".

Some texts that could help to have a better understanding about the question:

(Try results from google searchs "font rendering discrete space","sub-pixel font rendering", or "font hinting")

http://jcgt.org/published/0002/01/04/paper.pdf http://www.cutebugs.net/files/curve/fabris97antialiasing.pdf http://lspwww.epfl.ch/publications/typography/frsa.pdf https://www.grc.com/ctwho.htm

A "right" behaviour is difficult to define here, and so a "default behaviour" becomes almost impossible. It's a mathematical question about space and human perception more than about browsers behavior or CSS.

...anyway the discribed behaviour about "moving 1 pixel" is related to the font hinting technique the browser or system uses.

like image 55
miguel-svq Avatar answered Sep 20 '22 12:09

miguel-svq


But is this the recommended behavior among all browsers?

Here is what I found on w3.org

The reference pixel is the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm’s length. For a nominal arm’s length of 28 inches, the visual angle is therefore about 0.0213 degrees. For reading at arm’s length, 1px thus corresponds to about 0.26 mm (1/96 inch).

So 1px does not necessarily correspond the 1 pixel on the screen, see image below:

So even though you could calculate based on 0.25px (using the pixel value above), to move elements by 1 literal screen pixel, it is not done.

And what about sizes like padding and margin that may be determined by font-size when using ems? Do they get rounded up as well?

Check out this question, it may be of use. Basically the values are rounded. The reason your 11.5px looked the same as 12px was because it was rounded up. 11.4px would look just like 11px

Also look at this website, it provides some interesting behavior on how this works.

See the Code Snippet below an example. See how the div only gets moved down by one pixel on translateY(0.5px), this proves the browser rounds the value:

.box {
  width: 30px;
  height: 30px;
  background-color: #FF0000;
  display: inline-block;
}
#cont {
  outline: 1px solid #000;
  display: inline-block;
}
<div id="cont">
  <div class="box" style="transform: translateY(0.1px)"></div>
  <div class="box" style="transform: translateY(0.2px)"></div>
  <div class="box" style="transform: translateY(0.3px)"></div>
  <div class="box" style="transform: translateY(0.4px)"></div>
  <div class="box" style="transform: translateY(0.5px)"></div>
  <div class="box" style="transform: translateY(0.6px)"></div>
  <div class="box" style="transform: translateY(0.7px)"></div>
  <div class="box" style="transform: translateY(0.8px)"></div>
  <div class="box" style="transform: translateY(0.9px)"></div>
  <div class="box" style="transform: translateY(1.0px)"></div>
</div>
like image 43
Kaspar Lee Avatar answered Sep 17 '22 12:09

Kaspar Lee