px
: pixel - difficult to measure now with high-res screens. 96px
is about 1 physical inch on the screen.mm
: millimetercm
: centimeterQ
: quarter-millimeterin
: inchpt
: pointpc
: pica12pt
is equal to 16px
Unit | CSS property |
---|---|
rem | font-size document flow (consistent spacing) padding margin |
em | media queries document flow (with more space) |
px | shadow-box border border-radius |
% | page/container widths |
height
: use min-height() when you need to set a height so that the content does not overflow at the bottom if the viewport size changes.rem
for properties that you do not want to scale.em
for properties that you want to scale.Styling with relative units is helpful because you do not know the absolute size of the screen that your document will display on - you don’t know exactly how to size your elements
Ems are the most common relative length unit, comes from typography.
Uses the local font size to determine its computed value:
1.5em
, then the size of 1em
for that element is 24px
. (16px * 1.2 = 24px)font-size
is 16px
and the padding is 2em
, then the padding is 32px
DO NOT use ems for
font-size
. If you define thefont-size
with anem
, then the size of theem
is derived from the inherited font size. If you useems
to define other properties likepadding
, then the browser first calculates the font size, then calculates thepadding
with that font size. So,font-size
andpadding
might have the same declared value but different computed values.
.padded {
font-size: 16px;
padding: 1em; /* computes to 16px */
/*padding: 1.5em; computes to 24px */
}
Use rem
for font sizes.
Rem is short for “root em”, so a rem
is relative to the font-size
value in the root. The root is the html
tag, which is the root of the HTML document. You can access the html
tag with the :root
pseudo-class selector so you can have the specificity of a class element rather than a tag.
Because rems are relative to the root element, it has the same computed value throughout the stylesheet.
This article says to use rem for fonts and px for everything else. This is because padding and margin scale along with the font. You might want to use rem instead of px at times.
Examples and implementations in this CSS tricks article, Fun With Viewport Units.
Use cases:
The viewport is the area in the browser window where the web page is displayed - NOT including the address bar, shortcuts, toolbars, etc. The following are the basic units:
vh
: 1% of the viewport heightvw
: 1% of the viewport widthvmin
: 1% of the smaller dimension, height or widthvmax
: 1% of the larger dimension, height or widthSo, 25vh
is 25% of the viewport’s height.
Viewport units are good for large hero images. However, this is an issue with mobile devices because some mobile devices have a feature that hides the address or nav bar to save space. This causes viewport-relative items to change size on the screen. This is called layout thrashing.
Also, remember that viewports do not take scrollbars into account.
vmin
lets you set the height or width depending on the size of the viewport. This example sets the height to 90vh if the screen height is smaller than the width, and sets it to 90vw if the width is smaller than the height:
.div {
width: 90vmin;
height: 90vmin;
background-color: #369;
}
Viewport units were used for heroes, but some mobile devices dynamically hide menus when you are not scrolling and then display them when you are scrolling. This can cause the content on the screen to jump if you use viewport units. This is called layout thrashing.
This is largely resolved in the mobile browsers, but it might still be an issue.
To address this, CSS came up with large and small viewports:
l
to the unit (lvh
)s
to the unit (svh
)This is not used very often.
When a viewport size changes because the device hides a UX component, you can use the large (for screens without the address bar):
lvw
lvh
lvmin
lvmax
Or small (for screens with the address bar):
svw
svh
svmin
svmax
Some properties accept unitless values, but you can also use 0 without a unit, because 0 is equal to 0 of any length.
Accepts both units and unitless values, but prefer unitless because they are inherited differently:
To calculate the line-height, multiply the font-size
by the line-height
value:
16px
(1rem
) * 1.1
= 17.6px
/* total line height is 38.4px */
body {
line-height: 1.2;
}
.about-us {
font-size: 2em;
}
Create dynamic and context-based styling:
--var-name
) and assign with var()
var()
accepts a second optional fallback value:root
selector so they’re available for the entire page:root {
--main-font: Helvetica, Arial, sans-serif;
--brand-color: #369;
}
p {
font-family: var(--main-font, sans-serif);
color: var(--brand-color, blue);
}
.dark {
margin-top: 2em;
padding: 1em;
background-color: #999;
--main-bg: #333; /* redefine global vars */
--main-color: #fff;
}
You can add dark and light themes with custom properties. First, create the theme colors with class styles on the :root
element:
:root.dark {
--border-btn: 1px solid rgb(220, 220, 220);
--color-base-bg: rgb(18, 18, 18);
--color-base-text: rgb(240, 240, 240);
--color-btn-bg: rgb(36, 36, 36);
}
:root.light {
--border-btn: 1px solid rgb(36, 36, 36);
--color-base-bg: rgb(240, 240, 240);
--color-base-text: rgb(18, 18, 18);
--color-btn-bg: rgb(220, 220, 220);
}
/* apply custom props to elements below */
Then, use JS to grab the root element (documentElement
), and toggle the theme:
let setTheme = () => {
const root = document.documentElement;
const newTheme = root.className === "dark" ? "light" : "dark";
root.className = newTheme;
document.querySelector(".theme-name").textContent = newTheme;
};
document.querySelector(".theme-toggle").addEventListener("click", setTheme);