CSS Values and Units - 从 规范 理解值和单位系统

165 阅读13分钟

CSS Values and Units Module 定义了 CSS 属性值的类型系统,包括文本、数值、长度、角度等数据类型。理解这套系统是掌握 CSS 的基础,它规定了每个属性可以接受什么样的值、如何组合使用。本文基于 W3C 官方规范,全面介绍 CSS 值(Values)和单位(Units)的分类、语法、使用场景。

值定义语法

值定义语法(Value Definition Syntax)是 CSS 规范中用来描述属性值的形式化语言,理解它能帮助你准确读懂每个属性接受什么样的值。

为什么需要值定义语法

当你查阅 CSS 规范时,会看到类似这样的定义:

/* 属性定义示例 */
margin: <length> | <percentage> | auto

border-width: <line-width>{1,4}

这些符号组成的语法描述了属性可以接受的值类型和组合方式。掌握这套语法,你就能准确理解任何 CSS 属性的用法。

基本符号

类型与分组符

符号含义示例
<>数据类型<length> 表示长度类型
[]分组[ auto | <length> ] 把选项组合起来

组合符

符号含义示例
(空格)并列(按顺序都要写)<length> <color> 必须先长度后颜色
|或(只能选一个)auto | none 表示只能选其一
||或(可选多个,任意顺序)<length> || <color> 可以两个都写
&&与(都要写,任意顺序)<length> && <color> 两个都必须有

数量修饰符

符号含义示例
*零次或多次<length>* 可以写多个长度
+一次或多次<length>+ 至少要有一个长度
?可选(零次或一次)<color>? 颜色可选
{n,m}重复次数范围<length>{1,4} 可以写 1 到 4 个长度
#一次或多次,用逗号分隔<length># 可以写多个长度,用逗号分隔
!该组必须产生至少一个值[ bold | <length> ]! 至少要选一个

实际例子

/* padding 可以写 1-4 个长度或百分比值 */
padding: <length-percentage>{1,4}

/* background 的语法非常复杂 */
background: [ <bg-layer> , ]* <final-bg-layer>

/* transform 可以写多个变换函数 */
transform: <transform-function>+

值定义语法的完整规则较为复杂,包括空白符处理、函数记法等。详细内容参考:Value Definition Syntax - CSS Values Spec

CSS 数据类型概览

CSS 规范定义了丰富的数据类型,用 <> 包裹表示。关键字(keywords)不是数据类型,而是直接写在值定义中的字面量(如 autonone)。

