CSS Units and Our Pixels

  • Last updated on 3rd Nov 2022

Our phones, monitors, TV’s are lit up through pixels. Small little crystals that are inside our LCD-powered devices.. If theres absolutely anything I’ll remember from High School Chemistry class, it’ll be this. So, it makes sense to measure and use pixels for our css boxes? We’ll explore this and alot more in this article.

Introduction

Some devices implement sub-pixel rendering. Sub-pixel rendering is both a gift and a curse. We are granted the gift of our own devices making the edges of elements in our designs easier on the eyes for users through anti-liasing. We are granted the gift of “woaa that looks crisp”. For us as designers, it comes at an expense.

The single px measurement is unrealiable because of the sub-pixel rendering technology. Across different device sizes with their respective aspect ratios and resolutions, we then subject ourselves to “pixel-accurate” design. It’s simply impossible and not accurate to our idea of “pixel accuracy” when taking into account this integration. Although, there is a hidden and subtle benefit. More on this later.

Accessbility & Adhering to Proportional Design

Our browsers are responsive by default. Practically speaking, our usage of px then goes against the grain of designing as guides for the browser. We are saying to the browser, “Hey, this is not right. Let me fix it. I am your usurper. Accept me.”

pixel-meme-scared

Users have access to modifying how big their default font-size should be in browser settings. When we use px we override that choice. Even with full page zoom support, our designs should be steering the browser to it’s own decisiveness.

The solution to adhere to proportional design is through the usage of rem, em, ex, and ch because all are relative units of measurement. This means that all work with the users preference of their default font size (whether that’s through their Operating System (OS) or via the browser). These units are then pillars of proportional design because they don’t interrupt base functionality within the browser. Whatever process the browser takes to display our units, we know it won’t be “pixel perfect” but we also know we are really close.

Relativity in-depth

When we use rem units (16px when converted) we are saying, “whatever size the parent is, multiply it by number here”. The default styling of elements like our p element in the browser are largely responsive by default because of this very design.

:root {
  font-size: 1rem;
}

p {
  font-size: 1rem;
}

h1 - h3 elements are by default larger than the standard size of 1rem. They are 2rem (32px), 1.5rem (24px), and 1.2rem (19.2px) respectively.

The foundation of information before the internet was physical text like books or newspapers. Although you would need to have enough space to read and have legible text, pixels or a single dot of ink as the unit of measurement were the basis of the medium. I think that it’s natural that we haven’t really adapted fully to this change in our web design. With em, rem, ch, and ex as unit measurements, we’ll be more concise in this effort. All these relative units could be used across the board, not just with our text content.

Sub-pixel rendering’s hidden benefit comes from it’s “rounding” to approximate the value of our measurements. In practical terms, we don’t need to worry about being pixel perfect in our measurements because screens are always trying appear “crisp” by approximating the position of rough edges on screen. It won’t be pixel perfect, but it’ll be really close. For example, the real difference between 1.4375rem and 1.43rem is only a very neglible value of .12 of a whole pixel. With this understanding, we are free from a somewhat common problem:

pixel-meme

Scaling Relative Units

Maintaining a codebase adhering to the design of guiding the browser to be decisive allows for less headaches. It’s widely common to use media queries to set breakpoints using pixel measurements— but our browsers can never be pixel perfect, so why try? Instead, we should use proportionality as a base for our design.

This is exactly how browsers and our Operating Systems can delegate a default font size. Our Operating Systems use default (base) relative value to increase the font-size of all applications once the user has configured their preference via a slider or a number value. This is the same principle we can use to scale our relative units.

:root {
  font-size: 1rem;
}

@media (min-width: 768px) {
  :root {
    font-size: 150%;
  }
}

@media (min-width: 1024px) {
  :root {
    font-size: 200%;
  }
}

Above we are using media queries to adhere to our principle of guiding the browser. Instead of outright being explicit with px measurements, we are instead scaling our values accordingly. Had we decided to use px, our scaling would be explicit everytime, that’s no fun. We would then have to change our px values everytime we change our font-size value. Maintaining a codebase full of pixel breakpoints is hard, primarily because it goes against the grain of css of building exceptions to the rule of the cascade. In our the anti-case, by not using rem as a default. And if sub-pixel rendering is present (as with most displays) then what makes a pixel value “pixel perfect” is a shifting target. That itself is relative by nature.

Proportional Viewports

The beauty and majesticness (is that even a word?) of rem with relative units with the css calc() function. Our vw and vh measurements can replace breakpoints. When we work with breakpoints, we are working with the width dimension of the display, except whereareas we used px measurements, we could instead use vw and vh to scale our rem values accordingly.

:root {
  font-size: calc(1rem + 5vw);
}

Our calc() function can perform math operations. For us, this means proportional viewports. 5vw would be 5% of the browser’s current total width (horizontal). While 5vh would be 5% of the browser’s current total height (vertical).

The above css is composed of two parts. The first says “our minimum font-size is 1rem”, or our default base font-size value. Our 5vw is saying “increase our default font-size (1rem, which is 16px) by 5% of the browser’s current total width”.

This means that if our browser is 1920px wide, our font-size would be 1rem + 5% of 1920px, which is 1rem + 96px. Our total, would be 1rem (16px) + 96px = 7rem (112px). When our browser is only 720px wide, then our font-size would be 1rem + 5% of 720px, which is 1rem + 36px. Our total, would be 1rem (16px) + 36px = 3.25rem (52px).

An Elegant Upgrade:

.my-element {
  font-size: clamp(2rem, calc(1rem + 5vw), 10rem);
}

With clamp our font-size becomes truly responsive. Our CSS above is saying “the minimum value we will accept for our font-size is 2rem. Our maximum value is 10rem (160px). We can use these values to scale our rem size accordingly to be truly responsive.

Other Measurements

Earlier in the article a few alternative measurements were mentioned. Our em for example, can serve to compliment rem measurements. If I wanted to make a specific rem element bigger, em measurements conjoin to that capacity.

h3 {
  font-size: 2rem;
}

h3 expand {
  font-size: 1.5em;
}

Our em measurement is adding onto the font-size of the parent element. In this case, our h3 element. Our h3 has a font-size of 2rem (32px). If we instead changed our css to use rem as part of the expand class, there would be no change. The inheritance of the em unit is special. Above we are using rem for our block-level element. For an inline element, like a span, we should opt to use em instead.

One common use case for em is with SVGs, since text next to an SVG most repeatedly serves to compliment it.

ch and ex are like all the units discussed, relative measurements. ch is characterized to be the width of a single character. What is one ch equal to? The width of a 0. While ex is the height of a 0. ex is the height of the “0” character.

The purpose of ch is usage with text content with our inline (horizontal) flow. Then, working with max-inline-size to specify how much characters to fit within the line.

p {
  max-inline-size: 60ch;
}

The above css is saying “our paragraph element can only be 20 characters (0s) wide”.

Ending Thoughts

Proportional design as principle works for our maintainability, our designs, and a more accessible web. Browsers don’t need to be pixel perfect, and neither should we. We should use relative units to scale our designs accordingly to promote a more accessible and predictable web.

Resources

CSS Units

Inline elements

Media Queries

Sub-Pixel Rendering

24a11y CSS Units