响应式组件,不应该只盯着浏览器窗口

当同一个组件出现在首页主栏、文章侧栏、弹窗和管理面板里,视口宽度不再能准确描述它真正拥有的空间。容器查询让组件根据父容器的实际尺寸决定形态,而不是猜测浏览器窗口有多宽。

做响应式页面时,最常见的写法是根据视口宽度切换布局。页面只有一套固定结构时,这种方法很直接。但当同一个组件会出现在首页主栏、文章侧栏、弹窗和管理面板里,视口宽度就不再能准确描述它真正拥有的空间。

一张文章卡片在大屏幕上可能只分到三百像素,也可能占据整行。传统媒体查询看到的都是同一个大屏幕,于是组件只能依赖页面级样式补丁:放在侧栏时加一个类,进入弹窗时再覆盖一次,换到另一个页面继续追加规则。时间一长,组件看似复用,实际上和每个页面都绑在一起。

容器查询解决的是这个问题:组件根据父容器的实际尺寸决定自己的形态,而不是猜测浏览器窗口有多宽。先给承载组件的元素声明容器,再在组件内部描述不同宽度下的变化。这样决定布局的依据回到了组件附近。

一个实用的卡片可以只准备三种状态。空间较窄时,图片放在上方,标题限制行数,次要说明隐藏;空间适中时,图片与文字左右排列;空间足够宽时,再展示摘要、标签和辅助动作。组件不需要知道自己位于首页还是管理页,只需要知道当前容器能否容纳这些信息。

实现时可以从最小状态开始。默认样式保证在最窄空间里仍然可读,然后逐级增强。例如先让卡片纵向排列,再在容器达到适中宽度后改为两列。容器更宽时,可以增加图片比例、放开摘要行数,但不要因为空间变大就把所有信息都塞回来。响应式设计的目标不是填满区域,而是保持清晰的阅读顺序。

容器查询也适合处理组件内部的小差异。标题字号可以随容器变化,操作区可以从图标变成带文字按钮,元信息可以从单行压缩改为多行分组。配合容器查询单位,还能让内边距和标题尺寸在一个有限区间内平滑变化,减少突然跳档的感觉。

不过,容器查询不是把媒体查询全部替换掉。页面级导航、全局留白、整页分栏仍然与设备和视口有关,继续使用媒体查询更自然。容器查询更适合组件内部:当一个模块需要在多个位置复用,而且每个位置得到的宽度不同,就让组件观察容器;当变化关系属于整个页面,就继续观察视口。

实际改造旧项目时,不必一次重写全部样式。先挑一个补丁最多、复用范围最广的组件,把页面专用覆盖列出来,再把这些覆盖归纳为空间较窄、适中和宽阔三类。改造完成后,把组件分别放进几个不同宽度的测试容器,检查标题换行、图片裁切、按钮触控面积和横向溢出。只要组件脱离原页面后仍能稳定工作,这次改造就有价值。

容器查询真正带来的改变,不只是多了一种 CSS 语法,而是让组件重新拥有自己的布局规则。页面负责决定组件放在哪里,容器负责告诉组件有多少空间,组件自己决定如何呈现内容。三者边界清楚后,复用才不再意味着复制一组新的覆盖样式。

响应式组件,不应该只盯着浏览器窗口的抽象主题配图