六维教程

CSS 媒体查询

上一篇讲了响应式设计的三大支柱,流式布局和弹性图片已经解决了大部分溢出问题。但光靠它们还不够,有些布局在窄屏和宽屏下应该完全不一样,比如导航栏手机上是竖排、电脑上是横排。这就要靠媒体查询,它是响应式设计里最灵活的一根支柱。

@media 的语法

媒体查询的写法很简单,一个 @media 关键字,后面跟条件,条件成立时花括号里的规则才生效。

@media (max-width: 600px) {
  body {
    background: pink;
  }
}

意思是屏幕宽度不超过 600 像素时,页面背景变成粉色。条件还可以组合,比如要求同时满足”是屏幕设备”和”宽度不小于 768 像素”:

@media screen and (min-width: 768px) {
  .nav {
    display: flex;
  }
}

screen 是媒体类型,表示屏幕设备,主要用来区分打印等场景。and 表示并且,两个条件都要满足才生效。

断点怎么定

写媒体查询必然会遇到一个问题,断点,也就是宽度分界值应该取多少。网上最常见的参考是 Bootstrap 的体系。

断点 对应的屏幕
576px 小屏手机以上
768px 平板竖屏
992px 平板横屏、小电脑
1200px 常规电脑

除了这套,640px 和 1024px 也经常出现。但要记住,这些数字只是参考,不是标准答案。断点应该跟着内容走。比如你的导航栏在 700 像素时开始挤得难看,那就在 700 像素附近切,而不是硬套 768。先做出来,拖动浏览器窗口观察内容在哪里变形,再定断点,这才是正确姿势。

min-width 还是 max-width

这是新手最容易纠结的问题,记住两句口诀就行。

  • min-width 是”达到就生效”,屏幕宽度大于等于这个值,样式才生效
  • max-width 是”超过就失效”,屏幕宽度大于这个值,样式就失效

举个例子,同样是 768 像素这个分界:

/* 写法一,窄屏不生效,宽屏生效 */
@media (min-width: 768px) {
  .sidebar { display: block; }
}

/* 写法二,窄屏生效,宽屏失效 */
@media (max-width: 767px) {
  .sidebar { display: none; }
}

两条规则描述的是同一个切换点,区别只在思考方向。由这个方向,引出两种书写策略。

移动优先还是桌面优先

策略 写法 特点
桌面优先 先写桌面样式,再用 max-width 逐级拆小 老式思路,代码量通常更多
移动优先 先写手机样式,再用 min-width 逐步增强 现代主流,基础样式简单,越往上越丰富

推荐移动优先。原因是手机页面结构简单,写基础样式时思路清晰,电脑端的复杂效果都是往上叠加的增强,用 min-width 一层层加,阅读起来像在讲故事。而且移动端用户占比越来越大,先保证小屏体验是明智的。

完整示例,导航栏

写一个导航栏,电脑上横向排开,手机上变成竖排。

<nav class="nav">
  <a href="#">首页</a>
  <a href="#">教程</a>
  <a href="#">关于</a>
  <a href="#">联系</a>
</nav>
.nav {
  display: flex;
  flex-direction: column;  /* 移动优先,先竖排 */
}

.nav a {
  padding: 0.8rem 1rem;
  text-decoration: none;
  color: #333;
}

/* 屏幕够宽时改横排 */
@media (min-width: 768px) {
  .nav {
    flex-direction: row;
  }
}

注意基础样式里 .nav 是竖排的,媒体查询里才改成横排,这就是移动优先的典型写法。

深色模式也能用媒体查询

媒体查询不仅能问宽度,还能问系统的其他状态。比如用户把操作系统设成了深色模式,可以这样适配:

@media (prefers-color-scheme: dark) {
  body {
    background: #1e1e1e;
    color: #eee;
  }
}

有精力的话,给站点加一套深色主题会是很加分的小细节。

小结

媒体查询的语法很简单,难点在断点取舍和书写策略。记住三件事,断点按内容定别照抄,移动优先用 min-width 从简到繁,宽度之外还能监听深色模式这类系统状态。到这里,响应式设计三大支柱就齐了。下一篇开始讲 CSS 变量,让样式代码更好维护。

上一篇
CSS 响应式设计入门
下一篇
CSS 综合实战