告别固定字体大小:CSS使用相对单位提升网页可访问性和兼容性

在 Web 开发领域中,有很多误解流传,即使它们被反驳了很多次也仍然存在。"外部链接应该总是在新标签页中打开" 就是一个很好的例子。CSS Tricks 在将近十年前就对此进行了详细的解释(简而言之:大多数情况下是错误的),但它似乎仍然在某些角落中存在。

案例证明:在CSS中, px , em 或 rem 单位之间没有功能上的区别的想法是一个我一遍又一遍听到的误解,因此我想在这里发帖来解决这个问题。

我们要非常清楚:在CSS中使用的单位绝对很重要。并且在设置时 font-size 应尽可能避免使用 px 。

我们在谈论什么单位,它们是做什么的?

在我们讨论为什么应该避免使用 px 作为 font-size 之前,让我们确保我们都清楚我们正在谈论哪些单位,以及它们的一般行为。

px

px 是像素的缩写……虽然现在大多数情况下它不再是一个真正的像素。在显示器通常是一个相对可预测的低分辨率像素比例,比如1024×768的时代, 1px 通常等于屏幕上的一个实际像素。

屏幕使用称为像素的彩色光点阵来显示图像。一个像素是显示器上的一个彩色光点;硬件能够呈现的最小可能的“点”。这就是我在本节中所说的“字面上的”、“实际的”或“设备”像素;物理世界中的一个像素。

然而,当高分辨率(有时称为“视网膜”)屏幕出现时,设备开始将更多的像素压缩到更小的空间中,这些物理设备像素变得非常微小。在高分辨率屏幕上浏览网页,如果CSS中的 1px 仍然对应于一个字面设备像素,那么甚至阅读任何内容都将非常困难,因为像素本身正在迅速缩小。毕竟,现代智能手机的分辨率甚至比高清电视还要高。

所以现在, 1px 通常对应于放大的“缩放”像素的大小,而不是实际硬件上的字面像素。在我们的 CSS 中, 1px 的东西可能会占用多个物理硬件像素,而我们没有任何纯 CSS 的方法来指定一个字面设备像素。但这没关系,因为它们通常太小了,我们不想去处理它们。

一个例子:iPhone 14 Pro 上的像素非常微小,16px 在字面上的设备像素大小大约相当于2pt字号的印刷字体大小。好在浏览器为我们缩放了它们!

大多数情况下,这些并不在本讨论的语境中真正重要,但我认为了解这些还是很好的。重要的部分是:1px 等于浏览器视为单个像素的任何内容(即使在硬件屏幕上它不是真正的像素)。

em 和 rem

这就带我们来到了 em 和 rem ,它们彼此相似。继续讲述不严格相关但仍然有趣的小知识:"em" 是一个排版术语,实际上比计算机早了几十年。在排版上,一个 em 等于当前字体大小。

如果你将字体大小设置为 32pt(“pt”是另一个仍然有时使用的旧排版术语),那么 1em 就是32pt。如果当前字体大小为 20px ,那么 1em = 20px

在网页上,默认字体大小为 16px 。一些用户从不更改默认设置,但许多人会更改。但默认情况下, 1em 和 1rem 都将等于 16px 。

“Em” 最初是指 “M” 字符的宽度,这也是名称的由来。但现在它指的是当前字体大小,而不是特定字形的尺寸。

EM 和 REM 之间的区别

为了区分这两者:1rem 始终等于浏览器的字体大小,或者更准确地说是 html 元素的字体大小。rem 代表“根em”,而网页的根是<html>标签。因此, 1rem = document  字体大小。(默认情况下,这是 16px ,但可以被用户覆盖。)

另一方面,em是当前元素的字体大小。看下面的CSS:

.container {
  font-size: 200%;
}

p {
  font-size: 1em;
}

考虑到上述 CSS, .container 元素内的段落将会变成原来的两倍大小。这是因为 1em 表示“当前字体大小”,在 .container 内,它是200%1em × 200% = 2em (默认为 32px )

然而, .container 元素外的段落仍将是 1em 的正常字体大小(默认为 16px )。

如果我们在上面的CSS中将 em 更改为 rem ,那么所有段落标签的字体大小将始终是浏览器的默认大小,无论它们在哪里。

font-size: 1em 等同于 font-size: 100% 。em 和 % 单位在其他情况下并不总是等价的;例如, width: 1em 和 width: 100% 很可能会非常不同,因为此时百分比是基于父容器的宽度而不是其字体大小。但是,就 font-size 属性而言, % 和 em 是相同的。

