Skip to content

Instantly share code, notes, and snippets.

@basham
Last active November 19, 2024 15:03
Show Gist options
  • Save basham/2175a16ab7c60ce8e001 to your computer and use it in GitHub Desktop.
Save basham/2175a16ab7c60ce8e001 to your computer and use it in GitHub Desktop.
CSS Units Best Practices

CSS units

Recommendations of unit types per media type:

Media Recommended Occasional use Infrequent use Not recommended
Screen em, rem, % px ch, ex, vw, vh, vmin, vmax cm, mm, in, pt, pc
Print em, rem, % cm, mm, in, pt, pc ch, ex px, vw, vh, vmin, vmax

Relative units

Relative units play nicely with both screen and print media types and should be the most frequently used CSS units.

Unit Description
% percentage, relative to the same property of the parent element
em relative to font size of the element
rem relative to font size of the root element
ch relative to width of the "0" (ZERO, U+0030) glyph in the element's font
ex relative to x-height of the font

Absolute units

Physical units (e.g. cm, mm, in, pc, and pt) should only be used for print style sheets, while pixels (px) should only be used for the screen. While there are consistent conversions among all of these absolute length units, depending on the device, CSS units can actually mean different things. For example, while 1cm in CSS should print as one physical centimeter, there's no guarantee that 1cm in CSS results in one physical centimeter on the screen.

Unit Description cm mm in pc pt px
cm centimeter 1cm 10mm
mm millimeter 1/10cm 1mm
in inch 2.54cm 25.4mm 1in 6pc 72pt 96px
pc pica 1/6in 1pc 12pt 16px
pt point 1/72in 1/12pc 1pt 4/3px
px pixel 1/96in 1/16pc 3/4pt 1px

Viewport units

Viewport-percentage length units should be used with caution, as there is still some lingering bugs with their implementation.

Unit Description
vw relative to 1% of viewport's width
vh relative to 1% of viewport's height
vmin relative to 1% of viewport's smaller dimension
vmax relative to 1% of viewport's larger dimension

Contexts

Document-level

Assume the root font size is 16px but don't require it to be so. Either declare the font size as 100% or don't declare the font-size property at all.

html {
  font-size: 100%;
}

Borders

Most likely use px, as most of the time, the border shouldn't need to scale.

.Component {
  border-bottom: 1px solid #ccc;
}

Font-size

Font-size should only be applied at the lowest possible child elements, in order to minimize its cascading impact on relative units. While both of the following two examples are essentially equivalent, only the first is recommended.

DO:

.Component {
}
.Component-heading {
  font-size: 1.2em;
}
.Component-body {
  font-size: 0.9em;
}

DO NOT:

.Component {
  font-size: 1.2em;
}
.Component-heading {
  font-size: 1em;
}
.Component-body {
  font-size: 0.75em;
}

Padding and margin

In order to ensure consistent use of whitespace throughout the application, given a component could be used in a variety of contexts, it may be best to use rem for margin and padding than em.

.Component {
  margin: 1rem 0;
  padding: 1rem;
}

Media queries

Only use em within media query definitions, never pixels. Until there's wider rem support within media queries, rem should be avoided in media queries as well.

@media (min-width: 20em) {
  .Component {
    background-color: blue;
  }
}
@aflashyrhetoric
Copy link

Great overview/reference!

@equinusocio
Copy link

A tiny error:

em - relative to font size of the element

EM is relative to font size of the parent element. Not the element itself.

@fregante
Copy link

fregante commented Dec 15, 2016

@equinusocio no, em is relative to the closest font-size definition.

html {
  font-size: 10px;
  border-width: 1em; /* 10px */
}
body {
  font-size: 20px;
  border-width: 1em; /* 20px */
}

It only follows the parent's if you are setting the element's own font-size

html {
  font-size: 10px;
  border-width: 1em; /* 10px */
}
body {
  font-size: 2em; /* 20px */
  border-width: 1em; /* 20px, not 10px, because it follows its own font-size */
}

@fregante
Copy link

https://www.w3.org/TR/css-values-3/#font-relative-lengths

the font-relative lengths refer to the font metrics of the element on which they are used. The exception is when they occur in the value of the font-size property itself, in which case they refer to the computed font metrics of the parent element

@equinusocio
Copy link

