Say goodbye to fixed font sizes: CSS uses relative units to improve web accessibility and compatibility

In the world of web development, there are many misconceptions circulating that persist even when they've been refuted many times. "External links should always open in new tabs" is a good example . CSS Tricks explained this in detail (in short: mostly wrong) almost a decade ago, but it still seems to be around in some corners.

 Case in point: the idea that there is no functional distinction between , ,  or   units  in CSS is a misconception I hear over and over again, so I thought I'd post here to address it. pxemrem

Let's be very clear: the units you use in CSS absolutely matter. And should be avoided as much as possible when   . font-size px

What units are we talking about and what do they do?

Before we get into why using  as  should be avoided , let's make sure we're all clear which units we're talking about, and how they behave in general. pxfont-size 

px

px is short for pixel...although it's not really a pixel in most cases anymore. 1024×768In an era when  monitors were usually a relatively predictable low-resolution ratio of pixels, such as , 1px was usually equal to one actual pixel on the screen.

Screens display images using dots of colored light called pixels. A pixel is a single point of colored light on a display; the smallest possible "point" that the hardware is capable of representing. This is what I mean in this section as a "literal", "actual" or "device" pixel; a pixel in the physical world.

However, when high-resolution (sometimes called "retina") screens came along and devices started packing more pixels into a smaller space, those physical device pixels became tiny. Browsing the web on a high-res screen,  1px it's going to be very difficult to even read anything if the in CSS still corresponds to a literal device pixel, because the pixels themselves are rapidly shrinking. After all, modern smartphones have even higher resolutions than HDTVs.

So now,  1px usually the size corresponds to the enlarged "scaled" pixels, not the literal pixels on the actual hardware. In our CSS,  1px things may take up multiple physical hardware pixels, and we don't have any pure CSS way to specify a literal device pixel. But that's okay because they're usually too small and we don't want to deal with them.

An example: the pixels on the iPhone 14 Pro are so tiny that 16px is literally the size of a device pixel about the size of a typographic font at a 2pt font size. Good thing the browser scales them for us!

