Relative Units
Once upon a time, developers knew the exact screen size that their application used. Now, users can set their screen to any size, and the browser has to calculate units and apply styles.
This means that you have to create style rules that work in any context. This is called responsive design.
Responsive design is when styles respond differently based on the size of the browser window.
Relative units
Ems and rems are the most common (only?) relative units in CSS. Values declared using relative units are evaluated by the browser to an absolute value.
Ems
DO NOT use ems for
font-size
, because they are based on this value. You can useems
for the following:
- padding
- margin
- element sizing
An em
is relative to the element’s font-size
—its local font size—and its value varies depending on the element that that you’re applying it to. 1 em
means ’the font size of the current element'.
.padded {
font-size: 16px;
padding: 1em; /* computes to 16px */
/*padding: 1.5em; computes to 24px */
}
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.
To find the pixel size in
em
units, divide the desired pixel size by the inherited pixel size. For example, if you want a 20px font and the parent font is 16, 20/16 = 1.25 em.
Rems
You can use rems 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.
Fonts
Set the font-size
in the :root
pseudo-class. Use em
to set it here, and then rem
throughout the stylesheet to change the size, relative to the :root
setting.
The following example sets the inherited font size to 14px:
:root {
font-size: 0.875em;
}
For most browsers, the default font size is 16px.
Change padding and margin with fonts
If you change the font size for an element with rems, you do not have to change the padding or other relative properties because their values are calculated according to the local font-size
value.
Use
rem
for properties that you do not want to scale. Useem
for properties that you want to scale.
Media queries
A media query uses the @media
rule to specify styles that are applied to certain screen sizes or media types. You can define the root font-size in each media query:
:root {
font-size: 0.85em;
}
@media (min-width: 800px) {
:root {
font-size: 1em;
}
}
@media (min-width: 1200px) {
:root {
font-size: 1.15em;
}
}
min-width
is mobile-first responsive design.
Viewport-relative units
The viewport is the area in the browser window where the web page is displayed. The following are the basic units:
- vh—1% of the viewport height
- vw—1% of the viewport width
- vmin—1% of the smaller dimension, height or width
- vmax—1% of the larger dimension, height or width
So, 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.
When a viewport size changes because the device hides the address bar, 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
Viewports and font-size
You can use the calc()
function to do basic arithmetic with two or more values.
clamp() function
The clamp()
function lets you create a responsive font size. It has the following signature:
clamp(min-val, preferred-val-expression, max-val)
/* Example */
:root {
clamp(0.9rem, 0.6rem + 0.5svw, 1.5rem);
}
The previous example specifies a value of 0.6rem + 0.5svw
, where the 0.6em
acts as a minimum font size, and the 0.5svw
acts as a responsive scalar. The clamp function goes further to ensure that the value is never smaller than 0.9em
or larger than 1.5rem
.
Unitless numbers and 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
The line-height
is calculated locally as font-size x line-height. Use unitless values for line-height
because of inheritance–when you use a unitless number, the declared value is inherited and recalculated for each inherited child element. If you use a unit, when an element has a value defined with a length (rem, em, px), its computed value is inherited by child elements and can cause issues.
Variables (custom properties)
Define variables in the root
element so they are avialble for the entire page. Then, use them with the var()
function:
:root {
--main-font: sans-serif;
}
p {
font-family: var(--main-font);
}
The var()
function accepts an optional second parameter which acts as a fallback. If the first value is not defined, then it uses the second:
p {
font-family: var(--main-font);
color: var(--secondary-color, red);
}
Scope
Variables have scope. You can define a variable on the root
, and then redefine it on another ruleset for a particular container. Inheritence makes any styles based on the variable resolve to the root value if it is outside that container, and they resolve to the redefined value if it is inside the container.
Relative values
- A CSS pixel =/= to a monitor pixel
- Computed value: Absolute value that the browser computes for values declared using relative units
- Whe an element has a value defined using a length (px, rem, em, etc), its computed value is inherited by its child elements.
When to use rems:
- font sizing. Always use relative units when setting a font size because when users alter the screen zoom with + or -, pixels do not resize correctly.
When to use ems:
- padding
- margins
- element sizing
- border-radius
pixels:
- borders
percentages:
- container widths (as necessary)