不用 JS 量尺寸:用 CSS 容器查询与 :has() 做自适应卡片布局
【摘要】 做后台页面时,同一张卡片在主内容区是三列,塞进侧栏就只剩一列。用媒体查询判断视口宽度并不准确:卡片本身没变,布局却跟着页面走。于是有人用 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)