主题
如何实现一个响应式布局?
响应式布局的核心不是只写媒体查询,而是让布局能够随着可用空间变化而自然调整。
语法
css
@media mediatype and (media feature) {
/* 应用于特定设备属性的样式 */
}mediatype:
all:适用于所有设备类型。print:适用于打印机和打印预览模式。screen:适用于电脑屏幕、平板电脑、智能手机等。speech:适用于屏幕阅读器。
media feature:
width:设备的宽度。height:设备的高度。orientation:设备的方向(横向或纵向)。aspect-ratio:设备的宽高比。resolution:设备的分辨率。
示例,移动端优先:
css
/* 移动端 */
.container {
padding: 10px;
font-size: 14px;
}
/* 平板及以上 */
@media (min-width: 768px) {
.container {
padding: 20px;
font-size: 16px;
}
}
/* 桌面端及以上 */
@media (min-width: 1200px) {
.container {
padding: 40px;
font-size: 20px;
}
}桌面端优先则先定义宽屏样式,再通过 max-width 逐步收缩:
css
.container {
padding: 40px;
font-size: 20px;
}
@media (max-width: 1199px) {
.container {
padding: 20px;
font-size: 16px;
}
}
@media (max-width: 767px) {
.container {
padding: 10px;
font-size: 14px;
}
}新页面通常优先选择移动端优先;当桌面布局是既有基线、窄屏仅需做有限裁剪时,桌面端优先会更直接。
常见思路
- 移动端优先:先写小屏默认样式,再通过
min-width逐步增强。 - 使用弹性布局或网格布局,让元素本身具备伸缩能力。
- 把断点建立在布局变化点上,而不是死记设备型号。
设计稿换算
移动端 rem
可以把根字号设置为视口宽度的固定比例,再将设计稿尺寸换算为 rem。以 375px 宽设计稿、1rem = 37.5px 为例,150px 宽的元素为 4rem。
css
html {
font-size: calc(100vw / 10);
}
.card {
width: 4rem;
height: 2rem;
font-size: 0.64rem;
}不应通过 @media (device-width: ...) 为少数设备逐一设置根字号:设备宽度和浏览器布局视口并不等同,且无法覆盖连续变化的尺寸。文本缩放需求较强时,也应避免把所有字号机械地与根字号绑定。
移动端 vw
视口单位可直接表达设计稿比例。以 375px 宽设计稿为例:
css
.card {
width: calc(150 / 375 * 100vw);
height: calc(75 / 375 * 100vw);
font-size: clamp(14px, calc(24 / 375 * 100vw), 20px);
}对字体使用 clamp() 设置上下限,避免在过窄或过宽视口中出现不可读或过大的文字。图片保持比例时,优先使用 aspect-ratio 或 height: auto,不要同时把宽高分别绑定到 vw 与 vh,以免在不同宽高比下拉伸。
固定画布大屏
数据看板、展厅屏等场景有时需要按固定设计尺寸等比展示。此时可保留 1920 × 1080 画布,再根据可用视口计算缩放比例;这与普通响应式页面不同,普通页面仍应优先使用流式布局。
html
<div class="screen-viewport">
<main class="screen-canvas">...</main>
</div>css
.screen-viewport {
display: grid;
width: 100vw;
height: 100vh;
overflow: hidden;
place-items: center;
}
.screen-canvas {
width: 1920px;
height: 1080px;
transform: scale(var(--screen-scale, 1));
transform-origin: center;
}js
const canvas = document.querySelector('.screen-canvas')
function updateScale() {
const scale = Math.min(window.innerWidth / 1920, window.innerHeight / 1080)
canvas?.style.setProperty('--screen-scale', String(scale))
}
window.addEventListener('resize', updateScale)
updateScale()缩放不会改变画布的布局尺寸,因此应由外层容器负责居中和裁剪;缩放后的文字与交互区域在小屏上可能过小,不适合作为通用业务页面的适配策略。
注意事项
- 只改字号和内边距,并不等于真正完成响应式布局。
- 图片、表格、侧边栏、长单词和代码块通常也是响应式问题高发区。
- 现代响应式布局通常是媒体查询、弹性布局、流式尺寸共同配合,而不是单靠某一种技术。