总结一下:

  • 1em 是当前元素的字体大小。

  • 1rem (根em)是文档的字体大小(即浏览器的字体大小)。

好的,那就是单位的含义和来源。现在让我们回答为什么使用哪个单位很重要。

为什么这一切都很重要

再次强调的误解是:既然 1em 和 16px 相等,那么选择哪个单位并不重要。这似乎是合理的;如果 16px = 1rem ,那么选择哪种方式输入似乎并不重要。

记住, em 和 rem 是相对的;默认情况下,它们都(最终)基于浏览器的字体大小。

2rem 是浏览器字体大小的两倍;0.5rem 是其一半,依此类推。因此,如果用户更改其首选字体大小,如果使用 em 和 rem ,则网站上的所有文本都会相应更改,就像应该的那样。  仍然是该字体大小的两倍;0.5rem 仍然是其一半。

相比之下, px 值是静态的。无论容器、浏览器或用户的字体大小如何, 20px 只是 20px 。当设置静态像素值时,无论用户的字体偏好大小如何,它都会覆盖该选择并使用指定的确切值。

批判性地说,这意味着如果你的样式表使用 px 在任何地方设置 font-size ,那么基于该值的任何文本都将无法由用户更改。

那是非常糟糕的事情。它是不可访问的,甚至可能会阻止某人完全使用该网站。

因此,虽然可能存在一些有效的用例来解释这种行为,但它绝对不是你想要的默认行为。

这也是避免使用视口单位(如 vw 或 vh )设置字体大小的非常好的理由。它们也是静态的,用户无法覆盖。最多,像 calc(1rem + 1vw) 这样的值可能是可以接受的,因为它仍然包含 rem 作为基础。即便如此,我仍建议使用 clamp() 或媒体查询来设置最小和最大值,因为屏幕尺寸往往远远超出我们所期望或测试的范围。

超出字体大小的差异

好的,现在让我们谈谈当我们不特别处理 font-size 属性时, px 和 em / rem 如何变化。

开发人员通常通过缩放页面来进行测试,我认为这就是本文中心误解的来源。当你缩放时,所有内容都会被缩放(放大或缩小),在这种情况下,选择 px 或 em / rem 作为你的CSS单位通常并不重要。就缩放而言,两者的行为方式相同。而且,大多数视力良好的开发人员可能不会意识到其中还有更多内容。然而,棘手的问题是:

即使超出 font-size , px 的行为也与 em 和 rem 不同。

px 单位仍然与屏幕上像素的缩放值相关联。em 和 rem 与文档的字体大小相关联,而不是页面的缩放或比例。

为了演示,请看这个 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;
}

我们有几个段落,每个段落底部有 2px 边框,并且它们之间有 20px 边距。请注意,我们对两者都使用 px 单位。

如果你放大或缩小,元素的大小和距离保持相对不变。也就是说:你放大得越多,那条线就越粗,段落之间的间距就越大。

为了方便起见,这里有一张截图,显示了同一支笔的400%缩放。文本、线条和间距都变大了4倍;它们相对于彼此的大小保持不变:

当涉及到缩放时, px 、 em 或 rem 之间没有真正的区别。但缩放并不是用户使网站更易用的唯一方法。

如前所述,用户还可以指定默认和/或最小字体大小。当他们这样做时,功能开始分歧。

在下面的截图中,我已将Firefox的默认字体大小设置为 64px 。看一下:

将屏幕截图中的文本与其上方的文本进行比较。请注意,这一次,行并没有变粗,段落之间的边距也没有成比例增加。只有文本本身变大了。因为边框宽度和边距都是在 px 中设置的,它们保持不变,不会缩放。

但是请注意,如果将CSS中的 px 更改为相应的 rem 值,会发现线条和间距确实变大了!(zh-Hans)

所以,这里的总结是:

  • 当用户更改字体大小时, px 值不会缩放。

  • em 和 rem 的值会随字体大小成比例调整。

如果你想要一个交互式演示,将所有这些内容联系在一起,请查看最终的 CodePen;调整顶部的滑块以查看修改文档字体大小对各种元素的影响,基于它们使用的 CSS 单位。https://codepen.io/collinsworth/pen/KKepeMQ

选择哪一个

因此,知道 em 和 rem 会随字体大小缩放,但 px 值不会,那么我们该怎么办?我们应该永远不使用 px 吗?

虽然我认为如果你选择这条路,你可能会没事,但我仍然认为 px 有其存在的意义。

我们知道当用户调整字体大小时 px 值不会改变,这意味着像素单位实际上是某些美学元素的不错选择。也许我们有一定的间距,我们不希望在字体大小变大时变得更大。(如果默认情况下是一个大块的负空间,也许允许它缩放到更大的尺寸是没有意义的。)

