CSS Media Query 完整教程:让你的网页适配所有设备

目录

  1. 什么是 Media Query?
  2. 为什么要使用 Media Query?
  3. 基本语法
  4. 最常用的媒体特性
    • widthheight (视口尺寸)
    • orientation (屏幕方向)
    • resolution (屏幕分辨率)
    • hoverpointer (输入设备)
  5. 实践:构建一个简单的响应式布局
  6. 最佳实践与技巧
    • 移动优先 vs. 桌面优先
    • 使用相对单位
    • 测试的重要性
  7. 高级用法
    • @media 与其他 规则结合
    • 使用媒体查询进行内容切换

什么是 Media Query?

Media Query (媒体查询) 是 CSS3 的一个强大功能,它允许你根据设备的特征(如屏幕宽度、高度、方向、分辨率等)来应用不同的 CSS 样式。

media query 教程
(图片来源网络,侵删)

它就像一个“条件判断”语句,你可以告诉浏览器:“如果屏幕宽度小于 768 像素,那么就应用这些样式;否则,就应用那些样式。

这使得我们能够创建响应式网页,即同一个网页可以在不同尺寸的设备(如手机、平板、桌面电脑)上都能获得良好的浏览体验。


为什么要使用 Media Query?

在早期,网页主要是为桌面设计的,随着智能手机和平板电脑的普及,网页需要在各种屏幕尺寸上显示。

没有 Media Query 的情况:

media query 教程
(图片来源网络,侵删)
  • 在手机上,网页会显示得很小,需要用户手动缩放和水平滚动。
  • 布局可能会错乱,内容重叠或溢出。

使用 Media Query 的好处:

  • 提升用户体验自动适配设备,无需用户手动操作。
  • 内容优先级:在小屏幕上可以隐藏次要内容,突出主要信息。
  • 布局优化:可以调整列数、字体大小、间距等,使其在特定设备上更美观易读。
  • 避免无障碍问题:确保所有用户都能方便地访问你的网站。

基本语法

Media Query 通常有两种形式:外部链接内部样式

a) 在 <link> 标签中使用

这是最常见的方式,用于加载不同的 CSS 文件。

<!-- 默认样式,适用于所有设备 -->
<link rel="stylesheet" href="styles.css">
<!-- 当屏幕宽度小于等于 768px 时,加载这个文件 -->
<link rel="stylesheet" href="styles-mobile.css" media="(max-width: 768px)">

b) 在 <style> 标签中使用

将 Media Query 直接写在 CSS 文件中,这是更灵活、更常用的方法。

media query 教程
(图片来源网络,侵删)
/* 默认样式,应用于所有设备 */
body {
  font-size: 16px;
  background-color: #f0f0f0;
}
/* 当屏幕宽度小于等于 768px 时,应用这些样式 */
@media (max-width: 768px) {
  body {
    font-size: 14px; /* 字体变小 */
    background-color: #e0e0e0; /* 背景色稍深 */
  }
}

语法结构:

@media 后面跟着一个或多个媒体特性,用括号 包裹,你可以使用逻辑操作符来组合多个条件。

  • 逻辑操作符:
    • and: 逻辑与,必须同时满足所有条件。
      @media (min-width: 768px) and (orientation: landscape) { ... }
    • 逻辑或,满足其中一个条件即可(相当于 or)。
      @media (max-width: 600px), (orientation: portrait) { ... }
    • not: 逻辑非,排除某个条件。
      @media not (print) { ... } /* 适用于所有非打印设备 */
    • only: 用于防止旧版浏览器(如 IE9 及以下)应用样式,它们会忽略整个 @media 规则。
      @media only screen and (max-width: 768px) { ... }

最常用的媒体特性

这里我们介绍一些最核心、最常用的媒体特性。

a) widthheight (视口尺寸)

这是响应式设计中最常用的特性。

  • min-width: 当视口大于或等于指定宽度时生效。
  • max-width: 当视口小于或等于指定宽度时生效。

