媒体查询

75 阅读6分钟

1. 媒体查询基本概念

什么是媒体查询?

媒体查询是CSS3的功能,允许根据设备特性(如屏幕宽度、高度、方向等)应用不同的样式规则。

基本语法结构

css

@media media-type and (media-feature) {
  /* CSS规则 */
}

2. 媒体查询核心语法

媒体类型

css

@media screen {
  /* 屏幕设备 */
}

@media print {
  /* 打印设备 */
}

@media speech {
  /* 屏幕阅读器 */
}

@media all {
  /* 所有设备 */
}

媒体特性

css

/* 宽度相关 */
@media (min-width: 768px) {}    /* 最小宽度 */
@media (max-width: 1024px) {}   /* 最大宽度 */
@media (width: 768px) {}        /* 精确宽度 */

/* 高度相关 */
@media (min-height: 600px) {}
@media (max-height: 800px) {}

/* 方向 */
@media (orientation: portrait) {}  /* 竖屏 */
@media (orientation: landscape) {} /* 横屏 */

/* 分辨率 */
@media (min-resolution: 2dppx) {}  /* 最小分辨率 */
@media (max-resolution: 1.5dppx) {}

/* 其他特性 */
@media (hover: hover) {}          /* 支持悬停 */
@media (pointer: fine) {}         /* 精确指针(鼠标) */
@media (pointer: coarse) {}       /* 粗糙指针(触摸) */

逻辑操作符

css

/* AND 操作符 */
@media screen and (min-width: 768px) and (max-width: 1024px) {}

/* OR 操作符 */
@media (min-width: 768px), (orientation: landscape) {}

/* NOT 操作符 */
@media not screen and (min-width: 768px) {}

/* ONLY 操作符 */
@media only screen and (min-width: 768px) {}

3. 项目中的断点设置

常见的断点策略

Bootstrap 5 断点

css

/* 超小屏幕 (手机) */
@media (max-width: 575.98px) { /* xs */ }

/* 小屏幕 (平板竖屏) */
@media (min-width: 576px) and (max-width: 767.98px) { /* sm */ }

/* 中等屏幕 (平板横屏) */
@media (min-width: 768px) and (max-width: 991.98px) { /* md */ }

/* 大屏幕 (桌面) */
@media (min-width: 992px) and (max-width: 1199.98px) { /* lg */ }

/* 超大屏幕 */
@media (min-width: 1200px) { /* xl */ }

/* 超超大屏幕 */
@media (min-width: 1400px) { /* xxl */ }

移动优先断点

css

/* 基础样式 - 移动设备优先 */
.container {
  padding: 1rem;
  font-size: 14px;
}

/* 平板 */
@media (min-width: 768px) {
  .container {
    padding: 1.5rem;
    font-size: 16px;
  }
}

/* 桌面 */
@media (min-width: 1024px) {
  .container {
    padding: 2rem;
    font-size: 18px;
  }
}

/* 大桌面 */
@media (min-width: 1440px) {
  .container {
    padding: 3rem;
    max-width: 1200px;
    margin: 0 auto;
  }
}

4. 实际项目应用示例

响应式导航栏

css

/* 移动端导航 */
.navbar {
  display: flex;
  flex-direction: column;
  background: #333;
}

.nav-menu {
  display: none;
  flex-direction: column;
}

.nav-toggle {
  display: block;
  color: white;
  font-size: 1.5rem;
  background: none;
  border: none;
}

/* 平板及以上 */
@media (min-width: 768px) {
  .navbar {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
  }
  
  .nav-menu {
    display: flex !important;
    flex-direction: row;
    gap: 2rem;
  }
  
  .nav-toggle {
    display: none;
  }
}

响应式网格布局

css

/* 移动端:单列 */
.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}

/* 平板:两列 */
@media (min-width: 768px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
  }
}

/* 桌面:三列 */
@media (min-width: 1024px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
  }
}

/* 大桌面:四列 */
@media (min-width: 1440px) {
  .grid {
    grid-template-columns: repeat(4, 1fr);
    max-width: 1200px;
    margin: 0 auto;
  }
}

响应式字体大小

css

/* 基础字体大小 */
html {
  font-size: 14px;
}

/* 平板 */
@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

/* 桌面 */
@media (min-width: 1024px) {
  html {
    font-size: 18px;
  }
}

/* 使用rem单位 */
h1 {
  font-size: 2rem; /* 响应式缩放 */
  margin-bottom: 1rem;
}

p {
  font-size: 1rem;
  line-height: 1.6;
}

5. 高级媒体查询技巧

深色模式支持

css

/* 浅色模式(默认) */
:root {
  --bg-color: #ffffff;
  --text-color: #333333;
  --primary-color: #007bff;
}

