媒体查询
CSS媒体查询
概述
CSS 媒体查询是响应式网页设计的核心技术,它允许我们根据设备特性(如屏幕尺寸、分辨率、方向等)有条件地应用样式。本文将详细介绍媒体查询的语法、用法、实际应用场景以及最佳实践,帮助您创建适应各种设备的网页布局。
目录
基本概念
什么是媒体查询
媒体查询是 CSS3 的一个模块,允许内容根据设备的特性(如视口宽度、屏幕分辨率、设备方向等)进行渲染。通过媒体查询,我们可以为不同设备提供定制化的样式,而无需改变内容本身。
响应式设计与媒体查询
响应式设计是一种网页设计方法,旨在让网站在各种设备上都能提供最佳的浏览体验。媒体查询是实现响应式设计的关键技术之一,它与流式布局、弹性图片等技术结合使用,使网页能够适应不同的屏幕尺寸和设备特性。
媒体查询语法
基本语法
媒体查询由一个可选的媒体类型和零个或多个媒体特性组成:
@media mediatype and (media-feature-rule) {
/* CSS 规则 */
}
媒体类型
媒体类型指定了媒体查询适用的设备类型:
all
:适用于所有设备print
:适用于打印预览模式和打印页面screen
:适用于屏幕speech
:适用于语音合成器
/* 适用于屏幕设备 */
@media screen {
body {
font-size: 16px;
}
}
/* 适用于打印设备 */
@media print {
body {
font-size: 12pt;
}
}
逻辑操作符
媒体查询支持以下逻辑操作符:
and
:组合多个媒体特性,所有条件都必须满足not
:否定整个媒体查询only
:仅在媒体查询匹配时应用样式(主要用于防止旧浏览器应用样式),
(逗号):相当于 OR 操作符,任一条件满足即可
/* 屏幕宽度在 600px 到 900px 之间 */
@media screen and (min-width: 600px) and (max-width: 900px) {
body {
background-color: lightblue;
}
}
/* 非打印设备 */
@media not print {
body {
background-color: #f0f0f0;
}
}
/* 屏幕宽度小于 600px 或大于 900px */
@media (max-width: 600px), (min-width: 900px) {
.sidebar {
display: none;
}
}
媒体特性
媒体特性描述了输出设备的具体特征。以下是常用的媒体特性:
视口尺寸
/* 视口宽度 */
@media (min-width: 768px) { /* 视口宽度大于等于 768px */ }
@media (max-width: 767px) { /* 视口宽度小于等于 767px */ }
@media (width: 768px) { /* 视口宽度等于 768px */ }
/* 视口高度 */
@media (min-height: 600px) { /* 视口高度大于等于 600px */ }
@media (max-height: 599px) { /* 视口高度小于等于 599px */ }
@media (height: 600px) { /* 视口高度等于 600px */ }
设备方向
/* 横向模式 */
@media (orientation: landscape) {
.container {
flex-direction: row;
}
}
/* 纵向模式 */
@media (orientation: portrait) {
.container {
flex-direction: column;
}
}
显示质量
/* 像素比 */
@media (min-resolution: 2dppx) {
/* 适用于高分辨率屏幕,如 Retina 显示屏 */
.logo {
background-image: url('logo@2x.png');
}
}
/* 颜色深度 */
@media (color) {
/* 适用于彩色屏幕 */
}
@media (monochrome) {
/* 适用于单色屏幕 */
}
指针设备
/* 精确指针设备(如鼠标) */
@media (pointer: fine) {
.button {
padding: 8px 12px;
}
}
/* 不精确指针设备(如触摸屏) */
@media (pointer: coarse) {
.button {
padding: 12px 20px;
}
}
/* 无指针设备 */
@media (pointer: none) {
.tooltip {
display: none;
}
}
用户偏好
/* 暗色模式 */
@media (prefers-color-scheme: dark) {
body {
background-color: #121212;
color: #f0f0f0;
}
}
/* 亮色模式 */
@media (prefers-color-scheme: light) {
body {
background-color: #ffffff;
color: #121212;
}
}
/* 减少动画 */
@media (prefers-reduced-motion: reduce) {
* {
animation: none !important;
transition: none !important;
}
}
实际应用
1. 响应式布局
/* 基础样式(移动优先) */
.container {
width: 100%;
padding: 15px;
}
/* 平板设备 */
@media (min-width: 768px) {
.container {
width: 750px;
margin: 0 auto;
}
}
/* 小型桌面设备 */
@media (min-width: 992px) {
.container {
width: 970px;
}
}
/* 大型桌面设备 */
@media (min-width: 1200px) {
.container {
width: 1170px;
}
}
2. 导航菜单
/* 移动导航(汉堡菜单) */
.nav-menu {
display: none;
}
.nav-toggle {
display: block;
}
/* 桌面导航 */
@media (min-width: 768px) {
.nav-menu {
display: flex;
}
.nav-toggle {
display: none;
}
}
3. 响应式网格
/* 基础网格(单列) */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
/* 平板设备(双列) */
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* 桌面设备(四列) */
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
}
4. 响应式排版
/* 基础排版(小屏幕) */
body {
font-size: 16px;
}
h1 {
font-size: 1.75rem;
}
h2 {
font-size: 1.5rem;
}
/* 中等屏幕 */
@media (min-width: 768px) {
body {
font-size: 17px;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.75rem;
}
}
/* 大屏幕 */
@media (min-width: 1200px) {
body {
font-size: 18px;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem;
}
}
5. 打印样式
/* 打印样式 */
@media print {
/* 隐藏不必要的元素 */
nav, footer, .ads, .comments, .social-buttons {
display: none;
}
/* 调整排版 */
body {
font-size: 12pt;
line-height: 1.5;
color: #000;
background: #fff;
}
/* 显示链接 URL */
a::after {
content: " (" attr(href) ")";
font-size: 0.9em;
}
/* 避免分页问题 */
h1, h2, h3, h4, h5, h6 {
page-break-after: avoid;
}
img {
page-break-inside: avoid;
max-width: 100% !important;
}
}
高级技巧
1. 容器查询
容器查询是一种新兴的技术,允许基于父容器的尺寸而非视口尺寸应用样式:
/* 定义一个查询容器 */
.card-container {
container-type: inline-size;
}
/* 基于容器宽度应用样式 */
@container (min-width: 400px) {
.card {
display: flex;
}
.card-image {
width: 40%;
}
.card-content {
width: 60%;
}
}
2. 特性查询
特性查询允许我们检测浏览器是否支持特定的 CSS 属性或值:
/* 检测是否支持 grid 布局 */
@supports (display: grid) {
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
}
}
/* 检测是否支持 flex 布局(作为回退) */
@supports not (display: grid) {
.container {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 0 0 calc(33.333% - 20px);
margin: 10px;
}
}
3. 嵌套媒体查询
在预处理器(如 Sass)中,可以嵌套媒体查询:
.sidebar {
width: 100%;
@media (min-width: 768px) {
width: 30%;
float: left;
}
.widget {
padding: 15px;
@media (min-width: 992px) {
padding: 20px;
}
}
}
4. 断点管理
使用 CSS 变量管理断点:
:root {
--breakpoint-sm: 576px;
--breakpoint-md: 768px;
--breakpoint-lg: 992px;
--breakpoint-xl: 1200px;
}
@media (min-width: var(--breakpoint-md)) {
.container {
width: 750px;
}
}
浏览器兼容性
媒体查询支持情况
特性 | Chrome | Firefox | Safari | Edge | IE |
---|---|---|---|---|---|
基本媒体查询 | 21+ | 3.5+ | 4+ | 12+ | 9+ |
媒体特性范围语法 | 21+ | 3.5+ | 4+ | 12+ | 9+ |
容器查询 | 105+ | 110+ | 16+ | 105+ | 不支持 |
特性查询 | 28+ | 22+ | 9+ | 12+ | 不支持 |
兼容性处理
对于不支持媒体查询的旧浏览器,可以采用以下策略:
- 渐进增强:先为所有浏览器提供基础样式,然后通过媒体查询为现代浏览器添加增强功能。
/* 基础样式(所有浏览器) */
.container {
width: 100%;
max-width: 1170px;
margin: 0 auto;
}
/* 增强样式(支持媒体查询的浏览器) */
@media (min-width: 768px) {
.container {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 30px;
}
}
- 使用 JavaScript 库:如 Respond.js 可以为 IE8 及更早版本提供媒体查询支持。
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
最佳实践
1. 移动优先设计
从移动设备开始设计,然后逐步扩展到更大的屏幕:
/* 基础样式(移动设备) */
.container {
padding: 15px;
}
.nav {
display: flex;
flex-direction: column;
}
/* 平板设备及以上 */
@media (min-width: 768px) {
.nav {
flex-direction: row;
}
}
这种方法的优势:
- 简化了媒体查询(只需使用
min-width
) - 优先考虑移动用户体验
- 通常产生更简洁的 CSS 代码
2. 使用有意义的断点
不要基于特定设备设置断点,而应根据内容需求选择断点:
/* 不推荐:基于设备的断点 */
/* iPhone X */
@media (min-width: 375px) { ... }
/* iPad */
@media (min-width: 768px) { ... }
/* 推荐:基于内容的断点 */
@media (min-width: 600px) { ... } /* 当内容需要更多空间时 */
@media (min-width: 900px) { ... } /* 当布局需要改变时 */
@media (min-width: 1200px) { ... } /* 当内容可以更宽松排列时 */
3. 避免断点过多
保持断点数量合理,通常 3-4 个主要断点就足够了:
/* 主要断点示例 */
/* 小型设备(手机,小于 600px) */
/* 默认样式,无需媒体查询 */
/* 中型设备(平板,600px 及以上) */
@media (min-width: 600px) { ... }
/* 大型设备(笔记本电脑,900px 及以上) */
@media (min-width: 900px) { ... }
/* 超大型设备(大型显示器,1200px 及以上) */
@media (min-width: 1200px) { ... }
4. 使用相对单位
优先使用相对单位(如 em、rem、%)而非绝对单位(如 px):
/* 不推荐 */
body {
font-size: 16px;
}
.container {
width: 1200px;
}
/* 推荐 */
body {
font-size: 1rem;
}
.container {
width: 90%;
max-width: 75rem;
}
5. 组织媒体查询
有两种主要方式组织媒体查询:
方法一:按组件组织
/* 导航组件 */
.nav {
/* 基础样式 */
}
@media (min-width: 768px) {
.nav {
/* 平板样式 */
}
}
@media (min-width: 1024px) {
.nav {
/* 桌面样式 */
}
}
/* 卡片组件 */
.card {
/* 基础样式 */
}
@media (min-width: 768px) {
.card {
/* 平板样式 */
}
}
方法二:按断点组织
/* 基础样式(所有设备) */
.nav { ... }
.card { ... }
.footer { ... }
/* 平板样式 */
@media (min-width: 768px) {
.nav { ... }
.card { ... }
.footer { ... }
}
/* 桌面样式 */
@media (min-width: 1024px) {
.nav { ... }
.card { ... }
.footer { ... }
}
6. 测试与调试
使用浏览器开发工具模拟不同设备:
- Chrome DevTools 的设备模式
- Firefox 的响应式设计模式
- 实际设备测试
创建一个简单的调试辅助工具:
/* 在开发环境中显示当前断点 */
body::after {
content: "移动设备";
position: fixed;
bottom: 0;
right: 0;
background: black;
color: white;
padding: 5px;
z-index: 9999;
}
@media (min-width: 600px) {
body::after {
content: "平板设备";
background: blue;
}
}
@media (min-width: 900px) {
body::after {
content: "桌面设备";
background: green;
}
}
参考资源
总结
CSS 媒体查询是实现响应式设计的关键技术,它允许我们根据设备特性有条件地应用样式。通过掌握媒体查询的语法、特性和最佳实践,我们可以创建出在各种设备上都能提供良好用户体验的网页。
关键要点:
- 移动优先设计:从小屏幕开始,逐步扩展到大屏幕
- 使用有意义的断点:基于内容需求而非特定设备
- 保持简洁:避免过多断点,使用相对单位
- 考虑用户偏好:如暗色模式、减少动画等
- 测试多种设备:确保在各种屏幕尺寸上的良好表现
随着容器查询等新技术的发展,响应式设计将变得更加灵活和强大,但媒体查询仍将是前端开发中不可或缺的工具。