Skip to content

相对单位

1. 相对值的好处

终端设备尺寸越来越多样,使用绝对单位(如像素值)很难完全兼容,在不同尺寸设备上呈现效果可能差距很大,因此不得不开始考虑响应式设计。

响应式:样式能够根据浏览器窗口的大小有不同的响应。

相对单位就是解决这种问题的工具,可以使得布局能够更好地适应不同的显示设备。

css 支持几种绝对长度单位,最常用,最基础的是像素 px,不常用的有毫米 mm、厘米 cm、英寸 in、点 pt,印刷术语、派卡pc

2. em 和 rem

  • em 是最常见的相对单位,1em 等于当前元素的字号,其准确值取决于作用的元素。
  • 浏览器根据相对单位的值计算出绝对值,称为计算值。

2.1 使用 em 定义字号

需要注意 font-size 属性使用 em,此时属性值会根据继承的字号来计算:

css
body {
  font-size: 16px;
}

.slogan {
  /* 继承的值为16px,最终计算值就是 1.2*16 = 19.2px */
  font-size: 1.2em;
}

说明

font-size 默认值为 medium, 大多数浏览器中该值一般就是 16px

2.1.1 em 同时用于字号和其它属性

使用 em 定义了字号,同时定义了其它属性,如 paddingborder-radius,此时会先计算字号,再根据计算出的字号去算出其它属性值。

2.1.2 字体缩放的问题

  • 当元素出现嵌套,且每一级使用 em 定义字号,就可能出现文字缩放的现象。
  • 设置 font-size 有更好的选择:rem

2.2 使用 rem 设置字号

  • HTML 会被浏览器解析成 DOM 树,每个元素就是一个节点,<html> 元素是顶级(根)节点。
  • 根节点有一个伪类选择器 :root,相当于类型选择器 html{} ,但是伪类选择器优先级更高。
  • rem 是相对于根元素的单位,不管在什么地方使用 rem,都是使用根元素的字号进行计算。

技巧

rem 设置字号,用 px 设置边框,用 em 设置其它大部分属性,尤其是内边距、外边距和圆角。

3. 停止像素思维

3.1 设置一个合理的默认字号

  • 应该直接将根元素字号设置为想要的默认字号,在其它地方相对于根元素字号去计算。
  • 建议给根元素设置字号时使用相对单位 em 而非绝对单位。

3.2 构造响应式面板

  • 根据媒体查询改变根元素的字号,就可以根据不同的屏幕尺寸,渲染出大小不同的面板。
  • 媒体查询:可以指定某种屏幕尺寸或媒体类型下的样式,是响应式设计的关键部分。
  • 通过给根元素设置字号,响应式地给整个网页重新定义了 emrem
css
:root {
  font-size: 0.75em;
}

@media (min-width: 800px) {
  :root {
    font-size: 0.875em;
  }
}

@media (min-width: 1200px) {
  :root {
    font-size: 1em;
  }
}

3.3 缩放单个组件

使用 remem 可以方便地对组件进行缩放:

css
.panel {
  /* 给组件设置一个可预测的字号 */
  font-size: 1rem;
  padding: 1em;
  border: 1px solid #999;
  border-radius: 0.5em;
}

.panel > h2 {
  margin-top: 0;
  font-size: 0.8em;
  font-weight: bold;
  text-transform: uppercase;
}

/* 对面板进行放大 */
.panel.large {
  font-size: 1.2rem;
}

4. 视口的相对单位

  • 视口:浏览器窗口里网页可见部分的边框区域,不包括浏览器的地址栏、工具栏、状态栏。
  • vh:视口高度的 1/100。
  • vw:视口宽度的 1/100。
  • vmin:视口宽高中较小一方的 1/100。
  • vmax:视口宽高中较大一方的 1/100。

4.1 使用 vw 定义字号

使用视口相对单位设置字号的好处是能平滑过渡,字号不会在某个断点突然改变。

4.2 使用 calc() 定义字号

calc() 函数可以对两个及以上的值进行计算,在要结合不同单位的值时特别实用。支持的运算包括:加、减、乘、除,运算符前后需要有空格:

css
:root {
  /* 0.5em保证了最小字号,1vw确保字体会随着视口缩放 */
  fons-size: calc(0.5em + 1vw);
}

5. 无单位的数值和行高

  • 有些属性允许无单位的值,包括 line-heightz-indexfont-weight 等。
  • 任何长度单位如 pxemrem 都可以用无单位的值:0。
  • 继承的一个怪异特性:当一个元素的值定义为长度单位时,子元素会继承它的计算值;当使用无单位的数值时,继承的是声明值,即在子元素上会重新计算。
css
body {
  /* 使用无单位的值 */
  line-height: 1.2;
}

.about-us {
  font-size: 2em;
  /* line-height:1.2*2em */
}

警告

一个无单位的 0 只能用于长度值和百分比,如内边距、边框和宽度,不能用于角度值,比如度,或者时间相关的值,比如秒。

6. 自定义属性

自定义属性,也叫 CSS 变量:

css
:root {
  --main-font: Arial, sans-serif;
}
  • 变量名前必须有两个连字符 -- 用来跟 CSS 属性区分,剩下部分可以随意命名。
  • 变量必须在一个声明块中声明,通常在 :root {} 选择器内,这样变量在整个网页可用。
  • 调用函数 var() 就能使用该变量:
css
p {
  font-family: var(--main-font);
}
  • var() 函数接受第二个参数,用于指定备用值,如果第一个参数指定的变量不存在,就会使用第二个值:
css
:root {
  --main-font: Arial, sans-serif;
  --brand-color: #369;
}

p {
  font-family: var(--main-font, Helvetica);
  /* 第一个颜色不存在,则使用 blue */
  color: var(--main-color, blue)
}
  • 如果 var() 函数算出来的是一个非法值,对应属性就会设置为初始值。
  • 自定义属性的声明可以层叠和继承,因此可以在不同的选择器中定义相同的变量,在不同的地方可以有不同的值。