Appearance
CSS 媒体查询
媒体查询是CSS3中的一个模块,允许根据设备特性应用不同的样式。
概述
媒体查询使我们能够根据设备的特性(如屏幕尺寸、分辨率、方向等)来应用不同的CSS样式。
基本语法
基本结构
css
@media media-type and (media-feature) {
/* CSS 规则 */
.element {
color: red;
}
}
媒体类型
css
/* all - 适用于所有设备(默认) */
@media all and (max-width: 768px) {
.element { color: red; }
}
/* screen - 适用于彩色屏幕 */
@media screen and (max-width: 768px) {
.element { color: blue; }
}
/* print - 适用于打印预览和打印页面 */
@media print {
.no-print { display: none; }
}
/* speech - 适用于屏幕阅读器 */
@media speech {
.screen-only { display: none; }
}
媒体特性
视口尺寸
css
/* 宽度相关 */
@media (min-width: 768px) { /* 最小宽度 */
.element { font-size: 16px; }
}
@media (max-width: 767px) { /* 最大宽度 */
.element { font-size: 14px; }
}
@media (width: 1024px) { /* 精确宽度 */
.element { width: 100%; }
}
/* 高度相关 */
@media (min-height: 600px) {
.element { height: 100vh; }
}
@media (max-height: 400px) {
.element { overflow-y: auto; }
}
设备方向
css
@media (orientation: landscape) { /* 横屏 */
.landscape-only { display: block; }
}
@media (orientation: portrait) { /* 竖屏 */
.portrait-only { display: block; }
}
设备特性
css
/* 设备宽度/高度 */
@media (min-device-width: 1024px) {
.desktop { background: blue; }
}
@media (max-device-height: 800px) {
.element { padding: 10px; }
}
/* 设备像素比 */
@media (-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
.high-res-image {
background-image: url('image@2x.jpg');
background-size: 100px 100px;
}
}
逻辑操作符
and 操作符
css
/* 同时满足多个条件 */
@media screen and (min-width: 768px) and (max-width: 1024px) {
.element { background: yellow; }
}
comma (逗号) 分隔符
css
/* 满足任一条件(OR 逻辑) */
@media (max-width: 767px), (orientation: portrait) {
.element { display: block; }
}
not 操作符
css
/* 否定条件 */
@media not screen and (color) {
.element { background: black; }
}
only 操作符
css
/* 仅当整个查询匹配时才应用 */
@media only screen and (max-width: 768px) {
.element { width: 100%; }
}
常用断点
移动设备优先
css
/* 基础样式(移动设备) */
.element {
width: 100%;
font-size: 14px;
}
/* 平板设备 */
@media (min-width: 768px) {
.element {
width: 50%;
font-size: 16px;
}
}
/* 桌面设备 */
@media (min-width: 1024px) {
.element {
width: 33.33%;
font-size: 18px;
}
}
/* 大屏幕 */
@media (min-width: 1200px) {
.element {
width: 25%;
font-size: 20px;
}
}
按设备分类
css
/* 超小屏幕 (手机, 小于768px) */
@media (max-width: 767.98px) {
.xs-only { display: block; }
}
/* 小屏幕 (平板, 768px及以上) */
@media (min-width: 768px) and (max-width: 991.98px) {
.sm-only { display: block; }
}
/* 中等屏幕 (桌面, 992px及以上) */
@media (min-width: 992px) and (max-width: 1199.98px) {
.md-only { display: block; }
}
/* 大屏幕 (大桌面, 1200px及以上) */
@media (min-width: 1200px) {
.lg-only { display: block; }
}
高级媒体特性
颜色特性
css
/* 颜色位深度 */
@media (min-color: 8) { /* 至少8位颜色 */
.element { color: #333; }
}
/* 单色显示器 */
@media (monochrome) {
.element { color: black; }
}
功能特性
css
/* 是否支持触摸 */
@media (pointer: fine) { /* 精确指针(鼠标) */
.hover-effect { cursor: pointer; }
}
@media (pointer: coarse) { /* 粗略指针(触摸) */
.touch-element { padding: 15px; }
}
/* 悬停能力 */
@media (hover: hover) { /* 支持悬停 */
.element:hover { background: lightgray; }
}
@media (hover: none) { /* 不支持悬停 */
.element:active { background: lightgray; }
}
现代媒体查询
容器查询
css
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: flex;
}
.card img {
width: 100px;
}
}
用户偏好媒体查询
css
/* 减少动画偏好 */
@media (prefers-reduced-motion: reduce) {
.animation {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
/* 高对比度偏好 */
@media (prefers-contrast: high) {
.element {
color: #000;
background-color: #fff;
border: 2px solid #000;
}
}
/* 深色模式 */
@media (prefers-color-scheme: dark) {
body {
background-color: #1a1a1a;
color: #ffffff;
}
.card {
background-color: #2d2d2d;
border: 1px solid #444;
}
}
/* 减少透明度偏好 */
@media (prefers-reduced-transparency: reduce) {
.glass-effect {
background-color: rgba(255, 255, 255, 1);
backdrop-filter: none;
}
}
嵌套媒体查询 (CSS4)
css
/* 使用 @custom-media 定义自定义媒体查询 */
@custom-media --viewport-medium (width >= 500px) and (width <= 1200px);
@media (--viewport-medium) {
.element {
padding: 2rem;
}
}
实用示例
响应式网格
css
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (min-width: 1200px) {
.grid {
grid-template-columns: repeat(4, 1fr);
}
}
响应式导航
css
.nav-toggle {
display: none;
}
.navigation {
display: flex;
flex-direction: row;
}
/* 移动端 */
@media (max-width: 767px) {
.nav-toggle {
display: block;
}
.navigation {
display: none;
flex-direction: column;
position: absolute;
top: 100%;
left: 0;
width: 100%;
background: white;
}
.navigation.active {
display: flex;
}
}
响应式字体
css
.responsive-title {
font-size: 1.5rem;
line-height: 1.2;
}
@media (min-width: 768px) {
.responsive-title {
font-size: 2rem;
}
}
@media (min-width: 1024px) {
.responsive-title {
font-size: 2.5rem;
}
}
媒体查询最佳实践
移动优先 vs 桌面优先
css
/* 移动优先方法(推荐) */
.element {
/* 移动端样式 */
width: 100%;
padding: 10px;
}
@media (min-width: 768px) {
.element {
/* 平板及以上样式 */
width: 50%;
padding: 15px;
}
}
@media (min-width: 1024px) {
.element {
/* 桌面端样式 */
width: 25%;
padding: 20px;
}
}
避免设备特定断点
css
/* 避免:特定设备断点 */
@media (max-width: 320px) { /* iPhone 5 */
.element { width: 100%; }
}
/* 推荐:内容驱动的断点 */
@media (max-width: 400px) { /* 内容在该宽度下开始有问题 */
.element { width: 100%; }
}
组织媒体查询
css
/* 方法1:组件内嵌媒体查询 */
.card {
padding: 1rem;
}
@media (min-width: 768px) {
.card {
padding: 2rem;
}
}
/* 方法2:集中式媒体查询 */
.element {
width: 100%;
}
@media (min-width: 768px) {
.element {
width: 50%;
}
}
@media (min-width: 1024px) {
.element {
width: 25%;
}
}
性能考虑
减少复杂查询
css
/* 避免:过于复杂的查询 */
@media screen and (min-width: 576px) and (max-width: 768px) and (orientation: landscape) and (min-resolution: 192dpi) {
.element { color: red; }
}
/* 推荐:简化查询 */
@media (min-width: 768px) and (orientation: landscape) {
.element { color: red; }
}
避免频繁重绘
css
/* 使用不会触发重绘的属性 */
@media (max-width: 768px) {
.element {
transform: translateX(100%);
opacity: 0.8;
}
}
调试媒体查询
使用CSS计数器调试
css
body {
counter-reset: media-query-state;
}
@media (max-width: 767px) {
body::after {
counter-increment: media-query-state;
content: "Mobile: " counter(media-query-state);
}
}
@media (min-width: 768px) and (max-width: 1024px) {
body::after {
counter-increment: media-query-state;
content: "Tablet: " counter(media-query-state);
}
}
@media (min-width: 1025px) {
body::after {
counter-increment: media-query-state;
content: "Desktop: " counter(media-query-state);
}
}
最佳实践
- 使用移动优先的策略
- 选择合适的内容驱动断点而非设备特定断点
- 合理使用逻辑操作符组织复杂查询
- 考虑用户的可访问性偏好
- 避免过于复杂的嵌套查询
- 测试在不同设备和视口尺寸上的效果
- 利用现代媒体查询特性如用户偏好
- 保持性能和用户体验的平衡