常见断点:

  • 手机: max-width: 480pxmax-width: 768px
  • 平板: min-width: 769pxmax-width: 1024px
  • 桌面: min-width: 1025px

示例:

/* 适用于所有设备的基础样式 */
.container {
  width: 1200px;
  margin: 0 auto;
  padding: 20px;
  display: flex;
  gap: 20px;
}
.sidebar {
  flex: 1;
  background-color: #ccc;
}
.main-content {
  flex: 3;
  background-color: #ddd;
}
/* 当屏幕宽度小于等于 768px (平板或手机) */
@media (max-width: 768px) {
  .container {
    width: 100%; /* 容器宽度占满屏幕 */
    flex-direction: column; /* 改为纵向排列 */
  }
  .sidebar, .main-content {
    width: 100%; /* 侧边栏和主内容都占满宽度 */
  }
}

b) orientation (屏幕方向)

判断设备是横屏 (landscape) 还是竖屏 (portrait)。

  • orientation: landscape
  • orientation: portrait

示例:

/* 竖屏时,使用单列布局 */
@media (orientation: portrait) {
  .flex-container {
    flex-direction: column;
  }
}
/* 横屏时,使用双列布局 */
@media (orientation: landscape) {
  .flex-container {
    flex-direction: row;
  }
}

c) resolution (屏幕分辨率)

主要用于针对高分辨率屏幕(如 Retina 屏幕)优化。

  • min-resolution: 当设备分辨率大于或等于指定值时生效。
  • max-resolution: 当设备分辨率小于或等于指定值时生效。
  • dpi (dots per inch), dpcm (dots per centimeter), dppx (dots per pixel unit)

示例:

/* 为高分辨率屏幕提供更清晰的背景图 */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .logo {
    background-image: url('logo@2x.png'); /* 使用两倍大小的图片 */
    background-size: contain; /* 确保图片正确缩放 */
  }
}

d) hoverpointer (输入设备)

这是一个非常现代且有用的特性,可以检测用户是否使用悬停操作或鼠标指针。

  • hover: 检测设备是否支持悬停操作。
    • hover: none: 在没有指针的设备(如触摸屏)上,链接点击后不会出现悬停效果。
    • hover: hover: 在有指针的设备(如鼠标)上,悬停效果有效。
  • pointer: 检测设备的主要输入设备。
    • pointer: coarse: 粗指针,如手指触摸。
    • pointer: fine: 精指针,如鼠标光标。

示例:

/* 默认样式,链接有下划线 */
a {
  text-decoration: underline;
}
/* 在不支持悬停的设备上(如触摸屏),移除点击时的下划线 */
@media (hover: none) {
  a:active { /* :active 表示被点击时 */
    text-decoration: none;
  }
}
/* 在精指针设备上(如鼠标),悬停时改变颜色 */
@media (pointer: fine) {
  a:hover {
    color: blue;
  }
}

实践:构建一个简单的响应式布局

让我们动手创建一个包含头部、导航、主内容区和页脚的简单响应式页面。

HTML (index.html):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">响应式布局示例</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
        <h1>我的网站</h1>
    </header>
    <nav>
        <ul>
            <li><a href="#">首页</a></li>
            <li><a href="#">lt;/a></li>
            <li><a href="#">服务</a></li>
            <li><a href="#">联系</a></li>
        </ul>
    </nav>
    <main>
        <section class="content">
            <h2>主要内容</h2>
            <p>这是一些主要内容,展示在桌面和平板上。</p>
        </section>
        <aside class="sidebar">
            <h3>侧边栏</h3>
            <p>这是侧边栏内容,在手机上会移到主内容下方。</p>
        </aside>
    </main>
    <footer>
        <p>&copy; 2025 我的网站</p>
    </footer>
</body>
</html>

CSS (style.css):

