Skip to content

如何实现一个响应式布局?

响应式布局的核心不是只写媒体查询,而是让布局能够随着可用空间变化而自然调整。

语法
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-ratioheight: auto,不要同时把宽高分别绑定到 vwvh,以免在不同宽高比下拉伸。

固定画布大屏

数据看板、展厅屏等场景有时需要按固定设计尺寸等比展示。此时可保留 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()

缩放不会改变画布的布局尺寸,因此应由外层容器负责居中和裁剪;缩放后的文字与交互区域在小屏上可能过小,不适合作为通用业务页面的适配策略。

注意事项

  • 只改字号和内边距,并不等于真正完成响应式布局。
  • 图片、表格、侧边栏、长单词和代码块通常也是响应式问题高发区。
  • 现代响应式布局通常是媒体查询、弹性布局、流式尺寸共同配合,而不是单靠某一种技术。

基于 MIT 许可发布