In the second chapter of “Working with Relative Units”, Keith J.Grant’s good BOOK CSS in Depth has been translated. The explanation and examples of relative units in the book are quite comprehensive. After reading it, I found that I do not understand the relative units of CSS, and I hope to share with you, so I have this translation series. (for errata or translation suggestions, welcome Github PR ^_^)

Don’t say you Know CSS relative Units

  1. How to use EM more happily
  2. How to Use REM more happily [this article]
  3. Application of viewport related units
  4. None unit number and row height
  5. CSS Custom attributes

Corresponding chapter contents of this paper:

  • 2.2 em and rem
    • 2.2.2 Rem for font size
      • Availability: Use relative length units for font size
  • 2.3 Stop using pixel thinking to think
    • 2.3.1 Set a reasonable size default
    • 2.3.3 Make the panel “responsive”
    • 2.3.3 Resize a Component

2.2 em and rem

2.2.2 Rem for font size

When the browser parses an HTML Document, it creates a collection that represents the elements of the page, called the DOM (Document Object Model). Tree structure, each node represents an element. < HTML > is the top-level node (the root node), followed by its children and , followed by their children, descendants, and so on.

The root node is the ancestor of all other elements in the document. It has a special pseudo-class selector (:root) that can be represented in stylesheets. Using the type selector HTML with the class name, or using the tag selector directly, the effect is the same.

Rem is short for Root EM. Rem is associated with the root element and does not depend on the current element. No matter where you use this unit in the document, 1.2rem is the same calculated value, equal to 1.2 times the font size of the root element. The following example code declares the size of the root element and uses REM to declare the size in a nested unordered list.

[Snippet 2.10 uses REM to declare the size]

:root {                    1
  font-size: 1em;          2
}

ul {
  font-size: .8rem;
}
Copy the code
  • Pseudoclass :root is equivalent to an HTML selector
  • 2. Use your browser’s default font size (16px)

In this example, the root size is the browser’s default size of 16px (1em of the root element equals the browser’s default size). The size of the unordered list is 0.8rem and the result is 12.8px. Because this is only relevant to the root element, even though you nested the list inside the list, the size of the nested sublist remains the same.

Availability: Use relative length units for font size

Some browsers give the user two ways to customize the text size: zooming and setting a default font size. By pressing Ctrl+ or Ctrl-, the user can zoom the page. This visually enlarges or shrinks the text or image (or indeed all elements) of the entire page. In some browsers, this change only applies to the current TAB page and is temporary, and does not affect newly opened tabs.

Setting the default size is a little different. Not only is the entry to the Settings hard to find (usually on the browser Settings page), but the Settings are permanent until the user restores the default values. Note that this setting does not work with font sizes defined using PX or other absolute units. Because the default size is necessary for some users, especially those with low vision, you should define the size in relative units or percentages.

Rem simplifies much of the complexity that EM brings. In fact, REM provides a relatively unit-neutral solution between PX and EM, and is much easier to use. So, does that mean you should use REM for all elements, leaving out the other units of length? Of course not.

In the CSS world, the answer is usually, it depends. Rem is just one part of your toolbox. An important part of mastering CSS is learning to distinguish which tools to use in which scenarios. My choice is to use REM for font size, PX for border, and em for other metrics like padding, margin, border-radius, etc. However, when it is necessary to declare the width of the container, I prefer to use percentages.

This makes the size predictable, and you can also use em to scale the padding and margin of an element when other factors affect its size. Using pixels on a border is appropriate, especially if you want a nice line. This is the ideal way for me to use different units for different attributes, but again, these are tools, and different tools may work better in certain scenarios.

prompt

When in doubt, use REM for font size, PX for border, and em for most other attributes.

2.3 Stop using pixel thinking to think

Defining the size of the root element of a page as 0.625em or 62.5% has been common usage in recent years, and is a pattern, or rather, an anti-pattern.

[Snippet 2.11 Anti-pattern: Define font size to 10px globally]

html {
  font-size: .625em;
}
Copy the code

I don’t recommend it. This reduces the browser’s default font size from 16px to 10px. The nice thing about this is that it simplifies the calculation. If the designer tells you the font size should be 14px, you can easily calculate 1.4rem, since we’re still using relative units.

