Skip to content

C52. 媒体查询 响应式开发

2.1. @at-rules 支持 CSS 规则的选择性使用

@规则(@-rules) 是 CSS 中用于控制样式作用范围或条件的特殊指令,其中 @media 是响应式开发的核心工具。通过 @media,可以为不同设备或屏幕条件选择性应用样式

🌟 @media 的基本语法

css
/* 基础结构 */
@media <媒体类型> and (媒体特性) {
  /* 只在条件满足时生效的样式 */
}

/* 示例:当屏幕宽度 ≤ 600px 时,背景变浅蓝 */
@media screen and (max-width: 600px) {
  body {
    background-color: lightblue;
  }
}

2.1.1. 媒体类型(media types)

类型说明
screen电脑、手机等屏幕设备
print打印预览样式
all所有设备(默认)
tv电视等低分辨率设备

2.1.2. 媒体特性(media features)

特性说明
min-width设备最小宽度(如 min-width: 600px
max-width设备最大宽度(如 max-width: 768px
orientation屏幕方向(portrait 竖屏 / landscape 横屏)
resolution屏幕分辨率(如 resolution: 2dppx

WARNING

  • 单位需带单位(pxvw 等),无单位默认 px
  • 条件组合需用 andornot 支持但较少用)。

2.2. 通过 @media 支持响应式布局

响应式布局的核心是根据设备特性动态调整页面结构,媒体查询是其实现的关键。

🛠️ 示例:自适应导航栏

css
/* 默认布局(大屏幕) */
nav {
  display: flex;
  gap: 20px;
}

/* 当宽度 ≤ 768px 时,导航折叠为列 */
@media (max-width: 768px) {
  nav {
    flex-direction: column;
    align-items: center;
  }
}

2.2.1. 多条件组合技巧

css
/* 当屏幕宽度在 600px~900px 且横屏时 */
@media (min-width: 600px) and (max-width: 900px) and (orientation: landscape) {
  .image-container {
    width: 50%;
  }
}

/* 当分辨率 ≥ 2dppx(视网膜屏)时 */
@media (min-resolution: 2dppx) {
  img {
    srcset: "high-res.jpg 2x";
  }
}

2.2.2. 响应式最佳实践

  1. 设置视口(viewport) 在 HTML 头部添加:

    html
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    确保页面适配移动设备。

  2. 断点策略 常见断点:

    • 手机:max-width: 600px
    • 平板:max-width: 900px
    • 桌面:min-width: 1024px
  3. 避免过度嵌套 使用多个独立的媒体查询块,而非层层嵌套:

    css
    /* 推荐:独立块 */
    @media (max-width: 768px) { ... }
    @media (max-width: 480px) { ... }
    
    /* 避免:嵌套导致复杂度↑ */
    @media (max-width: 768px) {
      @media (orientation: portrait) { ... }
    }

2.3. Flex 和 Grid 相关属性变化是响应式开发的常见思路

通过媒体查询动态修改 Flex 和 Grid 属性,可实现灵活的布局切换。

2.3.1. Flex 布局的响应式调整

🌟 示例:移动端垂直导航栏

css
/* 默认:水平排列 */
.nav {
  display: flex;
  flex-direction: row;
}

/* 当宽度 ≤ 768px 时,改为垂直排列 */
@media (max-width: 768px) {
  .nav {
    flex-direction: column;
    align-items: center;
  }
}

🌟 示例:自适应图片尺寸

css
.image-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

/* 当宽度 ≤ 600px 时,每行1张 */
@media (max-width: 600px) {
  .image-gallery img {
    flex: 0 0 100%;
  }
}

/* 当宽度 ≤ 900px 时,每行2张 */
@media (max-width: 900px) {
  .image-gallery img {
    flex: 0 0 50%;
  }
}

2.3.2. Grid 布局的响应式调整

🌟 示例:自适应商品列表

css
.product-grid {
  display: grid;
  gap: 20px;
  padding: 20px;
}

/* 默认:3列 */
@media (min-width: 1024px) {
  .product-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* 平板:2列 */
@media (max-width: 1023px) and (min-width: 768px) {
  .product-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* 手机:1列 */
@media (max-width: 767px) {
  .product-grid {
    grid-template-columns: 1fr;
  }
}

🌟 示例:动态网格间距

css
/* 根据屏幕宽度调整间距 */
@media (max-width: 600px) {
  .grid-container {
    gap: 10px; /* 移动端减小间距 */
  }
}

2.3.3. 响应式优化技巧

  1. 优先使用相对单位vw%fr,而非固定像素值。
  2. 隐藏多余内容 在小屏幕下隐藏次要元素:
    css
    @media (max-width: 480px) {
      .sidebar {
        display: none;
      }
    }
  3. 结合视口单位
    css
    .header {
      height: 10vh; /* 高度随视口高度变化 */
    }

知识回顾

  1. 媒体查询核心要素
    • 媒体类型(screenprint)、媒体特性(min-widthorientation)、逻辑运算符(and)。
    • 视口设置 <meta name="viewport" ...> 是响应式布局的基础。
  2. Flex 布局响应式
    • 通过 flex-directionflex-wrapflex 属性调整排列方式和占比。
  3. Grid 布局响应式
    • 动态修改 grid-template-columns/rowsgap,或使用 repeat()minmax()
  4. 最佳实践
    • 定义断点分层(如手机→平板→桌面)。
    • 优先使用 @media 在现有样式表中添加规则,减少 HTTP 请求。

课后练习

  1. (单选)以下媒体查询的条件描述正确的是?

    • A. @media (max-width: 600px):屏幕宽度 ≥600px 时生效。
    • B. @media screen and (orientation: portrait):竖屏时生效。
    • C. @media not screen:仅在手机上生效。
    • D. @media (min-resolution: 1dppx):仅适用于低分辨率屏幕。
  2. (填空)使用媒体查询将 .header 的背景色改为红色,当屏幕宽度 ≤ 768px 且横屏时:

    css
    @media (max-width: 768px) and (orientation: ______) {
      .header { background-color: ______; }
    }
  3. (代码题)修复以下代码,使 .sidebar 在 ≤ 600px 宽度时隐藏:

    css
    @media (max-width: 600px) {
      .sidebar { display: none; } /* 正确 */
      .content { width: 100%; }
    }
  4. (实践题)使用媒体查询和 Grid,实现以下布局:

    • 桌面端:3列,列间距20px。
    • 移动端:1列,背景色为浅灰色。

Built by Vitepress | Apache 2.0 Licensed