In realtà sono giusti entrambi i casi perche comunque se il font-size non è dichiarato nell'elemento stesso l'em fa riferimento alla prima dichiarazione che trova nei parent, fino ad arrivare alla root e al font-size impostato dal browser. Quindi di default, è relativo al font-size più vicino si, ma che per forza è un parent (se non espresso appunto nell'elemento stesso)

@gsklee
Copy link

gsklee commented Apr 28, 2017

You probably wanna add ic into the Relative Units section which is relative to the width of the CJK "水" (WATER, U+6C34) character in the element's font.

@gsklee
Copy link

gsklee commented Apr 28, 2017

The last link inside the gist also seems to be dead.

@pmmueller
Copy link

pmmueller commented Nov 15, 2018

Thank you for this very nice overview!

About "Media Queries in em only" - that seems to be more of a myth than a fact or an actual recommendation.

Way back there were zoom problems in browsers, but in the 2012 article you cite the author has added this to the article in 2015:

You should note that the zooming behavior has long since been made consistent in browsers (i.e. fixed). Keep that in mind if you cite or otherwise put stock in this post. I never meant to be absolutely prescriptive about ems as units—use whatever feels natural and appropriate for your design strategy.

In other words: Media Queries in px are no problem.

Also there is a question about this from Stephen Hay to Ethan Marcotte right at the beginning of the "Speaker Panel | CSS Day 2014": https://vimeo.com/102847187#t=30s

Ethan prefers MQs in em but thinks that "it's more stylistic" and that "pixels are just fine".

@cjblomqvist
Copy link

Thanks for the post, and thanks @pmmueller for adding your note about this!

@bn-l
Copy link

bn-l commented May 8, 2019

Why not use ch and ex frequently? They seem perfect for width and height

@rcmohanraj
Copy link

Great post.. Thanks

@marwanbayoumi
Copy link

Excuse the dumb question but what do you mean by Print?

@basham
Copy link
Author

basham commented Feb 10, 2020

Excuse the dumb question but what do you mean by Print?

@marwanbayoumi You can use CSS to style a page differently whenever it is printed. In such cases, using a physical unit may be more appropriate. See these resources for more on this topic:

  1. A Guide To The State Of Print Stylesheets In 2018 (Smashing Magazine)
  2. Printing (MDN Web Docs)

@basham
Copy link
Author

basham commented Feb 10, 2020

Why not use ch and ex frequently? They seem perfect for width and height

@bn-l This guide is a bit bias toward web apps. When wanting to maintain fixed sizing and spacing throughout a user interface, it may be better to primarily use rem, as that provides a way to be flexible and consistent.

In the case of content sites, ch and ex units may occasionally be more appropriate. For example, if wanting to stay within the recommended 45–90 characters per line to improve readability, you could do this:

p {
 width: 45ch;
}

To calculate a similar width with another unit would involve math or trial-and-error. In this case, ch is a very straightforward solution.

@HMaker
Copy link

HMaker commented Sep 15, 2020

@basham Practices about scaling the elements for high DPI screens like smartphone screens would be good. Really the use o fixed pixels becomes a mess when the site is displayed in a screen with different DPIs, which always happen when the website is public.

@basham
Copy link
Author

basham commented Sep 17, 2020

@basham Practices about scaling the elements for high DPI screens like smartphone screens would be good. Really the use o fixed pixels becomes a mess when the site is displayed in a screen with different DPIs, which always happen when the website is public.

@HMaker Do you have any recommendations in this area or have any suggestions for such a resource? I haven't studied this topic. Don't know if there's too much more than a resolution media query.

Copy link

ghost commented Jan 31, 2021

"Only use em within media query definitions, never pixels." - the article from 2012. I think this has been fixed or am I wrong?

@akramnarejo
Copy link

Isn't it more responsive if we use rem for font-size rather than em.?

@berzi
Copy link

berzi commented Sep 16, 2021

This document should be updated, it shows up quite high on Google but contains many outdated concepts, for example based on limited feature support, even when caniuse now shows very good support (see for example vmin/vmax or rem on "usare relative" view, which clearly shows unsupported browser versions are almost completely unused at this point).

The vmin/vmax section in particular could use some expansion on the use case, and the em section should probably recommend the use of rem, which doesn't yield the same issues as em, since it doesn't inherit from parent elements in cascade.

Furthermore, the use of percentages is promoted as though it would solve any problem, but that is not the case and it's important to redirect the user. See for example this question on SE.

@andrei9669
Copy link

@berzi there's also this article that suggests not to use relative units on layout. altho, I don't know how relevant it is.

@faisal95bd
Copy link

That's what I've been looking for 😃

@vikramvi
Copy link

For media queries do we need to still use em vs rem ?

@allaboutnft
Copy link

Verify Github on Galxe. gid:mGErGTSTvcAM2BuipcSWyn

@AdejuwonAdepate
Copy link

nice/ but this wont work perfectly for media queries

@BANOnotIT
Copy link

vw/vh should be updated with lvh, lvw, dvw, dvh and the co.

@blou6
Copy link

blou6 commented Oct 20, 2023

Shouldn't we use 'rem' than 'em'?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment