Why em instead of px?
The reason I asked this question was that I forgot how to use em's as it was a while I was hacking happily in CSS. People didn't notice that I kept the question general as I wasn't talking about sizing fonts per se. I was more interested in how to define styles on any given block element on the page.
As Henrik Paul and others pointed out em is proportional to the font-size used in the element. It's a common practice to define sizes on block elements in px, however, sizing up fonts in browsers usually breaks this design. Resizing fonts is commonly done with the shortcut keys Ctrl++ or Ctrl+-. So a good practice is to use em's instead.
Using px to define the width
Here is an illustrating example. Say we have a div-tag that we want to turn into a stylish date box, we may have HTML-code that looks like this:
<div class="date-box">
<p class="month">July</p>
<p class="day">4</p>
</div>
A simple implementation would defining the width of the date-box
class in px:
* { margin: 0; padding: 0; }
p.month { font-size: 10pt; }
p.day { font-size: 24pt; font-weight: bold; }
div.date-box {
background-color: #DD2222;
font-family: Arial, sans-serif;
color: white;
width: 50px;
}
The problem
However, if we want to size the text up in our browser the design will break. The text will also bleed outside the box which is almost the same what happens with SO's design as flodin points out. This is because the box will remain the same size in width as it is locked to 50px
.
Using em instead
A smarter way is to define the width in ems instead:
div.date-box {
background-color: #DD2222;
font-family: Arial, sans-serif;
color: white;
width: 2.5em;
}
* { margin: 0; padding: 0; font-size: 10pt; }
// Initial width of date-box = 10 pt x 2.5 em = 25 pt
// Will also work if you used px instead of pt
That way you have a fluid design on the date-box, i.e. the box will size up together with the text in proportion to the font-size defined for the date-box. In this example, the font-size is defined in *
as 10pt and will size up 2.5 times to that font size. So when you're sizing the fonts in the browser, the box will have 2.5 times the size of that font-size.
What is the difference between px, em and ex?
- Pixels (
px
) are browser dependent. It is the absolute size that you would see on your screen. Em
are sort of like percentages.Em
s is referring to the base text size. The value of1 em
means the same thing as a value of100 percent
. But you can also say it in the opposite way: A percentage value is just anem
multiplied by 100.- Points(
pt
) are what you would want to use in print media.
Should I use px or rem value units in my CSS?
TL;DR: use px
.
The Facts
First, it's extremely important to know that per spec, the CSS
px
unit does not equal one physical display pixel. This has always been true – even in the 1996 CSS 1 spec.CSS defines the reference pixel, which measures the size of a pixel on a 96 dpi display. On a display that has a dpi substantially different than 96dpi (like Retina displays), the user agent rescales the
px
unit so that its size matches that of a reference pixel. In other words, this rescaling is exactly why 1 CSS pixel equals 2 physical Retina display pixels.That said, up until 2010 (and the mobile zoom situation notwithstanding), the
px
almost always did equal one physical pixel, because all widely available displays were around 96dpi.Sizes specified in
em
s are relative to the parent element. This leads to theem
's "compounding problem" where nested elements get progressively larger or smaller. For example:body { font-size:20px; }
div { font-size:0.5em; }Gives us:
<body> - 20px
<div> - 10px
<div> - 5px
<div> - 2.5px
<div> - 1.25pxThe CSS3
rem
, which is always relative only to the roothtml
element, is now supported on 99.67% of all browsers in use.
The Opinion
I think everyone agrees that it's good to design your pages to be accommodating to everyone, and to make consideration for the visually impaired. One such consideration (but not the only one!) is allowing users to make the text of your site bigger, so that it's easier to read.
In the beginning, the only way to provide users a way to scale text size was by using relative size units (such as em
s). This is because the browser's font size menu simply changed the root font size. Thus, if you specified font sizes in px
, they wouldn't scale when changing the browser's font size option.
Modern browsers (and even the not-so-modern IE7) all changed the default scaling method to simply zooming in on everything, including images and box sizes. Essentially, they make the reference pixel larger or smaller.
Yes, someone could still change their browser default stylesheet to tweak the default font size (the equivalent of the old-style font size option), but that's a very esoteric way of going about it and I'd wager nobody1 does it. (In Chrome, it's buried under the advanced settings, Web content, Font Sizes. In IE9, it's even more hidden. You have to press Alt, and go to View, Text Size.) It's much easier to just select the Zoom option in the browser's main menu (or use Ctrl++/-/mouse wheel).
1 - within statistical error, naturally
If we assume most users scale pages using the zoom option, I find relative units mostly irrelevant. It's much easier to develop your page when everything is specified in the same unit (images are all dealt with in pixels), and you don't have to worry about compounding. ("I was told there would be no math" – there's dealing with having to calculate what 1.5em actually works out to.)
One other potential problem of using only relative units for font sizes is that user-resized fonts may break assumptions your layout makes. For example, this might lead to text getting clipped or running too long. If you use absolute units, you don't have to worry about unexpected font sizes from breaking your layout.
So my answer is use pixel units. I use px
for everything. Of course, your situation may vary, and if you must support IE6 (may the gods of the RFCs have mercy on you), you'll have to use em
s anyway.
Why did Bootstrap 4 choose rem and em instead px?
REMs are useful almost anywhere size is explicitly set.
With rem, all font sizes are relative to the root element (aka, the
html tag). The reason for this is to make it easier to scale up or down for devices. You could technically change the html tag to a smaller or larger size to scale all font sizes equally – which is a super nice feature.... [T]he main thing to take-away is everything is dynamic and
relative to the root HTML tag.For example, change the html css font-size to a different number ...
and watch how the entire grid adjusts and scales.
Source: Scotch.io
Why use rem instead px when it's the same anyway?
So after all the research, I came to the conclusion that the only advantage of rem
, is that users who use a bigger default font-size in their browser setting, will get the font-size scaled properly, while px
will not scale. In other words, using rem
for font-size
, adds support for Accessibility to your website.
To sum up:
rem
is a way to add support for Accessibility to your website.- Keep in mind, most users use zoom instead of font-size change in their browser and phones, because zoom easier to access.
- Browser zoom has additonal affect on
em
, in other words, it scalesrem
andpx
equally. - Since 2012,
rem
is supported by all major browsers on desktop and mobile devices. - Use
px
as fall back option for IE8 and lower. - Although not specified by W3C, all browser across desktop and mobile devices have implemented a default
font-size
of 16px (feel free to Google yourself), which equals to 1rem
/em
- To make the conversion easier between
px
andrem
you can usehtml {font-size: 62.5%;}
which converts10px
to1rem
In one sentence: Use rem
with px
on font-size
to support accessibility.
html {
font-size: 62.5%;
}
.your_class {
font-size: 16px;
font-size: 1.6rem;
}
Ems instead of px in Chrome developer tools?
The values shown on the Computed tab are just that: computed. Therefore, they are listed in a "absolute" length unit like pixels and not a "relative" length unit like ems, rems or percentage, which all base their size off of some other criteria. For instance, if you set an elment to 100% of the viewport width, it will show you how many pixels the width of the element computes to and there is no option to view the value in any other unit. Likewise, because you're using ems, how big your icon is will be based off the inherited font-size value.
In fact, I haven't tested this but I think the px values shown on the computed tab are technically shown in device pixels and not CSS pixels, as CSS pixels themselves are relative length units (since their size is based on the DPI of the device screen).
Relative Length Units
Absolute Length Units
If browsers can zoom now, why should we use em instead of px?
Well, em's are good in css when you want to create custom scalable buttons, you see. If you used pixels for the padding, then you'll be in for a heck of measurements, while if you used em's, the padding would dynamically scale in size according to the size of the font.
Are there any practical reasons to use em instead of pt font size units?
Depending on the country where you live, you might actually end up breaking the law using pt instead of em, depending on how hard your legislature want to enforce rules. Here in the UK, there is a disability discrimination act, which has been used to target companies where their websites have been rendered in a fixed font. This is treated as discrimination because it disadvantages the partially sited who may have increased their browser font sizes to compensate - but your site still renders fonts at the size you set, and not at the size they would expect.
Yes, it's harder to get to grips with relative font-sizes and fluid layouts, but if you want to comply with legislation, you have to take the time to get to grips with this.
For local government work in the UK, targets have been set to ensure that websites follow Double A guidelines, one of which states "Use relative rather than absolute units in markup language attribute values and style sheet property values". See here.
Related Topics
How to Position Div Below Another Div
Formatting Numbers (Decimal Places, Thousands Separators, Localization, etc) With CSS
Split Div into 2 Columns Using CSS
Css Change Button Style After Click
What Is the Way to Add Horizontal Scroll on Material-Ui Table With Many Columns
Stretch Child Div Height to Fill Parent That Has Dynamic Height
How to Change Color Property of Mat-Slide-Toggle/ Overwrite CSS of Component
How to Set the Width of Select Box Options
Swap Div Position With CSS Only
Make a Div Fill an Entire Table Cell
Angular 5 - Failed to Load Resource: the Server Responded With a Status of 404 (Not Found)
How to Change Paper Size in Headless Chrome - Print-To-Pdf
How to Create a Flexible Vertical Line in Between Two Divs
Detect If a Browser in a Mobile Device (Ios/Android Phone/Tablet) Is Used