/* --- 基础样式 (所有设备) --- */
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    line-height: 1.6;
}
header, nav, main, footer {
    border: 1px solid #ccc;
    margin: 10px;
    padding: 10px;
}
header { background-color: #f4f4f4; }
nav { background-color: #333; }
nav ul { list-style-type: none; margin: 0; padding: 0; }
nav a { color: white; text-decoration: none; display: block; padding: 10px; }
nav a:hover { background-color: #555; }
main { display: flex; gap: 20px; }
.content { flex: 3; }
.sidebar { flex: 1; background-color: #f9f9f9; }
footer { text-align: center; background-color: #333; color: white; }
/* --- 平板和手机 (屏幕宽度小于等于 768px) --- */
@media (max-width: 768px) {
    main {
        flex-direction: column; /* 主内容区和侧边栏变为纵向排列 */
    }
    .content, .sidebar {
        width: 100%; /* 两者都占满宽度 */
    }
    nav ul {
        display: flex; /* 导航菜单变为横向 */
        flex-wrap: wrap; /* 允许换行 */
    }
    nav li {
        flex: 1; /* 每个菜单项平均分配空间 */
    }
}
/* --- 手机 (屏幕宽度小于等于 480px) --- */
@media (max-width: 480px) {
    nav ul {
        flex-direction: column; /* 导航菜单变回纵向 */
    }
    header h1 {
        font-size: 1.5em; /* 标题变小 */
    }
}

效果:

  • 桌面 (> 768px): 主内容区和侧边栏左右排列,导航菜单横向。
  • 平板 (<= 768px): 主内容区和侧边栏上下排列,导航菜单横向换行。
  • 手机 (<= 480px): 所有内容都是纵向排列,导航菜单也变为纵向。

最佳实践与技巧

a) 移动优先 vs. 桌面优先

  • 移动优先: 先为小屏幕设备编写基础样式,然后使用 min-width 媒体查询逐步为更大的屏幕添加样式。

    /* 基础样式 (移动端) */
    body { font-size: 14px; }
    /* 平板 */
    @media (min-width: 768px) {
      body { font-size: 16px; }
    }
    /* 桌面 */
    @media (min-width: 1024px) {
      body { font-size: 18px; }
    }

    优点: 代码更干净,加载更快(因为只加载了移动端的基础样式,没有多余的桌面端样式干扰),符合现代网络趋势。

  • 桌面优先: 先为桌面编写样式,然后使用 max-width 媒体查询为小屏幕“修复”布局。

    /* 基础样式 (桌面端) */
    body { font-size: 18px; }
    /* 平板 */
    @media (max-width: 1024px) {
      body { font-size: 16px; }
    }
    /* 手机 */
    @media (max-width: 768px) {
      body { font-size: 14px; }
    }

    缺点: 可能会加载一些不必要的桌面端样式到移动设备上。

建议: 优先使用“移动优先”

b) 使用相对单位

为了确保布局在不同屏幕上能灵活伸缩,请多使用相对单位,如:

  • (百分比)
  • em / rem (相对于当前字体大小)
  • vw / vh (相对于视口宽度和高度的百分比)
  • flexbox, grid (现代布局方式,天生响应式)

c) 测试的重要性

不要只依赖浏览器的开发者工具进行测试,一定要在真实的设备上进行测试,或者使用在线测试工具(如 BrowserStack)。


高级用法

a) @media 与其他 规则结合

你可以将 Media Query 与 @container (CSS Container Queries) 结合,但 @media 是最基础的。

b) 使用媒体查询进行内容切换

除了改变样式,你还可以使用 Media Query 来加载不同的 HTML 内容(虽然不推荐,因为不利于 SEO,但有时是必要的),这通常通过 JavaScript 实现。


Media Query 是响应式网页设计的基石,通过它,你可以:

  1. 检测设备特征:如屏幕宽度、方向、分辨率等。
  2. 应用条件样式:根据检测结果,动态地改变网页的布局、颜色、字体等。
  3. 创建无缝体验:让你的网站在手机、平板、桌面上都表现得体。

从今天起,尝试在你自己的项目中使用 Media Query,从最简单的 max-width 开始,逐步探索更多可能性,掌握了它,你就掌握了现代 Web 开发的一项核心技能。