也许有一些边框大小我们不想改变,或者页面上有用 CSS 创建的装饰元素,在更大的字体大小下看起来效果不佳。也许我们不希望填充随着字体大小的增加而膨胀。在所有这些情况下, px 仍然是一个不错的选择。

我个人建议使用 rem 来设置所有的大小。我只在想要与当前字体大小成比例的东西(例如,与一些文本旁边的图标应该与字符的高度完全相同,并且在一侧有半个字符的情况)中添加 em 。我不会在任何地方使用 px ,除非是明确不想随字体大小缩放的设计元素。

永远不要用 px 单位中设置 font-size ,除非你非常确定你在做什么,它会如何行动,以及在你这样做时它是否仍然可访问。

关于媒体查询的重要说明

出于与上述所有原因相同的原因,重要的是要避免在 @media 查询中使用 px ;当用户缩放时,它将正常工作,但是使用 px 的媒体查询将在用户自己设置更大的字体大小时失败。

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

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

这是因为随着字体大小的增加, 50rem 会根据用户的偏好变成不同的值,而 800px 则不会

很可能,当我们为较大的断点编写CSS时,我们认为有足够的屏幕空间让元素扩展。如果用户设置了非常大的字体大小,则可能不是这种情况,将媒体查询设置为 rem 而不是 px 可以帮助我们避免这种假设并响应用户的偏好。

我在这个网站上遇到了这个问题;我把所有的断点都设置在 px 上。然而,当我将默认字体大小设置得更大时,我的媒体查询没有响应,因为它们仍然只查看屏幕的像素宽度。因此,我仍然有一个微小的侧边栏,里面塞满了难以辨认的巨大文本,因为我没有考虑用户的偏好。在那之后,我立即改为 rem ,问题得到了解决。

简而言之:在媒体查询中,除非您确定自己知道在浏览器中设置自己的字体大小会对用户产生什么影响,否则一定要避免使用 px 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/36888.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为、阿里巴巴、字节跳动 100+ Python 面试问题总结(三)

系列文章目录 个人简介&#xff1a;机电专业在读研究生&#xff0c;CSDN内容合伙人&#xff0c;博主个人首页 Python面试专栏&#xff1a;《Python面试》此专栏面向准备面试的2024届毕业生。欢迎阅读&#xff0c;一起进步&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; …

R中高效安装包,以ComplexHeatmap包为例

包安装问题解决方案 1. Biocmanager安装 [2. 手动安装]&#xff08;正在更新……&#xff09; 目录 包安装问题解决方案前言1. install.packages()的介绍1.1 install.packages()的工作原理1.2 install.packages()安装失败的原因1.3 解决方案 2. BiocManage安装ComplexHeatmap总…

Android 中利用多个Button组合实现选项切换效果

效果图&#xff1a; xml布局: <LinearLayoutandroid:orientation"horizontal"android:layout_width"match_parent"android:layout_height"50dp"android:gravity"center"android:background"color/White">​<Linear…

Django_Paginator分页器

目录 分页器代码说明 简单demo 源码等资料获取方法 分页器代码说明 import os import random # 需要导入分页器类from django.core.paginator import Paginator, EmptyPage# 导入配置django配置文件 os.environ.setdefault(DJANGO_SETTINGS_MODULE, dailyfresh.settings)it…

SSH 远程口令登录及免密登录

简介&#xff1a; SSH是一种网络协议,用于计算机之间的加密登录。如果一个用户从本地计算机使用SSH协议登录另一台计算机我们就可以认为这种登录时安全的&#xff0c;即使被中途截获,密码也不会泄露 安装 1.服务器安装OpenSSH(CentOS系统默认安装了openssh) 1.yum install op…

Linux 安装elasticsearch,kibana,Logstash

1、Elasticsearch 安装 cd /usr/localwget \ https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.7-linux-x86_64.tar.gz \ https://artifacts.elastic.co/downloads/kibana/kibana-7.17.7-linux-x86_64.tar.gz \ https://artifacts.elastic.co/downlo…

POLARDB IMCI 白皮书 云原生HTAP 数据库系统 一 列式数据是如何存储与处理的

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

如何实现浏览器内多个标签页之间的通信?

1、使用 LocalStorage 特点&#xff1a;同域共享存储空间&#xff1b;持久化将数据存储在浏览器&#xff1b;提供事件监听storage变化 实现逻辑&#xff1a; A页面将数据存储在本地。B页面监听storage的变化&#xff0c;同步storage的最新数据&#xff1b; 好处&#xff1a;操…

