DrillLab
第 13 / 105 道13 / 105 · #274

什么是响应式设计,怎么做

What is responsive web design and how to achieve this

先自己答,再往下看Answer it yourself first

一句话:一套代码在不同屏幕尺寸下 都给出合适的排版,而不是给手机单独做一个站。

四个手段,按重要性排:

  • viewport meta——前提,没有它后面全白干(见 #381)。
  • 弹性单位—— 宽度用 % / fr /min() / clamp(), 字号用 rem,别到处写死 pxclamp(16px, 4vw, 24px)一行就能做出「有上下限的流式字号」。
  • 媒体查询——@media (max-width: 768px) 改布局。
  • 弹性布局——flex-wrapgrid-template-columns: repeat(auto-fit, minmax(240px, 1fr)),很多时候一行都不用写媒体查询就自适应了。

会追问:「断点怎么定?」—— 正确答案是「按内容定,不是按设备定」: 把浏览器慢慢拉窄,哪里开始难看就在哪里加断点。 追着 iPhone 型号列表定断点是过时做法, 因为设备尺寸年年变。

还会追问 mobile-first:默认样式写窄屏,用 min-width 往上加。 好处是移动端加载的 CSS 最少, 而且「加东西」比「删东西」好写 —— 用 max-width 往下覆盖经常要反复清理属性。

In one line: one codebase that lays out sensibly at any screen size — rather than building a separate mobile site.

Four techniques, most important first:

  • The viewport meta tag the precondition; without it nothing else matters (see #381).
  • Flexible units — widths in % /fr / min() / clamp(), font sizes in rem; stop hard-coding px everywhere. clamp(16px, 4vw, 24px) gives you a fluid font size with hard limits in a single line.
  • Media queries @media (max-width: 768px) to change layout.
  • Flexible layoutflex-wrap and grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) often adapt without a single media query.

Follow-up: “How do you choose breakpoints?” — the right answer is “from the content, not from device sizes”: drag the window narrower and add a breakpoint wherever it starts looking wrong. Chasing a list of iPhone dimensions is outdated, because device sizes change every year.

They will also ask about mobile-first: write the narrow layout as the default and add to it with min-width. Mobile then downloads the least CSS, and “adding” is easier to reason about than “undoing” — overriding downwards with max-width usually means repeatedly resetting properties.

CSS现在真正会写的响应式示意Illustrative
1/* 不写一行媒体查询的自适应网格 */
2.cards {
3 display: grid;
4 grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
5 gap: 16px;
6}
7
8/* 有上下限的流式字号 */
9h1 { font-size: clamp(24px, 5vw, 44px); }
10
11/* mobile-first:默认窄屏,往上加 */
12.layout { display: block; }
13@media (min-width: 768px) {
14 .layout { display: grid; grid-template-columns: 240px 1fr; }
15}
1/* A responsive grid without a single media query */
2.cards {
3 display: grid;
4 grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
5 gap: 16px;
6}
7
8/* A fluid font size with an upper and lower bound */
9h1 { font-size: clamp(24px, 5vw, 44px); }
10
11/* mobile-first: narrow by default, add from there upwards */
12.layout { display: block; }
13@media (min-width: 768px) {
14 .layout { display: grid; grid-template-columns: 240px 1fr; }
15}