Most of the time, these don't really matter in the context of this discussion, but I think it's good to know. The important part is: 1px Equal to whatever the browser sees as a single pixel (even if it's not really a pixel on a hardware screen).

em and rem

This brings us to  em and  rem , which are similar to each other. Moving on to a tidbit that isn't strictly related, but still fun: "em" is a typographical term that actually predates computers by decades. Typographically, one  em is equal to the current font size.

If you set the font size to  32pt("pt" is another old typography term still sometimes used), then  1em yes 32pt. If the current font size is  20px then  1em = 20px.

On web pages, the default font size is  16px . Some users never change the default, but many do. But by default,  both 1em and  1rem will be equal to 16px.

"Em" originally referred to the width of the "M" character, which is where the name comes from. But now it refers to the current font size, not the dimensions of a specific glyph.

Difference Between EM and REM

To differentiate the two: 1rem always equal to the browser's font size, or more precisely the font size of the html element. rem stands for "root em", and the root of a web page is <html>the tag. Hence,  1rem =  document  font size. (By default this is  16px , but can be overridden by the user.)

On the other hand, emis the font size of the current element. Look at the CSS below:

.container {
  font-size: 200%;
}

p {
  font-size: 1em;
}

Taking into account the above CSS,  the paragraphs inside the element will be doubled in size. This is because it   means "current font size", inside , it is .  (default is  ) . .container1em.container 200%1em × 200% = 2em 32px

However, paragraphs outside the element will still be   at the normal font size (the default   ). .container 1em16px

em If we change to  in the CSS above  rem , then the font size of all paragraph tags will always be the browser's default size, no matter where they are.

font-size: 1em is equivalent to font-size: 100% . em and % units are not always equivalent in other contexts; for example,  width: 1em em and  width: 100% % are likely to be very different, since percentages are then based on the parent container's width rather than its font size. However, as far as the font-size property is concerned,  % and  em are the same.

in conclusion:

  • 1em is the font size of the current element.

  • 1rem (root em) is the font size of the document (i.e. the browser's font size).

Ok, so that's what units are and where they come from. Now let's answer why it matters which unit you use.

why it all matters

Again, the misconception is that since  1em and  16px are equal, it doesn't matter which unit you choose. This seems reasonable; if  16px = 1rem , then it doesn't seem to matter which way you choose to enter.

Remember,  em and  rem are relative; by default, they are both (ultimately) based on the browser's font size.

2rem Twice the browser font size; 0.5rem half it, and so on.  So if the user changes their preferred font size, all text on the site changes accordingly, as it should, if using  em and  . Still twice that font size; still half that.rem  0.5rem 

Values , by contrast, are static. 2  just works  regardless of the font size of the container, browser or user . When setting a static pixel value, it overrides that selection and uses the exact value specified, regardless of the user's font preference size. px 0px20px 

Critically speaking, this means that if your stylesheet usage  px is set anywhere  font-size , any text based on that value will not be able to be changed by the user.

That's a very bad thing. It is inaccessible and may even prevent someone from using the site at all.

So while there may be valid use cases for this behavior, it's definitely not the default behavior you want.

This is also a very good reason to avoid setting font sizes using viewport units such as vw or vh . They are also static and cannot be overridden by the user. At most,  calc(1rem + 1vw) a value like this is probably acceptable since it's still included  rem as a base. Even so, I'd still recommend using or media queries to set min and max values, as screen sizes are often way beyond what we expect or test for. clamp() 

Difference beyond font size

Ok, now let's talk about  how  andfont-size changes when we don't deal with  properties  in particular .px em / rem 

Developers usually test by zooming the page, which I think is the source of the misconception at the center of this article. When you zoom, everything gets scaled (zoomed in or out), in which case it usually doesn't matter what you choose  or   /   as your CSS units. As far as scaling is concerned, both behave the same way. And most developers with good eyesight probably won't realize there's more to it. However, the tricky questions are: pxemrem

 Behavior differs from   and  font-size even px beyond   .emrem

px Units are still tied to scaled values ​​of pixels on the screen. em and rem  are tied to the font size of the document, not the zoom or scale of the page.

For a demonstration, take a look at this CodePen:

HTML CSSResult Skip Results Iframe
EDIT ON
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nam eum aliquam eveniet.</p>
<p>Sapiente delectus in ab excepturi, commodi placeat quaerat saepe voluptas sunt numquam.</p>
<p>Rerum veniam, quidem voluptatibus deleniti nihil consequatur blanditiis explicabo eum quos. Nam.</p>
<p>Natus necessitatibus delectus neque tenetur sint illum obcaecati similique sequi doloribus eligendi?</p>
<p>Eos quidem iure debitis dolorum repellendus ab incidunt ipsam suscipit, autem consequuntur?</p>
p {
  border-bottom: 2px solid black;
  margin-top: 0;
  margin-bottom: 20px;
}

We have several paragraphs with  2px borders at the bottom of each paragraph and  margins between them. Note that we use   units for both. 20pxpx

If you zoom in or out, the size and distance of elements remain relatively unchanged. That is: the more you zoom in, the thicker that line gets, and the more space there is between paragraphs.

For your convenience, here's a screenshot showing the same pen at 400% zoom . The text, lines, and spacing are all 4 times larger; they remain the same size relative to each other:

When it comes to scaling,  there is no real difference between  px , ,  em or rem . But zooming isn't the only way users can make a site more usable.

As mentioned earlier, users can also specify a default and/or minimum font size. When they do, the features start to diverge.

In the screenshot below, I've set Firefox's default font size to 64px  . take a look:

Compare the text in the screenshot with the text above it. Note that this time, the lines are not getting thicker and the margins between paragraphs are not increasing proportionally. Only the text itself gets bigger. Since both border width and margin are set in px, they stay the same and don't scale.

But notice that if you change the values ​​in CSS  px to the corresponding  rem values, you will find that the lines and spacing are indeed bigger! (zh-Hans)

So, the summary here is:

  • The px value doesn't scale when the user changes the font size.

  • The em and rem values ​​scale proportionally to the font size.

If you want an interactive demo that ties all of this together, check out the resulting CodePen; adjust the sliders at the top to see how changing the document font size affects various elements, based on the CSS units they use. https://codepen.io/collinsworth/pen/KKepeMQ

which one to choose

So, knowing  em that  rem sums scale with font size, but  px values ​​don't, what do we do? Should we never use  px it?

While I think you'll probably be fine if you choose this path, I still think px has a purpose.

We know that px the value , which means that pixel units are actually a good choice for certain aesthetic elements. Maybe we have some spacing that we don't want to get bigger when the font size gets bigger. (Maybe it doesn't make sense to allow it to scale to a larger size if it's a big chunk of negative space by default.)

Maybe there's some border size we don't want to change, or a decorative element on the page created with CSS that doesn't look good at larger font sizes. Maybe we don't want the padding to bloat as the font size increases. In all these cases, px is still a good choice.

Personally I recommend using  rem to set all the sizes. I only add em's in things where you want to be proportional to the current font size (for example, in the case of some text where an icon next to it should be exactly the height of the character, and have half a character on one side)  . I wouldn't use it anywhere  px except for design elements that explicitly don't want to scale with font size.

Never  px set font-size  in units unless you are very sure what you are doing, how it will behave, and whether it will still be accessible when you do.

Important note about media queries

For the same reasons as all of the above, it's important to avoid  @media using in queries  px ; it will work fine when the user zooms, but use  px a media query that will fail when the user sets a larger font size themselves.

@media (min-width: 800px) {
  /* Changing font size does NOT affect this breakpoint */
}

@media (min-width: 50rem) {
  /* Changing font size DOES affect this breakpoint */
}

This is because as the font size increases 50rem it becomes a different value based on the user's preference, while  800px it doesn't .

Chances are, when we write CSS for larger breakpoints, we think there is enough screen real estate for the element to expand. This may not be the case if the user has set a very large font size, setting the media query to  rem not  px helps us avoid this assumption and respond to the user's preference.

I ran into this problem on this site; I set all breakpoints on px . However, when I make the default font size larger, my media queries become unresponsive because they still only look at the pixel width of the screen. So I still have a tiny sidebar stuffed with huge illegible text because I'm not taking user preferences into account. Immediately after that, I changed to rem and the problem was resolved.

In short: In media queries, unless you are sure you know how setting your own font size in the browser will affect your users, definitely avoid it  px .

Guess you like

Origin blog.csdn.net/qq_48652579/article/details/131317361