探索MediaPipe的人像分割

MediaPipe是Google开源的计算机视觉处理框架&#xff0c;基于TensorFlow来训练模型。图像分割模块提供人像分割、头发分割、多类分割。本文主要探索如何实现人像分割&#xff0c;当然在人像分割基础上&#xff0c;我们可以做背景替换、背景模糊。 目录 一、配置参数与模型 1…

微擎后台getshell,低权限也可以

/web/index.php?csite&aeditor 这个文件可以编辑html&#xff0c;然后前台会解析成php 没测试最新版 比如编辑专题&#xff1a;/web/index.php?csite&aeditor&dopage&multiid0 上架抓包 改html内容为php 复制前台url 访问之 博客原文&#xff1a; 微擎后…

GEE入门学习,遥感云大数据分析、管理与可视化以及在林业应用丨灾害、水体与湿地领域应用丨GPT模型应用

目录 ①海量遥感数据处理与GEE云计算技术实践应用 ②GPT模型支持下的Python-GEE遥感云大数据分析、管理与可视化技术及多领域案例实践应用 ③GEE遥感云大数据林业应用典型案例实践及GPT模型应用 ④遥感云大数据在灾害、水体与湿地领域典型案例实践及GPT模型应用 ①海量遥感…

关于SpringBoot、Nginx 请求参数包含 [] 特殊符号 返回400状态

问题来源&#xff1a; 使用RESTful风格发送带有特殊符号(如&#xff1a;点、大括号等)的请求&#xff0c;当使用Nginx做地址映射时会返回报"HTTP Status 400-Bad Request"的错误&#xff0c;这个时候我们需要对Nginx的映射方式做一下调整。 Nginx调整完发现跳转后又报…

回归预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 回归预测 | MATLAB实现WOA-CNN-GR…

ELK日志记录——Kibana组件——grok 正则捕获插件、mutate数据修改插件、multiline 多行合并插件、date 时间处理插件

grok 正则捕获插件 grok 使用文本片段切分的方式来切分日志事件 内置正则表达式调用 %{SYNTAX:SEMANTIC} ●SYNTAX代表匹配值的类型&#xff0c;例如&#xff0c;0.11可以NUMBER类型所匹配&#xff0c;10.222.22.25可以使用IP匹配。 ●SEMANTIC表示存储该值的一个变量声明&…

【新版系统架构】第十七章-通信系统架构设计理论与实践

软考-系统架构设计师知识点提炼-系统架构设计师教程&#xff08;第2版&#xff09; 第一章-绪论第二章-计算机系统基础知识&#xff08;一&#xff09;第二章-计算机系统基础知识&#xff08;二&#xff09;第三章-信息系统基础知识第四章-信息安全技术基础知识第五章-软件工程…

《数学模型(第五版)》学习笔记(1) 第1章 建立数学模型 第2章 初等模型

参考数学建模论坛《数学模型(第三版)》学习笔记 http://www.madio.net/thread-146480-1-1.html 参考视频 数模视频&#xff08;姜启源、谢金星&#xff09; https://www.bilibili.com/video/BV1VJ411w7r3/?spm_id_from333.788.recommend_more_video.0&vd_source3ef6540f84…

【高级程序设计语言C++】初识模板

1. 函数模板1.1函数模板的实例化1.2显示实例化1.3模板参数的匹配原则 2.类模板2.1类模板的定义格式2.2类模板的实例化 1. 函数模板 概念&#xff1a; 函数模板代表了一个函数家族&#xff0c;该函数模板与类型无关&#xff0c;在使用时被参数化&#xff0c;根据实参类型产生函…

哪些软件分析工具需要使用到pdb符号文件?

目录 1、什么是pdb文件&#xff1f;pdb文件有哪些用途&#xff1f; 2、pdb文件的时间戳与pdb文件名称 3、常用软件分析工具有哪些&#xff1f; 4、使用Windbg调试器查看函数调用堆栈时需要加载pdb文件 4.1、给Windbg设置pdb文件路径 4.2、为什么要设置系统库pdb文件下载服…

springboot家具商城系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

vuepress - - - 首页底部版权信息加a标签超链接跳转或备案信息跳转链接

修改前 默认的底部版权信息只能填写纯文本&#xff0c;加不了超链接跳转等。 对应\docs\README.md内容&#xff1a; 修改后 修改后&#xff0c;点击Zichen跳转会打开新的网页。 看官网例子 底部添加了备案号跳转链接。 找到官网的github部署的文件。点导航栏中的“指…