
写完《现代 CSS 中的相对单位 》这节课之后,我原本以为大家会带着一种"原来如此"的轻松感继续往下写代码。但很快,私下就有不同的同学问:为什么这里不用 px ?什么时候该用 rem ?vw 和 0% 到底有什么区别?移动端布局什么该用 rem 还是 vw ?这些问题不仅在一个地方出现,而是在不同平台、不同时间被反复提起。
于是,我决定单独用一节课,把这些零散的问题集中起来,好好聊一聊。我们不再孤立地看某一个单位,而是把 px 、em 、rem 、% 、视窗单位(如 vw 、vh)、容器查询单位(如 cqw 、cqh)以及 ex 、ch 和 lh 放在同一个语境下,重新理解它们的作用,以及更重要的------如何做出选择。
CSS 单位选择的本质:不是用什么,而是跟随谁变化
在实际开发中,很多人一开始都会本能地选择 px。它足够简单、直接,几乎不需要额外思考------设计稿量多少就写多少,浏览器呈现出来的结果也高度一致。这种"所见即所得"的确定性,在项目初期确实非常有吸引力。
但随着项目逐渐复杂,这种看似稳妥的选择,往往会开始暴露出问题。页面在不同设备上看起来似乎"差不多",却总差那么一点协调感;字体系统变得难以统一,局部调整容易牵一发动全身;为了适配各种尺寸,不得不引入越来越多的媒体查询;而组件一旦脱离原有上下文,复用时也常常出现不可预期的表现。
很多人会因此怀疑,是不是一开始就不应该使用 px 。但从结果来看,问题并不在于某一个具体单位,而在于我们没有在一开始建立一套清晰的尺寸关系。
这正是这节课真正要解决的核心问题。CSS 单位表面上是在描述"长度",但它们更本质的作用,其实是在定义一种关系------元素的尺寸,应该跟随变化。
当你写下一个值时,本质上是在做一次"绑定"。使用 px ,意味着它几乎不跟随外部环境变化;使用 % ,它会依赖父元素;使用 em ,它会响应当前元素的字体大小(font-size);使用 rem ,则是跟随根元素(html);视窗单位(如 vw 、vh)绑定的是浏览器的视窗,而 cqw 、cqh 这样的容器查询单位,则让元素直接跟随其所在的父容器。
也就是说,你并不是在选择"用哪种单位更好",而是在决定这个元素应该"听谁的"。是跟随屏幕变化,还是跟随父级容器?是依赖全局排版系统,还是保持自身的稳定?一旦换一个角度去看,很多原本让人纠结的问题,其实会自然消失。
你会开始意识到,px 并不是错误,它只是选择了不响应变化;rem 也不是万能方案,它只是把变化集中在一个全局入口;vw 看起来很灵活,但有时会让组件失去边界感;而容器查询单位,则是在回答一个更现代的问题------组件是否可以只关心自己所在的空间,而不是整个页面。
接下来,我们不会从定义出发逐个讲解每个单位,而是先建立一套"尺寸关系模型",再去分析每种单位适合绑定的对象,最后总结出一套可以直接应用在项目中的选择策略。目标不是让你记住所有单位的细节,而是让你在任何场景下,都能快速判断------这里的尺寸,究竟应该跟随谁变化。
CSS 单位的尺寸关系模型
如果把前面所有零散的讨论收拢在一起,其实可以得到一个非常关键的结论:
CSS 单位并不是一堆彼此独立的"语法选项",它们本质上构成了一整套尺寸依赖关系系统。
一旦从这个角度去理解,就可以把所有单位放进一个统一的框架中来看待,也就是所谓的"CSS 单位的尺寸关系模型"。
这个模型的核心可以用一句话概括:每一个尺寸,本质上都是依附在某个参照物上的结果。 你写下的从来不是一个孤立的数值,而是一种"绑定关系"。也就是说,当你在写 CSS 时,你真正做的事情并不是定义一个长度,而是在决定这个长度应该"跟谁产生关系"。
基于这个视角,我们就可以把所有常见单位重新整理一遍。不再按语法分类,而是按照它们"依附谁"来划分。这样整理之后,会得到一个非常清晰的结构------一个由不同"关系层级"组成的尺寸模型。
绝对关系:不跟随任何对象
在所有尺寸关系中,"绝对关系"是容易理解的一类,它几乎不依附于任何外部对象。典型代表就是 px 。当你使用 px 时,本质上传达的是一种明确的意图:这个尺寸应当保持稳定,不随着环境变化而改变。
这种特性让 px 在很多场景下非常有价值。比如边框、阴影、精细对齐等细节控制,都需要高度确定性和可预测性,这正是 px 的优势所在。它提供了一种接近"所见即所得"的体验,让你可以精确地掌握视觉结果。
但问题在于,一旦把这种"固定性"扩展到布局层面,比如用在容器尺寸、间距系统或整体排版上,就会开始削弱页面的弹性。页面难以自然适配不同设备,响应能力变差,后期往往需要额外的补丁来弥补。
所以,与其把 px 简单理解为"绝对单位",不如换一个更本质的视角来看------它其实是一种主动拒绝建立关系的选择。
全局关系:跟随根元素
在"在局关系"这一类中,所有尺寸都会统一依附于同一个源头------根元素(html)。最典型的代表就是 rem 。当你使用 rem 时,本质上传达的是一种明确的选择:这个尺寸不由局部环境决定,而是完全跟随全局系统。
这种机制非常适合用于构建设计系统。无论是字体层级、间距体系,还是组件的基础尺寸,都可以基于 rem 来建立。一旦调整根元素的字号(font-size),整个页面就会按照既定比例整体缩放,从而实现一致且可控的响应效果。
不过,这种"全局绑定"也有一个前提:你必须建立清晰且合理的全局规则。如果没有这一步,rem 并不会减少复杂度,只是把原本分散在各处的问题,集中转移到了全局层面。换句话说,rem 并不是简化问题的工具,而是放大设计系统价值的工具。
局部关系:跟随当前上下文
"局部关系"这一类单位,强调的是尺寸与当前上下文之间的依赖关系,而不是与整个页面或全局系统的绑定。典型代表是 em 和 % 。其中,em 相对于当前元素的字体大小(font-size),而 % 通常相对于父元素的尺寸计算。需要知道的是,% 是一个较为复杂的单位,它应用在不同属性值时,依附的参照物是不同的。
当你使用这类单位时,其实是在表达这样一种意图:这个元素的大小,不由全局决定,而是由它所处的环境来决定。换句话说,它就是"就地适应"的。
这种特性在组件内部尤其有用。例如按钮、卡片这类 UI 元素,其内边距、间距、子元素尺寸等,都可以随着组件自身的变化而自然缩放,从而形成更具弹性的结构。
不过,这种"局部依赖"也带来一个隐患:它是可以层层嵌套的。一旦组件结构变得复杂,多层 em 或 % 叠加之后,最终的计算结果往往不再直观,甚至难以追踪。因此,在使用这类单位时,需要对层级关系保持足够的控制,避免无意中引入过深依赖链。
环境关系:跟随视口
"环境关系"这一类单位,直接把尺寸绑定到浏览器视口,也就是屏幕本身。典型代表是 vw 、vh ,以及 vmin 、vmax 等。使用这些单位时,元素的尺寸应当随着屏幕大小按比例变化------屏幕多大,它就多大。
这种能力在很多场景中非常有用。比如全屏布局(如首屏视觉区域)、流式字号,以及一些强依赖视觉比例的设计,都可以通过视口单位获得非常自然的响应效果。
不过,一旦把这类单位用在组件内部,就容易引发问题。因为此时组件的尺寸不再由自身或其容器决定,而是直接被整个页面环境"接管"。结果就是,组件失去了应有的独立性,在不同布局或上下文中变得难以控制和复用。
容器关系:跟随父容器
"容器关系"代表的是一种更现代的尺寸绑定方式------元素不再依赖整个视口,而是直接依附于自身所在的父容器。典型单位是 cqw 、cqh 等容器查询单位。
当你使用这类单位时,这个元素的尺寸,不再由屏幕决定,而是由它当前所处的空间来决定。也就是说,它只关心"自己有多少可用空间",而不是整个页面有多大。
这正好解决了传统响应式设计中一个核心限制------媒体查询只能基于视口进行判断,但在实际开发中,组件更关心的往往是自身容器的尺寸,而不是屏幕尺寸本身。
容器单位的出现,让响应式能力从"页面级"下沉到了"组件级"。组件不再依赖外部布局或全局断点,就可以根据自身环境自动调整,从而真正具备独立、自适应的能力。这也是现代 CSS 组件化设计中非常关键的一步。
内容关系:跟随文本与排版度量
"内容关系"这一类单位,关注的已不再是布局结构,而是文本本身的度量。典型代表包括 ch 、ex 、lh 和 rlh 。与前几类不同,它们不依赖视口、容器或父元素,而是直接绑定到字体和排版系统之上。
当你使用这些单位时,其实是在表达一种更偏向内容驱动的设计思路。尺寸应当由文本本身来决定,而不是由外部布局强加。比如,ch 基于字符宽度,常用于控制理想的阅读行长;ex 反映字体的 x-height ;lh 和 rlh 则直接与行高(line-height)相关,用来建立稳定的垂直节奏。
这种方式的价值在于,它把"排版经验"转化成了"系统规则"。例如,用 60ch 控制段落宽度,可以自然得到更舒适的阅读长度;用 1lh 控制段落或模块之间的间距,可以让整体节奏始终保持 一致,而不需要反复微调具体数值。
从更高层来看,这类单位所代表的,是一种设计理念的转变:不是让内容去适配布局,而是让布局围绕内容生长。
比例关系:无单位
这一类并不是在描述"跟随谁变化",而是在定义变化本身。与前面所有单位不同,它不关心依附对象,而是直接规定变化的比例,因此,可以把它理解为一种"比例关系"。典型的例子包括:
CSS
line-height: 1.5;
flex: 1;
opacity: 0.8;
这些值有一个共同特点:它们表达的不是一个具体长度,而是一个倍数关系。换句话说,它们关注的不是"多大",而是"多少倍"。以最常见的 line-height: 1.5 为例:
CSS
p {
font-size: 16px;
line-height: 1.5;
}
这里的 1.5 实际含义是:行高等于当前字体大小的 1.5 倍。如果字体大小从 16px 变成 20px,行高会自动变成 30px。
关键在于,这种关系是"内嵌"的,而不是"引用"的。它不像 em 那样依赖字体作为单位,也不像 rem 依赖根元素,而是直接把比例规则写进属性本身。这种表达方式更直接,也更稳定。
正因为如此,在很多场景中,无单位数值反而是更推荐的写法,尤其是在排版中。相比固定的 24px,或者可能受嵌套影响的 1.5em,line-height: 1.5 不依赖具体单位,不会产生层级累积问题,还能随着字体变化自动调整。同时,它的语义也更清晰------表达的是"阅读密度",而不是一个具体尺寸。
这种"比例关系"其实在 CSS 中无处不在,并不仅仅局限于排版。在 Flex 布局中:
CSS
.item {
flex: 1;
}
表达的是空间分配的比例,而不是具体宽度。
在 Grid 中,虽然 fr 看起来像单位,但本质上同样是一种比例系统:
CSS
grid-template-columns: 1fr 2fr;
表示的是 1:2 的空间分配关系。再比如透明度、变换等属性:
CSS
opacity: 0.5;
scale: 1.2;
同样是在描述相对变化,而不是绝对数值。
从这个角度来看,无单位数值其实承担的是另一种角色:它不负责"绑定关系",而是负责在既定关系中,定义变化的幅度。
在理解了前面的所有关系之后,其实还可以再往前走一步,把整个模型进一步抽象。换一个更简洁的视角来看,CSS 中的所有尺寸,本质上都在回答两个问题:它是否需要变化?如果需要变化,它应该跟随谁变化。
第一个问题是在区分"固定"和"响应"。有些尺寸需要保持稳定,比如边框或精细对齐,这时选择的是"不变化";而有些尺寸则需要随着环境调整,这时就进入"响应"的范畴。第二个问题则是在确定依附对象------是跟随全局系统、局部上下文、视口环境、容器空间,还是内容本身。
一旦用这种方式思考,单位选择就不再是一个依赖经验或记忆的过程,而是一个可以被推导的决策过程。你不再需要记住"某种场景用某种单位",而是先明确关系,再自然得出答案。
这也正是"尺寸关系模型"真正重要的地方。很多开发中的问题,并不是单纯因为"单位选错了",而是关系选错了:在应该使用全局关系的地方使用了局部关系,在应该依赖容器的地方却绑定了视口,在应该围绕内容排版的地方却用了固定值。结果就是,系统逐渐失去一致性,适配变得困难,维护成本不断增加。
而这个模型的价值,在于提供了一个统一的判断框架:先决定关系,再选择单位。一旦顺序颠倒------先选单位,再试图去适配各种场景------问题往往就会不断出现。
最佳使用场景
从这里开始,CSS 单位就不再是一组零散的工具,而是一整套可以被设计、被推理、也可以被复用的系统。你不再是在零碎地选择某一个单位,而是在基于一套清晰的关系模型,去构建整个页面的尺寸逻辑。
接下来,更关键的一步,是把这套模型真正落到实际项目中。也就是说,在具体场景里,你到底该使用哪一类单位。与其去记忆"某种场景对应某种单位",不如换一种更稳定的思考方式------从"关系"出发,反推出"选择"。一旦你明确了这个元素应该跟随谁变化,单位本身几乎是自然浮现的。
因此,接下来的内容,我们会基于这套"尺寸关系模型",按顺序逐一拆解每一类单位在真实项目中的最佳使用场景。重点不在于记住规则,而在于理解背后的逻辑,并能够在不同情境中灵活应用。
当你理解到这一层时,CSS 单位这件事就不再是一个依赖经验的选择题,而是一个可以建模、可以推导,甚至可以系统化设计的能力。这一步,基本已经进入"设计系统思维"的范畴了。
px :用于"需在稳定、不参与响应"的细节
px 最适合的使用场景,其实并不在布局层面,而是在那些需要稳定、不参与响应变化的细节 上。换句话说,当一个尺寸的变化不会带来收益,甚至可能破坏视觉一致性时,px 往往是最合理的选择。
典型的例子包括细边框(如 1px 或 0.5px)、图标对齐的微调、阴影与描边、分割线,以及一些小范围的视觉校正。这些细节的共同点在于:它们依赖精确的像素控制,一旦随着环境变化而缩放,反而容易产生模糊、偏移或不协调的视觉效果。
从这个角度来看,在这些场景中使用 px,反而是一种更"响应式"的选择------因为你在有意识地避免不必要的变化,让关键细节保持稳定。
但需要注意的是,这种优势并不适用于布局层面。如果把 px 用作主要的布局单位,比如容器宽度、模块间距或字体尺寸,一旦页面进入多端适配阶段,这些"固定值"就会迅速变成负担,限制整体的弹性和可扩展性。
rem:用于"全局一致"的系统级尺寸
rem 最适合的使用场景,是构建设计系统中的"全局一致"尺度。它的核心价值在于,把所有尺寸统一绑定到根元素,从而让整个页面在同一个规则下运作。
在实际项目中,rem 常用于定义全局字体体系、统一的间距系统,以及组件的基础尺寸(例如 padding、margin、gap)。这些场景有一个共同特点:它们需要在整个页面中保持一致,并且能够随着整体策略一起缩放。
例如,你可以基于 rem 定义一套间距系统:
CSS
:root {
--space-1: 0.5rem;
--space-2: 1rem;
--space-3: 2rem;
}
当根元素的字号发生变化时,这些间距会自动按比例调整,而不需要逐个修改组件。这种方式可以极大地降低维护成本,同时保证视觉上的一致性。
不过需要注意的是,rem 更适合用于"系统层",而不是"局部例外"。如果某个组件需要根据自身环境动态变化,比如根据容器或上下文自适应,那么继续使用 rem 反而会让它变得僵硬。换句话说,rem 擅长统一规则,但并不擅长处理局部差异。
em 或 % :用于"组件内部的自适应关系"
em 和 % 这一类单位,最适合用于构建组件内部的自适应关系。它们的特点是依赖当前上下文,而不是全局系统,因此非常适合用来描述组件内部各个元素之间的比例关系。
例如,一个按钮组件可以这样定义:
CSS
.button {
font-size: 1rem;
padding: 0.5em 1em;
}
这里的 em 实际上传达的是一种关系:按钮的内边距应该随着字体大小变化。也就是说,组件内部的空间是"绑定"在自身排版之上的,而不是写死为某个固定值。
类似的使用场景还有很多,比如图标与文字之间的比例关系(使用 em),子元素宽度占父元素的比例(使用 %),以及卡片内部结构中常见的 100% 宽度元素等。这些都属于在组件内部建立相对关系的典型用法。
这类单位的核心价值在于,让组件具备"自我缩放"的能力。当组件被放入不同的上下文中,比如更大的容器、不同的字号环境,或者不同的布局结构时,它可以自然适配,而不需要额外调整具体数值。
不过需要注意的是,这种依赖关系是可以层层叠加的。一旦嵌套层级过深,em 的计算路径就会变得复杂,最终结果也不再直观。因此,在复杂结构中使用时,需要有意识地控制层级,避免关系链失控。
视窗单位:用于"与屏幕强绑定"的布局或视觉
vw 和 vh 这类视窗单位,最适合用于那些与屏幕强绑定的布局或视觉设计。它们直接以浏览器视口为参照,因此表达的是一种非常明确的关系:尺寸应该随着屏幕变化,而不是由容器或内容决定。
在实际项目中,这类单位常见于全屏布局、流式字号,以及一些依赖屏幕比例的视觉效果。例如:
CSS
.hero {
height: 100vh;
}
或者:
CSS
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
这些用法的共同点在于:它们让元素的尺寸直接响应视口变化,从而在不同设备上保持一种整体的视觉比例。
不过需要注意的是,这种"直接绑定屏幕"的能力,并不适合用在组件内部。一旦在组件中使用 vw 或 vh,组件的尺寸就会脱离自身上下文,被整个页面环境所控制。这会导致组件难以复用,也更难在不同布局中保持稳定表现。因此,视口单位更适合作为页面级或视觉级的工具,而不是组件级的默认选择。
窗器单位:用于"真正可复用的响应式组件"
cqw、cqh 等容器查询单位,最核心的使用场景是构建真正可复用的响应式组件。与视口单位不同,它们并不依赖整个页面,而是直接绑定到组件所在的父容器。
例如一个卡片组件:
CSS
.card {
width: 100%;
padding: 5cqw;
}
这里表达的是一种非常清晰的关系:组件的尺寸不由屏幕决定,而是由它当前所处的容器空间决定。也就是说,组件只关心"自己有多少可用空间",而不关心整个页面的大小。
这种能力在很多场景中尤为重要。比如同一个组件需要出现在不同布局中(侧边栏、主内容区或网格中),或者组件需要根据可用空间自动调整结构,又或者希望减少对媒体查询的依赖。这些问题,用传统的视口响应方式往往很难优雅解决,而容器单位则可以直接应对。
从更高层来看,容器查询单位的意义在于,让组件具备一种"环境感知能力",但这个环境是局部的,而不是全局的。组件不再依赖页面断点,而是根据自身所处的上下文自我调整。这也可以说是现代 CSS 从页面级响应式迈向组件级响应式的关键一步。
ch 或 lh 等:用于"排版与阅读体验驱动"的设计
ch、lh 等这类单位,最适合用于那些以排版和阅读体验为核心的内容区域。与前面侧重布局的单位不同,它们直接绑定到文本本身的度量,因此更适合解决"读起来是否舒服"的问题。
典型的应用场景包括:控制文章正文的宽度(例如 max-width: 60ch)、设置段落之间的间距(如 margin-bottom: 1lh),以及建立整体的垂直节奏。这些场景有一个共同点:尺寸不应该由布局决定,而应该由内容本身来驱动。
例如:
CSS
.article {
max-width: 65ch;
line-height: 1.6;
}
通过 ch 控制行长,可以直接得到更理想的阅读宽度,而不需要反复尝试具体数值。再比如:
CSS
p {
margin-bottom: 1lh;
}
使用 lh 来定义间距,可以让段落之间始终与当前的文本节奏保持一致。
这类单位的真正价值,在于它们把原本依赖经验的排版决策,转化为可以复用的系统规则。你不再需要不断"微调数值",而是可以通过单位本身,让设计自然成立。
无单位值
无单位数值最适合用于那些本质上是在表达"比例关系",而不是具体尺寸的场景。与其他单位不同,它不依附于某个参考系,而是直接定义一种倍数规则,因此特别适合用来描述变化幅度、分配关系或节奏控制。
在实际开发中,这类写法广泛存在于排版、布局和视觉效果中。例如在排版中:
CSS
p {
line-height: 1.6;
}
这里的 1.6 表达的是行高与字体大小之间的比例关系,而不是一个固定高度。这样做的好处是,无论字体如何变化,行高都会自动按比例调整,从而保持稳定的阅读节奏。这类用法的共同点在于:它们关注的不是尺寸本身,而是尺寸之间的关系。
无单位数值的核心价值在于,它把设计中的"比例"和"节奏"直接表达出来,而不会受到单位或上下文嵌套的干扰。相比使用固定值或依赖单位的写法,它通常更加稳定、可预测,也更贴近设计本意。
从更高层来看,这类写法实际上是在把"经验规则"转化为"数学关系"。你不再是在不断调整一个个具体数值,而是在定义一套可以自动生效的比例系统。这也是它在现代 CSS 中越来越重要的原因。
如果把前面所有使用场景再压缩成一条清晰的决策路径,其实可以用一个非常简单的思考顺序来判断:首先,这个尺寸是否需要变化?如果答案是不需要,那么直接使用 px,让它保持稳定即可。
如果这个尺寸需要变化,接下来要问的就是------它应该跟随谁变化。是跟随全局系统(rem),还是组件内部(em 、 %),是跟随屏幕(vw 、 vh),还是跟随容器(cqw 、 cqh),又或者是跟随内容本身(ch 、 lh)。当这个问题有了明确答案,单位的选择几乎是自然得出的结果。
当你用这种方式做决策时,会慢慢意识到一件事:你不再是在"选单位",而是在设计一套尺寸关系。一旦关系是清晰的,代码本身就会变得更加稳定、可预测,同时也更容易维护。这才是 CSS 单位真正的使用方式。
不过,到这里还只是第一步。如果你已经接受了"尺寸关系模型"的视角,那么接下来一个更贴近真实开发的问题就会浮现出来:在实际项目中,我们几乎不会只使用一种单位------那不同类型的单位应该如何组合使用?
这一步,才是真正体现 CSS 能力的地方。因为一旦进入"混合使用",你所做的就不再只是选择某一种关系,而是在有意识地组合多种关系,让它们在同一个系统中协同工作。
混合使用的本质:叠加多个"跟随逻辑"
在讨论"混合使用"之前,需要先把一件事说清楚:混合单位并不是随意拼凑,而是在同一个元素上,有意识地叠加不同层级的"依附关系" 。每一种单位,都在负责一部分逻辑,而不是彼此冲突。
举个最简单的例子:
CSS
.card {
padding: 1rem 2em;
}
这段代码里,其实同时存在两种关系。1rem 绑定的是全局系统,用来保证整体的一致性;而 2em 则跟随组件内部的字体大小,用来维持局部的协调性。
从结果来看,这并不是混乱,而是一种分工:全局负责统一规则,局部负责自适应细节。正是这种"关系的叠加",让组件既能融入整体系统,又能在自身内部保持灵活性。
最常见的组合:全局 + 局部(rem + em)
这是最推荐、也最稳定的一种组合方式:让不同层级的关系各司其职,而不是互相干扰 。一个常见且有效的模式是------用 rem 定义基础尺寸,用 em 来做组件内部的比例调整。
例如一个按钮组件:
CSS
.button {
font-size: 1rem; /* 全局控制 */
padding: 0.5em 1.2em; /* 局部跟随 */
border-radius: 0.5rem; /* 系统统一 */
}
这里的结构其实非常清晰。按钮的整体尺寸(如字体大小、圆角)是绑定在全局系统上的,因此可以保持一致性;而内部的间距(padding)则依赖自身字体,从而能够随着组件大小自然缩放。
这种组合方式的核心在于分层:全局负责统一规则,局部负责内部协调。最终的效果是,组件既能融入整体设计系统,又能在自身范围内保持灵活性------既统一,又不僵硬。
布局 + 内容:% 或 fr + ch 或 lh
在内容型页面(比如文章或文档)中,一种非常高效且稳定的组合方式是:用布局单位控制结构,用内容单位控制阅读体验。也就是说,先解决"内容放在哪里",再解决"内容读起来是否舒服"。
例如:
CSS
.layout {
display: grid;
grid-template-columns: 1fr min(65ch, 100%);
}
在这个结构中,1fr 负责的是整体布局的空间分配,让页面具备弹性;而 65ch 则用来限制文本的最大行长,从而保证阅读的舒适度。两者关注的层面完全不同,却可以自然协同。
再比如段落间距的处理:
CSS
.article p {
margin-bottom: 1lh;
}
这里使用 lh 来控制间距,使其直接跟随文本节奏变化,而不是依赖固定数值。
从整体来看,这种组合的核心在于分工明确:布局单位决定"块在哪里、占多少空间",而内容单位决定"读起来是否舒适" 。当两者各自负责自己的问题时,页面既能保持结构上的灵活性,又能在阅读体验上更加稳定自然。
响应式组合:rem + vw
这是现代响应式设计中非常常见、也非常实用的一种组合方式。它的核心思路可以概括为一句话:在"稳定"和"流动"之间找到平衡。
例如:
CSS
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
这段代码实际上融合了多层关系。2rem 作为最小值,提供一个基于全局系统的稳定下限;5vw 作为中间值,让字体能够随着视口变化而动态调整;而 4rem 则作为最大值,防止尺寸在大屏上无限增长而失控。
从本质上来看,这种写法并不是简单地混用单位,而是在构建一套"有边界的响应规则":允许尺寸根据环境变化,但同时为这种变化设定清晰的上下限。这样既能获得流动性的优势,又能避免不可控带来的问题。
这种模式的价值在于,它让响应式不再是"要么固定,要么完全流动"的二选一,而是变成一种可控、可设计的连续变化过程。
组件级响应:容器单位 + rem
当你开始使用容器查询单位时,一种非常自然、也非常实用的组合方式就会出现:让容器决定结构,用 rem 维持系统一致性。
例如:
css
.card {
padding: 2rem;
gap: 2cqw;
}
这里其实是两种关系在协同工作。rem 用来定义基础间距,确保组件始终遵循整体设计系统;而 cqw 则根据容器宽度进行微调,让组件在不同空间下都能做出合适的调整。
这种组合的关键在于分工清晰:全局系统负责"统一语言",容器关系负责"适应环境" 。最终的结果是,组件既能够在不同容器中灵活变化,又不会偏离整体设计风格,从而同时具备一致性和适应性。
固定 + 弹性:px + 其他单位
在实际开发中,"完全响应式"并不总是目标。有些细节本身就需要保持稳定,比如 1px 的边框、精细的阴影、或者分隔线。这些元素一旦随着环境变化,反而容易破坏视觉的清晰度和一致性。
因此,一种非常常见且合理的做法是,把不同类型的尺寸分开处理。例如:
CSS
.card {
padding: 1rem;
border: 1px solid #ddd;
}
这里的 rem 用来控制整体结构,让组件能够随着全局系统调整;而 px 则用来锁定细节,确保边框始终保持清晰和稳定。
这种组合方式的核心,其实是一种取舍:让该变化的部分具备弹性,让不该变化的细节保持稳定。当这两者各自发挥作用时,页面既有响应能力,又不会失去精致度,这是一种非常健康且实用的平衡。
calc():显式组合关系
当你需要更精细地控制多种尺寸关系时,可以借助 calc() 把这些关系"写出来"。它的作用,不只是做简单计算,而是把原本隐含在设计中的逻辑,转化为清晰可读的表达。
例如:
CSS
.container {
padding: calc(1rem + 2vw);
}
这里实际上是在组合两种关系:1rem 提供一个稳定的基础间距,而 2vw 让间距可以随着屏幕略微放大。也就是说,这个间距既有全局一致性,又具备一定的响应能力。
再比如:
CSS
.box {
height: calc(100vh - 4rem);
}
这里表达的是另一种常见逻辑:用视口高度作为整体空间,再减去一个固定的导航高度,从而得到实际可用区域。
从本质上看,calc() 的价值在于,它让不同关系之间的组合变得明确且可控。你不再需要在脑中"估算"这些关系,而是可以直接用数学形式把它们表达出来,从而让代码本身就成为设计逻辑的一部分。
当你逐渐熟悉这些单位的组合方式之后,会开始看到一个更高层的模式------不同单位,其实在解决不同"层级"的问题。换句话说,它们并不是随意选择的工具,而是在各自的层面上承担不同职责。
例如,px 更偏向视觉细节层,用来处理那些不应该变化的精细部分;rem 属于设计系统层,负责全局的一致性;em 和 % 则工作在组件内部,用于建立局部的自适应关系;vw、vh 面向页面环境,与屏幕尺寸直接相关;cqw 这样的容器单位属于组件环境层,让组件根据自身空间变化;而 ch、lh 则作用于内容层,用来优化排版和阅读体验。
当这些层级被理清之后,一个非常重要的原则也会变得清晰:在混合使用单位时,最容易出问题的情况,是多个单位在"争夺同一个控制权"。比如,一个尺寸既想跟随视口(vw),又想跟随容器(cqw);或者字体既由 rem 控制,又在嵌套中被 em 不断放大。这种情况下,结果往往会变得不可预测,也更难维护。
为了避免这种问题,可以用一个非常简单但实用的判断方式:在写下任何一个尺寸之前,先问自己一句------这个值,主要由谁来决定? 如果答案是唯一的,那么直接选择对应的单位即可;如果答案涉及多个因素,那么就需要通过组合(例如 clamp()、calc(),或者分层设计)来明确各自的作用边界。
当你开始有意识地"混合关系",而不是简单地"混合单位"时,你会发现一个明显的变化:CSS 不再是一个依赖不断试错的过程,而是变成了一套可以被设计、被推导的系统。这一步,其实就是从"会写 CSS",走向"会设计 CSS"的关键转变。
小结
当你把这些内容全部走完,再回头看最开始的问题------"到底该用 px、rem,还是 vw?"------其实已经不那么重要了。
因为你已经不再依赖某一个"正确答案",而是拥有了一套可以自己推导答案的思考方式。
你会开始从"关系"出发,而不是从"单位"出发;先判断这个尺寸应该跟随谁,再去选择合适的表达方式。很多过去需要反复试错的问题,也会在这个过程中自然消失。
从更长远来看,这种思维方式的价值,并不仅仅局限在 CSS 单位上。它本质上是在训练你用一种更结构化的方式去理解界面:把页面拆成不同层级,把尺寸拆成不同关系,再通过组合让它们协同工作。
当你做到这一点时,CSS 就不再只是"写样式",而是在构建一套有逻辑的系统。
而这,也正是从"能实现设计",走向"能设计系统"的关键一步。