/* 深色模式 */
@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #1a1a1a;
    --text-color: #ffffff;
    --primary-color: #4dabf7;
  }
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
  transition: background-color 0.3s ease, color 0.3s ease;
}

减少动画支持

css

/* 正常动画 */
.animated-element {
  animation: slideIn 0.5s ease-out;
}

/* 用户偏好减少动画 */
@media (prefers-reduced-motion: reduce) {
  .animated-element {
    animation: none;
    transition: none;
  }
  
  * {
    scroll-behavior: auto;
  }
}

高对比度模式

css

@media (prefers-contrast: high) {
  .button {
    border: 2px solid currentColor;
  }
  
  .link {
    text-decoration: underline;
  }
}

触摸设备检测

css

/* 鼠标设备 */
@media (hover: hover) and (pointer: fine) {
  .menu-item:hover {
    background-color: #f0f0f0;
  }
}

/* 触摸设备 */
@media (hover: none) and (pointer: coarse) {
  .menu-item:active {
    background-color: #f0f0f0;
  }
}

6. 项目组织最佳实践

方法一:按断点组织CSS

css

/* base.css - 基础样式 */
.container { max-width: 100%; }

/* mobile.css - 移动端样式 */
@media (max-width: 767px) {
  .sidebar { display: none; }
}

/* tablet.css - 平板样式 */
@media (min-width: 768px) and (max-width: 1023px) {
  .sidebar { width: 200px; }
}

/* desktop.css - 桌面样式 */
@media (min-width: 1024px) {
  .sidebar { width: 300px; }
}

方法二:移动优先(推荐)

css

/* 基础样式 - 移动设备 */
.component {
  padding: 1rem;
  font-size: 14px;
  margin-bottom: 1rem;
}

/* 平板 */
@media (min-width: 768px) {
  .component {
    padding: 1.5rem;
    font-size: 16px;
    margin-bottom: 1.5rem;
  }
}

/* 桌面 */
@media (min-width: 1024px) {
  .component {
    padding: 2rem;
    font-size: 18px;
    margin-bottom: 2rem;
    display: flex;
    gap: 2rem;
  }
}

方法三:使用CSS变量管理断点

css

:root {
  --breakpoint-sm: 576px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 992px;
  --breakpoint-xl: 1200px;
  --breakpoint-xxl: 1400px;
}

@media (min-width: var(--breakpoint-md)) {
  .container {
    max-width: 720px;
    margin: 0 auto;
  }
}

@media (min-width: var(--breakpoint-lg)) {
  .container {
    max-width: 960px;
  }
}

7. 常见问题与解决方案

1. 断点重叠问题

css

/* ❌ 错误:断点重叠 */
@media (min-width: 768px) { /* 样式A */ }
@media (min-width: 1024px) { /* 样式B */ }

/* ✅ 正确:使用max-width限制 */
@media (min-width: 768px) and (max-width: 1023px) { /* 平板样式 */ }
@media (min-width: 1024px) { /* 桌面样式 */ }

2. 性能优化

css

/* ❌ 避免过多媒体查询 */
@media (min-width: 320px) { /* 样式 */ }
@media (min-width: 321px) { /* 样式 */ }

/* ✅ 合理的断点间隔 */
@media (min-width: 576px) { /* 样式 */ }
@media (min-width: 768px) { /* 样式 */ }

3. 移动优先vs桌面优先

css

/* ✅ 移动优先(推荐) */
.element { 
  /* 移动端样式 */
  width: 100%; 
}

@media (min-width: 768px) {
  .element { 
    /* 覆盖移动端样式 */
    width: 50%; 
  }
}

/* ❌ 桌面优先(不推荐) */
.element { 
  /* 桌面端样式 */
  width: 50%; 
}

@media (max-width: 767px) {
  .element { 
    /* 需要重置很多样式 */
    width: 100%; 
  }
}

8. 现代CSS替代方案

Container Queries(容器查询)

css

.component {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .component {
    /* 根据容器宽度调整样式 */
    display: flex;
  }
}

CSS Grid 和 Flexbox 的响应式

css

/* 自动响应式网格 */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

/* 弹性响应式 */
.flex-container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.flex-item {
  flex: 1 1 300px; /* 基础300px,可伸缩 */
}

总结

媒体查询是现代响应式Web设计的核心工具。掌握其正确使用方法可以:

  1. 创建真正的响应式设计 - 适应各种设备和屏幕尺寸
  2. 提升用户体验 - 根据设备特性优化交互
  3. 提高可维护性 - 通过合理的断点策略组织代码
  4. 增强可访问性 - 支持用户偏好设置

在实际项目中,建议采用移动优先的策略,结合CSS变量管理断点,并考虑使用现代布局技术(Grid、Flexbox)来减少对媒体查询的依赖。