从 vw/vh 到 clamp(),前端响应式设计的痛点与进化

一、原生响应式设计的痛点
1、使用 vw/vh/% 的蜜月期与矛盾点
在长期前端开发实践中,曾经深信'响应式设计'是前端布局的终极解法。于是在 Vue 项目中大量使用了 vw、vh、% 等相对单位,期望一套布局能在所有设备上自然伸缩。尤其是首页大屏的文字,可以使用 vw 设置字号和外层容器宽度来实现不同屏幕一行文字数量相同的效果,体验很不错。
font-size: 0.3vw
但这种设计存在一个致命的问题,如果在 16 寸笔记本上显示合理,一切看起来都很完美,那么在 27 寸显示屏上文字就会巨大得夸张、间距极度拉大会显得很不协调。在一些更小尺寸笔记本/pad 或超宽屏显示器上,整个布局又显得拥挤或者极度分散。
局部响应式设计的好体验会在全局响应式设计中'失真'、'失活',最终两边都不讨好,只能满足模块不相互重叠,不挤占空间的底线要求(那与 flex 布局相比又有什么优越性呢?)

2、以 px+@media 为主轴实现多端样式兼容
在苦求无解的挣扎后,又回到了 px 固定尺寸的怀抱,再用 @media 去针对不同分辨率做细粒度适配。事实上这也是常见的 CSS 高级教程所推荐的成熟方案。通过 px 给出合适美观的元素内容和留白设计,再通过 @media 识别设备的分辨率宽度,针对不同场景给出不同的 css 设计方案。
但这样又带来了新的痛苦,@media 规则暴增,维护成本极高;每次改动一处样式,都要担心会不会破坏别的元素设计;项目规模稍大,样式文件就像'层层叠叠的补丁堆'。可读性差,维护成本高,每次做更新维护都让人非常痛苦。而且甲方不会考虑维护 @media 所需的时间,只会问'为什么需求简单维护时间这么长?'
后来接触到 Tailwind CSS 之后这个情况变得更加糟糕,Tailwind CSS 带来了极大的开发爽感,但响应式设计同样麻烦,需要用到一个映射表:
| 前缀 | 最小宽度 | CSS 等效 |
|---|---|---|
sm | 640px | @media (min-width: 640px) |
md | 768px | @media (min-width: 768px) |
lg | 1024px | @media (min-width: 1024px) |
xl | 1280px | @media (min-width: 1280px) |
2xl | 1536px | @media (min-width: 1536px) |
<!-- sm、md、lg 分别对应在不同屏幕范围下的 font-size 值 -->
<>标题


