首页  >  文章  >  web前端  >  REM 与 PX 关系:如何编写更易于访问的媒体查询

REM 与 PX 关系:如何编写更易于访问的媒体查询

PHPz
PHPz原创
2024-08-27 18:01:11825浏览

我们是开发人员。我们希望开发响应速度最快的布局。我们希望适应不同的设备、分辨率和用户设置。我们希望在所有样式表中使用一致的单位。我们希望尽可能少地做数学运算。

我们什么时候想要这个?现在!
我们需要知道什么?很多东西!
我们该怎么做呢?具有自定义 SASS 函数!

通过使用 SASS 函数,我们可以通过了解和考虑更多用户的系统和浏览器级别设置来容纳更多用户。我将讨论 rem 值与像素值的关系以及可能影响它们之间关系的因素。 1rem 几乎总是以 16px 开始,但用户可以通过多种方式更改它。我们稍后将编写的这个 SASS 函数非常有用,因为它可以应用于更大的项目,并且可以逐步引入到您现有的项目中。

背景

促使我研究这个主题的是 Hajime Yamasaki Vukelic 的文章《没有桌面屏幕这样的东西》,他对响应式设计的看法是“响应性不是一组简单的任意屏幕宽度......响应能力与稳健性有关:在页面开始崩溃之前,您可以拉伸或挤压页面多少”。 Hajime 谈到他的父亲如何以 400% 的正常速度浏览网页。虽然这看起来像是一种边缘情况,但了解用户缩放显示的不同方式以及我们正在编写的样式如何受到这些设置更改的影响非常重要。

缩放显示

让我们从尽可能小的开始,准确理解像素是什么。对于开发人员而言,有两种类型的像素:设备像素是给定屏幕上的光点数量,CSS 像素是测量单位。设备像素通常不等于 CSS 像素。了解两者之间的差异非常重要,这样我们就可以确定哪些设置会影响每个值。

用户可以像 Hajime 的父亲一样通过多种方式更改屏幕上内容的大小。用户缩放显示的最常见方法:

  • 更改显示分辨率(系统设置)
  • 放大浏览器选项卡(在 Mac 上按 ⌘ 和 +,在 Windows 上按 Ctrl 和 +)
  • 增加浏览器设置中的字体大小。

第一个和第二个选项,更改显示分辨率和缩放浏览器,本质上是做同样的事情。这两种方法都会缩放 CSS 像素,以便每个 CSS 像素占用更多的设备像素。在这种情况下,我们的布局都按比例缩放。 1rem 仍等于 16px,但每个 CSS 像素占用更多设备像素。要测试这一点,您可以放大浏览器选项卡,直到触发“移动”布局。此设置可以快速测试,通常不会造成太大问题。

更改浏览器字体大小将导致最大的变化。默认情况下,浏览器的设置为“medium”,在 Chrome 中意味着 1rem 为 16px。当用户增加字体大小时,1rem 的值将增加,但其他值不会缩放。 1rem 将等于更多的 CSS 像素,因此会占用更多的设备像素。在 Chrome 上,将字体大小设置为“非常大”时,1rem 将等于 24px。 CSS 像素的大小保持不变,只是根字体大小发生了变化。任何引用根字体大小的值都会受到影响。

The REM to PX relation: how to write more accessible media queries

在您的代码中,如果您混合使用像素和 rem 值,那么您可能会开始出现布局问题,因为 rem 值会缩放,但像素值将保持不变。上图显示了一个简单的示例,说明当文本设置为 rem 值,而最大宽度、列宽和填充设置为像素值时,布局会发生多么剧烈的变化。响应式布局应根据根字体大小进行相应缩放。

媒体查询的问题

这通常是我们编写媒体查询的方式:

@media (min-width: 1000px) {
    ...declarations here
}

由于我们试图响应并适应所有用户的设置,因此我们希望尽可能使用相对单位。让我们在媒体查询中使用 rem 值而不是像素:

@media (min-width: 62.5rem) {
    ...declarations here
}

使用默认浏览器设置,1000px 等于 62.5rem
1rem = 16px
1000px / 16px/rem = 62.5rem
这看起来就像每次我想写一个相对单位时都必须做的数学运算。我们一开始就说过我们不想做数学。

