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 变量,让样式代码更好维护。