不用 JS 量尺寸:用 CSS 容器查询与 :has() 做自适应卡片布局

举报
yd_291533083 发表于 2026/11/02 09:10:23 2026/11/02
【摘要】 做后台页面时,同一张卡片在主内容区是三列,塞进侧栏就只剩一列。用媒体查询判断视口宽度并不准确:卡片本身没变,布局却跟着页面走。于是有人用 JavaScript 监听容器宽度再加类名,能跑通,却多了一层状态同步,异步加载和组件复用时容易出岔子。 容器查询:按容器宽度换布局.card-list { container-type: inline-size; }@container (min-wid...

做后台页面时,同一张卡片在主内容区是三列,塞进侧栏就只剩一列。用媒体查询判断视口宽度并不准确:卡片本身没变,布局却跟着页面走。于是有人用 JavaScript 监听容器宽度再加类名,能跑通,却多了一层状态同步,异步加载和组件复用时容易出岔子。

容器查询:按容器宽度换布局

.card-list { container-type: inline-size; }
@container (min-width: 560px) {
  .card { grid-template-columns: 120px 1fr; }
}

声明后卡片只关心所在容器:宽就左右并排,窄就上下堆叠,同一组件在不同位置表现一致。注意声明 container-type 会建立新的包含块,内部绝对定位浮层的参照会变,写之前先确认。

:has():按内容换布局

以前父元素无法按子元素状态变样式,有图和无图卡片只能靠脚本加类名。现在可以直接写:

.card:has(.card-cover) { grid-template-columns: 120px 1fr; }
.card:not(:has(.card-cover)) { padding: 16px; }

内容变了样式跟着变,模板不用维护两套类名。表单行获得焦点时高亮整行、某项勾选时改变行底色,也都是一条选择器的事。

组合使用

@container (max-width: 420px) {
  .card:has(.card-cover) .card-cover { height: 120px; }
}

窄容器下有图卡片也不坚持并排,图片压成顶部通栏保证可读;宽容器恢复左右结构。先看宽度,再看内容,最后才是样式,推导顺序很清楚。

落地检查

断点要按卡片可读宽度定,别照搬视口断点;默认样式应是可用的单列布局,给旧浏览器留回退;:has() 限定在卡片、行这类小范围,别在整棵树上通配;能用样式表达的规则别交给脚本,避免服务端渲染与客户端水合不一致。

容器查询把判断依据从视口还给组件自身,:has() 让父级能响应子级状态。规则越靠近它描述的元素,复用时越不容易被环境带偏。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。