This may seem convenient at first, but there are actually two problems with this approach. First, it forces you to write a lot of repetitive style code. 10px is too small for most text, and you’ll need to overwrite it back and forth throughout the page. You’ll find yourself declaring a 1.4rem font size for paragraphs (

) and a 1.4rem font size for links for navigation (

The second problem is that when you do this, you’re still thinking in pixels. While you’re writing 1.4rem in code, in your head you’re actually thinking 14px. In responsive Web development, you should learn to live with “fuzzy” values. It doesn’t matter how many pixels 1.2em actually equals, just that it’s a little bit bigger than the inherited font size, and that’s good enough. And if it’s not what you want on screen, change it. It takes time and trial and error, but the truth is we need to do the same with PX. (In Chapter 13, we’ll have more specific ways to optimize this implementation.)

When using EM, it’s easy to get caught up in the confusion of, what does this value translate to in pixels? Especially for font size. You keep multiplying and dividing em values, and you get crazy fast. Instead, I want you to take on the challenge of trying to get into the habit of using EM first. If you’re used to working with pixels, the transition to EM takes some time and practice, but trust me, it’s worth it.

This doesn’t mean you’ll never use pixels again. If you’re working with a designer, you might want to communicate with more precise pixel values, and that’s fine. At the beginning of the project, you need to declare a base font size (usually the usual font size for headings or annotations). It is often easier to describe size using absolute values.

When switching to REM, there is a calculation, so let the calculator do the work (usually I do it in Spotlight by pressing CMD + space on my Mac). Start by declaring the root size on the root element, and from there, using pixels should be the exception, not the norm.

In this chapter, I will continue to talk about pixels. This will help me explain how relative units work, and it will also help you get into the habit of calculating em values. After this chapter, I’ll mostly use relative units to talk about font sizes.

2.3.1 Set a reasonable size default

Let’s say you want to set the default font size to 14px. Setting 10px as a base value and overwriting it on the page is not recommended. Instead, you should declare a value directly on the root element. In this code snippet, the target size is inherited, the browser default is 16px, so 14/16 = 0.875.

Add the following code to the top of a new stylesheet, and we’ll add additional code on top of it. This sets the default font size for the root element (< HTML >).

[Snippet 2.12 Setting the correct default font size]

:root {1 font: 0.875em; 2}Copy the code
  • 1 or use the HTML selector
  • 2 14/16 (expected value px/inherited value px) equals 0.875

Now, your expected base size of 14px is valid for all elements on the page, and you don’t need to redeclare it anywhere else. All you need to do is change the font size where the design is different, such as the title.

Let’s create a panel like figure 2.7. The panel you created is based on 14px font size and uses relative units.

[Figure 2.7 panel using relative units and inheritance type]

Here is a template to add to your page.

[Template for snippet 2.13 panel]

<div class="panel">
  <h2>Single-origin</h2>
  <div class="panel-body">
    We have built partnerships with small farms around the world to
    hand-select beans at the peak of season. We then carefully roast
    in <a href="/batch-size">small batches</a> to maximize their
    potential.
  </div>
</div>
Copy the code

The next piece of code is styled. You’ll use em for the padding and border-radius, REM for the title size, and PX for the border. Add the following code to your stylesheet.

[Snippet 2.14 using panels of relative units]

.panel { padding: 1em; 1 border - the radius: 0.5 em. 1 border: 1px solid# 999; 2} .panel > h2 { margin-top: 0; 3 the font - size: 0.8 rem. 4 font-weight: bold; 4 text-transform: uppercase; 4}Copy the code
  • 1 Use em for padding and border-radius
  • Define a thin border with 1px
  • Remove the extra space above the panel. See chapter 3 for more explanation
  • 4 Use REM to control the font size of headings

This code adds a thin border to the panel and defines the style of the title. I want the title to be small, bold and all caps. (You can make the size larger or use different typography depending on your design.)

The second selector > is a direct descendant Combinator that represents the sub-element H2 under the panel. A more complete index of selectors and combinatorial selectors can be found in Appendix A.

In snippet 2.13, I added a panel-body class to body for a clearer look, but you’ll notice that you don’t need it in your own code. Because this element inherits the size from the root element, it already looks like what you want it to look like.

2.3.3 Make the panel “responsive”

Let’s look at this a little bit more deeply. You can change the base font size by adding a media query based on the screen size, which allows the panel to vary in size depending on the screen size. (See Figure 2.8)

[Figure 2.8 Responsive panels in different screen sizes: 300px (top left), 800px (top right), 1440px (bottom)]

Media Query — styles are declared using the @media rule, which triggers style controls for different screen sizes or media types (such as printers or monitors). This is a key element of responsive design. See this example in snippet 2.15 for more detail, and I’ll cover the topic of media queries in more detail in Chapter 8.

To achieve this effect, change your style code to this.

[Snippet 2.15]

:root {1 font: 0.75em; 1} @media (min-width: 800px) {2 :root {2: font-size: 0.875em; 2 } 2 } 2 @media (min-width: 1200px) { 3 :root { 3 font-size: 1em; 3} 3}Copy the code
  • 1 works on all screens, but will be overwritten on larger screens
  • Override the default style code for screens wider than 800px
  • For screens wider than 1200px, overwrite the above two styles

The first set of style rules declares the default font size for small screens, which is what we want to see on smaller screens. Then use the media query to override the default code by incrementing the size step by step with 800px and 1200px as the two watersheds.

Using these font sizes for the root element of the page, the em and REM values are redefined in response to changing the entire page. Although you haven’t made any changes to the panel directly, it is now responsive. On a small screen, such as a mobile phone, the font size will be rendered even smaller (12px). Then, on the larger screen, the size of the component will be enlarged to 14px and 16px for sizes larger than 800px and 1200px, respectively. Change your browser window and see how the components change.

If you use strictly relative units like this throughout the page, the entire page will zoom in and out depending on the window size. This will be an important part of your responsive strategy. The two sets of media query declaration code above can help you save extra code for using media queries in other parts of the page. However, if you declare the font size in pixels in an element, it won’t have any effect.

Similarly, if your boss or client decides that the size of your site is too small or too large, you can always change one line of code to affect one global element, and the change will affect the rest of the page with no effort.

2.3.3 Resize a Component

You can also scale a separate component on the page by using EM. Sometimes, you may need a larger version of a component on the interface. To do this on our panel, first you need to add a class name large to the panel:

.

In Figure 2.9, we see a comparison of the normal and large panels. The effect is similar to a responsive panel, but both sizes can be used on the same page.

[Figure 2.9 Normal size panel and large panel on a page]

Let’s make some minor changes to the panel size declaration. You’re still using relative units, but you need to adjust their base values. Font size: 1rem for the parent element of each panel. This means that no matter where the panel is used, the font size of each panel is a fixed value.

Second, use em to re-declare the size of the title, not REM, so that the title can be associated with the parent element size 1rem that was just declared. Here’s the code. Update your stylesheet code.

[Snippet 2.16 Creating a large version of the panel]

.panel {
  font-size: 1rem;               1
  padding: 1em;
  border: 1px solid # 999;Border - the radius: 0.5 em. } .panel > h2 { margin-top: 0; The font - size: 0.8 em. 2 font-weight: bold; text-transform: uppercase; }Copy the code
  • 1 Specify the font size for the component declaration
  • The size of other elements is associated with the size of the parent element using em

These changes don’t seem to affect the style of the panel, but now you’re ready to make a large panel with only a small line of code modification. All you need to do is rewrite the parent element size to a value other than 1rem. Because other elements are evaluated depending on the font size of the parent element, changing it will change the relative size of the entire panel. Add the next CSS snippet to your stylesheet and define a large panel.

[Snippet 2.17 Enlarging the entire panel with one line of code]

.panel. Large {1 FONT: 1.2rem; }Copy the code
  • The composition selector points to an element that has both the Panel class and the Large class

Now you can add class=”panel” to normal panels and class=”panel large” to large panels. Similarly, you can define a smaller version just by setting the size of the parent element smaller than 1rem. If the panel is a more complex component with multiple font sizes or padding, it can be resized with a single declaration, as long as all child elements are declared using EM.


Don’t say you Know CSS relative Units

  1. How to use EM more happily
  2. How to Use REM more happily [this article]
  3. Application of viewport related units
  4. None unit number and row height
  5. CSS Custom attributes

Chapters:

  • 2.1 Magic relative to unit values
    • 2.1.1 The struggle of Pixel-perfect Design
    • 2.1.2 The end of the perfect pixel web
    • Pixel, Point, and PC (PICA)
  • 2.2 em and rem
    • 2.2.1 Using em for Font size
      • When we declare font size and other attributes in an element using em
      • Type shrinkage problem
    • 2.2.2 Rem for font size
      • Availability: Use relative length units for font size
  • 2.3 Stop using pixel thinking to think
    • 2.3.1 Set a reasonable size default
    • 2.3.2 Make this panel “responsive”
    • 2.3.3 Resize a Component
  • 2.4 Viewport-relative Units
    • CSS3
    • 2.4.1 Using VW on font size
    • 2.4.2 Using calc() on font size
  • Unitless number and line height
  • 2.6 Custom Properties (also called “CSS variables”)
    • 2.6.1 Dynamically Changing the Value of a user-defined Attribute
    • 2.6.2 Changing the value of a custom attribute through JavaScript
    • 2.6.3 Exploring custom attributes
  • conclusion

Copyright Information:

Book: CSS in Depth Chapter: Working with Relative Units


The author @Yuying Wu, front-end enthusiast/encourager/New Zealand working holiday/poop collector. Currently, I am working in B2B front-end team of a large e-commerce company.

Thank you for reading this. If you have any questions or suggestions, please leave a comment below.

If you like the front end as much as I do, like to play with independent blogs or cutting-edge technology, or have any career questions, please follow me and communicate with me.

Zhihu ID: @yuying Wu Github: Yuying Wu