文本类型:

  • <custom-ident> - 自定义标识符
  • <dashed-ident> - 带前缀的标识符(如 --variable-name
  • <string> - 字符串
  • <url> - URL 资源定位符

数值类型:

  • <integer> - 整数
  • <number> - 实数
  • <percentage> - 百分比
  • <ratio> - 比例

长度类型:

  • <length> - 长度值
  • <length-percentage> - 长度或百分比

其他量类型:

  • <angle> - 角度
  • <time> - 时间
  • <frequency> - 频率
  • <resolution> - 分辨率

复合类型:

  • <color> - 颜色值
  • <image> - 图像
  • <position> - 位置

接下来的章节将详细介绍这些数据类型的使用方法。

文本数据类型

CSS 中的文本数据类型用于表示关键字、字符串、标识符和 URL。

关键字(Keywords) - 预定义的标识符

关键字是预定义的标识符,直接写在属性值中:

display: block; /* block 是关键字 */
position: relative; /* relative 是关键字 */

全局关键字

CSS 还定义了全局关键字(CSS-wide keywords),适用于所有属性:

  • initial - 重置为属性的初始值
  • inherit - 继承父元素的值
  • unset - 如果属性自然继承则继承,否则重置为初始值
  • revert - 回退到浏览器默认样式
  • revert-layer
.element {
  color: inherit; /* 继承父元素的颜色 */
  margin: initial; /* 重置为初始值 0 */
}

全局关键字不能与其他组件值组合使用

/* 错误示例 */
color: inherit red; /* 无效 */
margin: 10px initial; /* 无效 */

<custom-ident> - 自定义标识符

允许你自定义标识符名称:

/* 定义动画名称 */
@keyframes fadeIn {
} /* fadeIn 是自定义标识符 */

/* 定义计数器名称 */
counter-reset: my-counter; /* my-counter 是自定义标识符 */

/* 自定义属性名(CSS 变量) */
--primary-color: blue; /* primary-color 是自定义标识符 */

注意:自定义标识符不能使用 CSS 关键字,且区分大小写。

<string> - 字符串

用引号包裹,可以是单引号或双引号:

content: "Hello World";
font-family: "Helvetica Neue", Arial, sans-serif;

/* 字符串中可以包含转义字符 */
content: "Line 1\ALine 2"; /* \A 表示换行 */

<url> - URL

用于引用外部资源:

background-image: url(image.png);
background-image: url("https://example.com/image.png");

/* 使用 url() 函数 */
@import url(styles.css);

URL 可以是相对路径或绝对路径,规范还定义了 URL 修饰符、空 URL 等特殊情况。详细内容参考:Textual Data Types

数值数据类型

数值数据类型是 CSS 中最重要的类型之一,包括整数、实数、百分比和比例。

<integer> - 整数

表示整数,可以带符号:

z-index: 10;
z-index: -5;

/* 用于 nth-child 等选择器 */
:nth-child(2n + 1) {
} /* 2n+1 中的 2 和 1 都是整数 */

<number> - 实数

表示实数,可以是整数或小数:

opacity: 0.5;
line-height: 1.5;
font-weight: 400;

/* 可以是负数 */
order: -1;

Dimension 类型说明

Dimension 是"带单位的数值"的统称,不是具体的数据类型。具体的 dimension 类型包括:<length>(长度)、<angle>(角度)、<time>(时间)、<frequency>(频率)、<resolution>(分辨率)等,这些将在后续章节详细介绍。

width: 100px; /* <length> 类型 */
transform: rotate(45deg); /* <angle> 类型 */
transition-duration: 0.3s; /* <time> 类型 */

<percentage> - 百分比

表示相对于参考值的百分比:

width: 50%; /* 相对于父元素宽度的 50% */
font-size: 120%; /* 相对于父元素字体大小的 120% */

/* 百分比的参考值取决于具体属性 */
margin-top: 10%; /* 相对于父元素的宽度(不是高度!) */

<length-percentage> - 混合百分比和维度

某些属性可以同时接受长度和百分比:

/* <length-percentage> 类型 */
width: 100px; /* 绝对长度 */
width: 50%; /* 百分比 */
width: calc(100px + 50%); /* 混合计算 */

<ratio> - 比例

表示宽高比,用于 aspect-ratio 等属性:

aspect-ratio: 16 / 9; /* 16:9 的宽高比 */
aspect-ratio: 1; /* 简写形式,等同于 1/1 */

/* 用于媒体查询 */
@media (aspect-ratio: 16/9) {
}

数值类型还涉及到范围检查、计算规则等细节。详细内容参考:Numeric Data Types

<length> - 长度单位

长度(Length)是 CSS 中最常用的数据类型,分为相对长度和绝对长度两大类。

相对长度单位

相对长度单位的值相对于其他参考值计算。

字体相对单位

这些单位相对于字体尺寸计算:

单位相对于示例
em当前元素的 font-sizepadding: 1em 等于当前字体大小
rem根元素的 font-sizemargin: 2rem 相对于 html 字体
ex当前字体的 x-height(小写字母 x 的高度)line-height: 2ex
ch数字 0 的宽度width: 40ch 适合等宽字体文本
cap大写字母的高度margin-top: 1cap
ic表意文字(如汉字)的宽度width: 20ic
lh当前元素的行高margin-bottom: 0.5lh
rlh根元素的行高padding: 1rlh
/* em 会层级累积 */
body {
  font-size: 16px;
}
div {
  font-size: 1.5em;
} /* 24px */
p {
  font-size: 1.5em;
} /* 36px,相对于父元素 div */

/* rem 始终相对根元素,不会累积 */
div {
  font-size: 1.5rem;
} /* 24px */
p {
  font-size: 1.5rem;
} /* 24px,都相对于 body */

视口相对单位

这些单位相对于视口(Viewport)尺寸:

单位含义示例
vw视口宽度的 1%width: 50vw 占视口宽度的一半
vh视口高度的 1%height: 100vh 占满视口高度
vminvwvh 中较小的值font-size: 5vmin
vmaxvwvh 中较大的值font-size: 5vmax
vi内联方向的 1%(横排=vw,竖排=vh)padding-inline: 5vi
vb块方向的 1%(横排=vh,竖排=vw)padding-block: 5vb
/* 全屏布局 */
.hero {
  width: 100vw;
  height: 100vh;
}

/* 响应式字体 */
h1 {
  font-size: calc(2rem + 2vw); /* 基础 2rem + 视口缩放 */
}

规范还定义了不同的视口变体(large、small、dynamic),用于处理移动端浏览器地址栏的显示/隐藏问题:

  • lvh/lvw - Large viewport(最大视口,地址栏隐藏时)
  • svh/svw - Small viewport(最小视口,地址栏显示时)
  • dvh/dvw - Dynamic viewport(动态视口,随地址栏变化)

绝对长度单位

绝对长度单位有固定的物理尺寸:

单位名称换算
px像素1px = 1/96 inch
cm厘米1cm = 96px/2.54
mm毫米1mm = 1/10 cm
Q四分之一毫米1Q = 1/40 cm
in英寸1in = 96px
pt1pt = 1/72 in
pc派卡1pc = 12pt
/* px 是最常用的绝对单位 */
border: 1px solid black;

/* 打印样式中常用物理单位 */
@media print {
  body {
    margin: 2cm;
  }
  p {
    font-size: 12pt;
  }
}

注意:除了 px,其他绝对单位在屏幕显示中很少使用,主要用于打印样式。

单位选择建议

  • 字体大小:使用 rem 便于全局调整
  • 组件内间距:使用 em 保持与字体的比例关系
  • 布局尺寸:使用 px% 或视口单位
  • 响应式设计:结合 vw/vhrem 使用
  • 打印样式:使用 ptcm

详细内容参考:Distance Units

其他单位类型

除了长度,CSS 还定义了角度、时间、频率、分辨率等单位类型。

<angle> - 角度

用于旋转和渐变等场景:

单位名称换算
deg一圈 360deg
grad百分度一圈 400grad
rad弧度一圈 2π rad ≈ 6.2832rad
turn圈数一圈 1turn
/* 旋转变换 */
transform: rotate(45deg);
transform: rotate(0.125turn); /* 等同于 45deg */

/* 线性渐变 */
background: linear-gradient(90deg, red, blue);
background: linear-gradient(0.25turn, red, blue); /* 等同于 90deg */

/* 角度可以是负数 */
transform: rotate(-30deg); /* 逆时针旋转 */

<time> - 时间

用于动画和过渡:

单位名称换算
s1s = 1000ms
ms毫秒1ms = 0.001s
/* 过渡效果 */
transition: all 0.3s ease;
transition-duration: 300ms; /* 等同于 0.3s */

/* 动画 */
animation: fadeIn 2s ease-in-out;
animation-delay: 500ms;

<frequency> - 频率

主要用于音频相关的 CSS 特性(较少使用):

单位名称换算
Hz赫兹每秒周期数
kHz千赫兹1kHz = 1000Hz
/* 音频属性(实验性) */
voice-pitch: 200Hz;

<resolution> - 分辨率

用于媒体查询,表示设备像素密度:

单位名称含义
dpi每英寸点数Dots per inch
dpcm每厘米点数Dots per centimeter
dppx每像素单位点数Dots per px unit
/* 高清屏幕媒体查询 */
@media (min-resolution: 2dppx) {
  /* Retina 屏幕的样式 */
  .logo {
    background-image: url(logo@2x.png);
  }
}

@media (min-resolution: 192dpi) {
  /* 等同于 2dppx */
}

注意:1dppx = 96dpi,因为 CSS 规定 1 inch = 96px。

详细内容参考:Other Quantities

数学表达式

CSS 提供了强大的数学函数,允许在样式中进行动态计算。

基础计算:calc()

calc() 函数允许你进行四则运算:

/* 混合不同单位计算 */
width: calc(100% - 80px);

/* 复杂计算 */
margin-left: calc(50% - 100px / 2);

/* 嵌套 calc */
font-size: calc(1rem + calc(1vw * 2));

/* 配合 CSS 变量 */
:root {
  --spacing: 16px;
}
.element {
  padding: calc(var(--spacing) * 2);
}

注意:

  • +- 运算符两侧必须有空格
  • */ 运算符可以没有空格,但建议保持一致
  • 除法运算中,除数不能为 0

比较函数:min()、max()、clamp()

这些函数用于值的范围控制:

/* min() 返回最小值 */
width: min(100%, 600px); /* 取较小值,不超过 600px */

/* max() 返回最大值 */
font-size: max(1rem, 20px); /* 至少 20px */

/* clamp() 限制在范围内 */
/* clamp(最小值, 首选值, 最大值) */
font-size: clamp(1rem, 2.5vw, 2rem);
/* 等同于:max(1rem, min(2.5vw, 2rem)) */

实际应用:

/* 响应式字体大小 */
h1 {
  font-size: clamp(1.5rem, 5vw, 3rem);
  /* 最小 1.5rem,最大 3rem,中间根据视口缩放 */
}

/* 容器宽度限制 */
.container {
  width: min(90%, 1200px);
  /* 小屏幕用 90%,大屏幕最多 1200px */
}

取整函数:round()、mod()、rem()

CSS 提供了取整和取余函数(较新特性):

/* round() 四舍五入到最近的倍数 */
width: round(100px, 15px); /* 结果 105px,最接近 15 的倍数 */

/* mod() 取模(保留除数符号) */
rotate: mod(200deg, 360deg); /* 结果 200deg */

/* rem() 取余(保留被除数符号) */
margin: rem(18px, 5px); /* 结果 3px */

三角函数:sin()、cos()、tan()

用于创建复杂的动画和布局效果:

/* 创建圆形布局 */
.item {
  --angle: calc(360deg / var(--total) * var(--index));
  transform: rotate(var(--angle)) translateY(calc(sin(var(--angle)) * 100px));
}

/* 波浪动画 */
@keyframes wave {
  to {
    transform: translateY(calc(sin(1turn) * 20px));
  }
}

反三角函数也可用:asin()acos()atan()atan2()

指数和对数函数

/* pow() 幂运算 */
width: pow(2, 3); /* 8,即 2³ */

/* sqrt() 平方根 */
margin: sqrt(16px); /* 4px */

/* hypot() 计算斜边长度 */
width: hypot(3px, 4px); /* 5px,勾股定理 */

/* log() 对数 */
font-size: log(8, 2); /* 3,即 log₂8 */

/* exp() 自然指数 */
opacity: exp(-2); /* e⁻² */

符号函数:abs()、sign()

/* abs() 绝对值 */
margin: abs(-10px); /* 10px */

/* sign() 返回符号 */
/* 返回 1(正数)、-1(负数)或 0 */
opacity: sign(-5); /* -1 */

数学常数

CSS 定义了数学常数:

/* e(自然对数的底,约 2.718) */
transform: rotate(calc(e * 1deg));

/* pi(圆周率,约 3.1416) */
transform: rotate(calc(pi * 1rad));

/* 无穷大和 NaN */
width: calc(infinity * 1px); /* 无穷大 */
width: calc(-infinity * 1px); /* 负无穷大 */
width: calc(NaN * 1px); /* 非数字 */

实用案例

/* 响应式间距系统 */
:root {
  --base-spacing: clamp(0.5rem, 2vw, 1.5rem);
}

.section {
  padding: calc(var(--base-spacing) * 2);
  gap: var(--base-spacing);
}

/* 流式排版 */
p {
  font-size: clamp(1rem, 0.875rem + 0.5vw, 1.25rem);
  line-height: calc(1em + 0.5rem);
}

/* 网格布局计算 */
.grid {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: max(1rem, 2vw);
}

数学表达式的详细语法规则、类型检查、计算顺序等较为复杂。详细内容参考:Mathematical Expressions

其他重要数据类型

除了前面介绍的值和单位类型,CSS 还有一些重要的数据类型在其他规范中定义。这里简要介绍它们的基本用法。

<color> - 颜色

颜色是 CSS 中最常用的数据类型之一,有多种表示方式:

/* 关键字 */
color: red;
color: transparent;

/* 十六进制 */
background: #ff0000;
background: #f00; /* 简写 */
background: #ff0000ff; /* 带 alpha 通道 */

/* RGB/RGBA */
color: rgb(255, 0, 0);
color: rgba(255, 0, 0, 0.5);
color: rgb(255 0 0 / 0.5); /* 新语法 */

/* HSL/HSLA */
color: hsl(0, 100%, 50%);
color: hsla(0, 100%, 50%, 0.5);
color: hsl(0 100% 50% / 0.5); /* 新语法 */

/* 新颜色空间(CSS Color Level 4) */
color: lab(50% 40 60); /* Lab 色彩空间 */
color: lch(50% 70 180); /* LCH 色彩空间 */
color: oklab(0.5 0.2 0.1); /* OKLab */
color: oklch(0.5 0.2 180); /* OKLCH */
color: color(display-p3 1 0 0); /* Display P3 */

颜色的详细语法、色彩空间、渐变等内容参考:CSS Color Module

<image> - 图像

<image> 类型用于表示图像资源,可以是 URL、渐变或其他图像函数:

/* URL 图像 */
background-image: url(photo.jpg);

/* 线性渐变 */
background: linear-gradient(to right, red, blue);
background: linear-gradient(45deg, red 0%, blue 100%);

/* 径向渐变 */
background: radial-gradient(circle, red, blue);
background: radial-gradient(ellipse at center, red 0%, blue 100%);

/* 锥形渐变 */
background: conic-gradient(red, yellow, green, blue, red);
background: conic-gradient(from 45deg, red, blue);

/* 重复渐变 */
background: repeating-linear-gradient(45deg, red 0px, red 10px, blue 10px, blue 20px);

/* 图像集(针对不同分辨率) */
background-image: image-set(url(image-1x.jpg) 1x, url(image-2x.jpg) 2x);

图像的详细用法、渐变语法、图像处理等参考:CSS Images Module

<position> - 位置

<position> 用于表示二维坐标位置,常用于 background-positionobject-position 等属性:

/* 关键字 */
background-position: center;
background-position: top left;
background-position: bottom right;

/* 百分比 */
background-position: 50% 50%; /* 居中 */
background-position: 0% 0%; /* 左上角 */
background-position: 100% 100%; /* 右下角 */

/* 长度值 */
background-position: 10px 20px; /* 距左 10px,距顶 20px */

/* 混合使用 */
background-position: left 10px top 20px; /* 距左 10px,距顶 20px */
background-position: center bottom 10px; /* 水平居中,距底 10px */

/* 单值语法 */
background-position: center; /* 等同于 center center */
background-position: top; /* 等同于 top center */
background-position: 25%; /* 等同于 25% 50% */

位置值的语法规则:

  • 单个值:指定水平位置,垂直位置默认 center
  • 两个值:第一个是水平位置,第二个是垂直位置
  • 关键字可以与长度/百分比混合使用

详细内容参考:CSS Values - Position