我们都见过一个常见的修复方法,即 1rem = 10px。这通常是在设置项目的样板文件时完成的。您可以通过定位 html 选择器来覆盖根元素上的根字体大小:

html {
    font-size: 62.5% 
    // this is math 
    // but it only needs to be done once for the whole project 
    // so I'll let it slide
}

Now any time we want to convert a pixel value from the design to a rem value in our code we just have to carry the decimal one place.
1rem = 10px
To get a value of 1000px, we use 100rem. This still involves math but is fairly minor.

Now, when using a rem value, we can safely assume that 1rem will be 10px.
Right?
Yes?
Example?
No need. We know it is true. We have used rem for widths, heights, paddings, margins, translates or any other declaration without any issue. But…will there be any issue using it in the condition for a media query?

@media (min-width: 100rem) {
    // does is trigger at 1000px as expected?
    ...declarations here
}


Open the example in a new window and play with the width of the viewport. When the “desktop” media query triggers then the background will turn blue.

What is happening?

The values for a media query are calculated before any other rules are set, so the ruleset we applied to the html element in the start of our project will not be applied in the condition of the media query. According to this media query, 1rem is still equal to 16px. We expected 100rem to be 1000px but it ended up being 1600px.

If you change the browser font size to “very large” and refresh the example, you will notice that 1rem = 15px and the 100rem media query won’t trigger until 2400px. If your monitor isn’t wide enough to see that change happen, zoom out on the browser with ⌘/Ctrl and + .

The condition for the media query is not scaling consistently with the browser’s desired font size.

  • Font size “Medium”:
    • 1rem = 10px
    • Media query: 100rem = 1600px
    • rem to px ratio: 0.0625
  • Font size “Very Large”:
    • 1rem = 15px
    • Media query: 100rem = 2400px
    • rem to px ratio: 0.0416666667

For content and layouts to scale consistently, we need the rem to px ratio to always remain the same.

REMPX()

This has taken a long time to get to even suggesting a solution to a problem that we maybe didn’t know we had.

Let’s create a custom SASS function that will allow us to write our code in pixel values and be rendered as rem values. I came across this function on a legacy project at work but I believe it was heavily inspired by this quick article: Convert pixel values to rem, Sass style, by Bhargav Shah. Since this article was written, CSS introduced its own rem() function which calculates the remainder of a fraction so instead we’ll name our function rempx().

$html-font-size: 16px;

@function stripUnit($value) {
    @return $value / ($value * 0 + 1);
}

@function rempx($pxValue) {
    @return #{stripUnit($pxValue) / stripUnit($html-font-size)}rem;
}

//implementation:
.image {
  height: rempx(300px);
}


Open the example in a new window and play with the width of the viewport and change the browser font size (refresh the page after you update the font size).

Notice how after we change the browser font size to “very large” (after a page a refresh), the 1rem square becomes larger and you can see that 1rem is equal to 24px.

When used in the condition of a media query, a rempx value will scale accordingly with the browsers font size. With the font size set to “very large”, the desktop layout rempx(1000px) will trigger at the viewport width of 1500px. The scaling of the content and layout behave the same way as when we zoom in on the browser.

A huge benefit of writing all your units with the rempx() function is you can write pixel values from the designs and then it renders it as a rem value in the browser. This function is very easy to introduce to a project or include in the boilerplate of your future projects.

Wrapping up

This function can be written once and used everywhere.
We can take the pixel values from the design and generate a scalable rem value.
Our media query triggers relative to the root font size.
All our layout and content scales consistently.
No math necessary.
Better user experience across a wider range of user settings.
Better user existence overall.
Better developer existence overall.
This function improves our existence.

Further reading

There’s No Such Thing as a Desktop Screen Hajime Yamasaki Vukelic

Zoom, zoom, and zoom: the three types of browser (and CSS!) magnification, Miriam Suzanne

Convert pixel values to rem, Sass style, Bhargav Shah

以上是REM 与 PX 关系:如何编写更易于访问的媒体查询的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn