在现代 web 开发中, 由于设备的多样性和屏幕尺寸的不断变化, 响应式布局成为了一个麻烦、但是又非常重要的技术追求. 因此, 在技术方案的学习上, 为了应对各种不同的响应式需求, 我们要学习大量的基础技术方案. 好在在 css 中, 这些方案都开始逐渐趋于成熟. 在 css 的技术方案中, 提供了大量的响应式尺寸单位来解决不同的响应式需求.
响应式单位:指的是会随着参考对象的改变而自动调整的尺寸单位.
常见的响应式单位包括:
em:相对于父元素的字体大小rem:相对于根元素(html)的字体大小%:相对于父元素的百分比vw/vh:相对于视口宽度/高度的百分比vmin/vmax:相对于视口最小/最大尺寸的百分比本文主要是来介绍一下 css 中的第一个响应式尺寸单位: em
em 的参考对象为该元素本身的字体大小.
例如, 下面这个例子, 有一个元素 div, 我们设置其字体大小为 14px, 此时, 其他的属性尺寸使用 em 来表示. 那么有如下换算
11em = 14px20.5em = 7px30.6em = 8.4px
此时, 我们就可以使用 em 来设置元素的边框、内边距、外边距等属性.
演示效果如下
01.supercss_em_03_box {02font-size: 14px;03border: 0.5em solid #000;04padding: 1em;05margin: 1em;06border-radius: 0.6em;07background: #fff;08color: #222;09transition: background 0.2s, color 0.2s, border-color 0.2s;10}1112@media (prefers-color-scheme: dark) {13.supercss_em_03_box {14background: #18181c;15color: #eee;16border-color: #444;17}18}
该元素的字体大小, 如果没有设置
16px例如, 当父元素字体为 16px 时, 那么对于子元素而言
11em = 16px22em = 32px
如果我们将父元素字体大小设置为 20px, 那么对于子元素而言
11em = 20px22em = 40px
这样, 我们可以只需要更改父元素的字体大小, 就可以控制子元素的大小发生变化.
观察一下这个案例
01import './index.css'0203function Demo01() {04return (05<div className='supercss_em_01_parent m-4'>06I'm parent div set font-size: 20px07<div className='child'>08I'm child div set font-size: 2em09</div>10</div>11);12}1314export default Demo01;
这是一个改变父元素的字体大小, 然后, 然后对子元素相关的 em 尺寸造成影响的案例. 此时, 当我们通过按钮改变父元素的字体大小, 注意观察子元素的高度变化.
1.child {2height: 8em;3}
rem 拥有与 em 几乎相同的特性, 不过一个微弱的区别就是, rem 仅仅只会参考根元素的字体大小.
在实践项目中, 我们常常会直接使用 rem 来实现移动端的响应式布局.
在本网站的案例中, 由于案例的父节点都不是根 html 节点, 因此案例中的单位会优先使用 em 来演示其特性, 大家理解这个场景的不同即可.
这主要是因为移动端设备的屏幕尺寸逻辑像素宽度相差不多, 例如, iphone SE 的逻辑像素宽度为 375px, iphone 14 的逻辑像素宽度为 390px, 其他 max 版本的逻辑像素宽度为 430px. 因此, 为了做到在不同移动端尺寸下有相同的视觉体验, 我们会根据宽度的变化来计算根元素的字体大小. 从而实现其他使用了 rem 的元素的等比缩放.
这个思路并不适用于 PC 端. 因为 PC 端的屏幕尺寸过大, 等比缩放之后布局会变得非常奇怪. 具体的实现思路我们会在后续的文章中进行介绍.
因此在 PC 端, 我们也许可能会基于根 html 节点的字体大小来设计一些开发规范, 但是其大小基本上是固定的. 例如默认情况下, 我们使用 tailwindcss 时, 根 html 节点的字体大小为 16px