Units
Definitions
Absolute units
Definite - they do not change in context:
px: pixel - difficult to measure now with high-res screens.96pxis about 1 physical inch on the screen.mm: millimetercm: centimeterQ: quarter-millimeterin: inchpt: point (12ptis equal to16px)pc: pica
Computed value
Absolute value that the browser computes for values declared using relative units. When an element has a value defined using a length (px, rem, em, etc), its computed value is inherited by its child elements.
Length
Formal name for a CSS element that has a unit, which is formally called a distance measurement.
Relative units
Different values depending on the context they are called in
- They are evaluated by the browser to an absolute value
- rems and ems are the most common
Suggested units
| Unit | CSS property |
|---|---|
rem | font-sizedocument flow (consistent spacing)paddingmargin |
em | media queriesdocument flow (with more space) |
px | shadow-boxborderborder-radius |
% | page/container widths |
Height
Use min-height when you need to set an element height so that the content does not overflow at the bottom if the viewport size changes.
Relative units
rems and ems
- No scaling:
remfor properties that you do not want to scale. - Scaling:
emfor 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. For example:
- Set a font size with relative units so it scales proportionately with the size of the window
- Set size of everything relative to the base font size and then resize everything by changing the base font size only
ems
Ems are the most common relative length unit, comes from typography. It uses the local font size to determine its computed value:
The computed value of a font size is derived from its inherited value:
- If
font-sizeis1.5em, then the size of1emfor that element is24px. (16px * 1.2 = 24px) - If
font-sizeis16pxand the padding is2em, then the padding is32px
Ems are tricky for nested elements that use ems for font-size and other properties, like padding
- If em size is smaller than 1, child elements computed value is smaller (0.8em * 0.8em = 0.64em)
- If em size is larger than 1, child elements computed value is larger (1.5em * 1.5em = 2.25em)
Do not use for font size
If you define the font-size with an em, then the size of the em is derived from the inherited font size. If you use ems to define other properties like padding, then the browser first calculates the font size, then calculates the padding with that font size. So, font-size and padding 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 */
}
rems
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.
Viewport-relative units
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 width
So, 25vh is 25% of the viewport’s height.
Hero images
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.
Examples and implementations in this CSS tricks article, Fun With Viewport Units. Use cases:
- full-height heroes
- full-screen app-like interfaces
- Responsive typography
- Full-Height layouts, hero images, and sticky footers
- Fluid aspect ratios
- Full width containers in Limited width parents
- Scroll indicators
vmin
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;
}
Large and small units
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:
- large is when all UX components are hidden. Prepend an
lto the unit (lvh) - small is when UX components are visible. Prepend an
sto the unit (svh)
When in doubt, use small viewport units.
When a viewport size changes because the device hides a UX component, you can use the large (for screens without the address bar):
lvwlvhlvminlvmax
Or small (for screens with the address bar):
svwsvhsvminsvmax
line-height
Some properties accept unitless values, but you can also use 0 without a unit, because 0 is equal to 0 of any length.
line-height accepts both units and unitless values, but prefer unitless because they are inherited differently. Unitless values are recalculated (computed) for all child elements.
Child elements inherit computed values if the value is assigned with lengths (units). This causes issues with line-height
To calculate the line-height, multiply the font-size by the line-height value. For example, 16px (1rem) * 1.1 = 17.6px
/* total line height is 38.4px */
body {
line-height: 1.2;
}
.about-us {
font-size: 2rem;
}
Custom properties (variables)
Create dynamic and context-based styling. You can declare a variable and assign a value to reference throughout your stylesheet.
This is more versatile than preprocessor variables because you can create a variable with double hyphens (--var-name) and assign with var(), and var() accepts a second optional fallback value.
Set global vars in the :root selector so they’re available for the entire page. These vars have scope—you can redifine variables within rulesets:
: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;
}