CSS 媒体查询

很多小伙伴会好奇:“为什么绿叶网在不同尺寸的设备(比如电脑、手机等)查看时,页面效果是不一样的,怎么做到自动适应不同设备的呢?” 其实,这就需要用到 “CSS 媒体查询” 这个技术了。

CSS 媒体查询(Media Query),可以让我们根据不同的设备尺寸来使用不同 CSS 样式的技术。使用媒体查询,可以使网页在各种设备上呈现出最佳的浏览效果,从而提高用户体验。

CSS 媒体查询语法

在 CSS 中,我们可以使用 @media 规则来定义媒体查询。

语法:

@media mediatype and | not | only (media feature) {
    /* CSS 样式 */
}

说明:

​ 下面分别介绍这些的具体用法。

1. mediatype(媒体类型)

​ mediatype 用于指定媒体类型,常用的媒体类型有以下几种。

  • all:所有媒体类型。
  • print:打印机。
  • screen:计算机屏幕、平板电脑、智能手机等。
  • speech:屏幕阅读器等发声设备。

2. and | not | only(逻辑操作符)

​ and | not | only 用于指定媒体查询的条件。

  • and:用于连接多个媒体特征,表示 “且” 的关系。
  • not:用于否定媒体查询,表示 “非” 的关系。
  • only:用于指定某种特定的媒体类型,可以用来排除不支持媒体查询的浏览器。

3. media feature(媒体特征)

​ media feature 用于指定媒体查询的特征,常用的媒体特征有以下几种。

  • width:视口的宽度。
  • height:视口的高度。
  • min-width:视口的最小宽度。
  • max-width:视口的最大宽度。
  • min-height:视口的最小高度。
  • max-height:视口的最大高度。
  • orientation:视口的旋转方向(landscape 或 portrait)。
  • aspect-ratio:视口的宽高比。
  • color:设备的颜色深度。
  • resolution:设备的像素密度。

到这里,初学的小伙伴可能会觉得一脸懵逼,媒体查询这么复杂?怎么学得会呢?其实在实际项目开发中,如果是 PC 优先,我们大多数情况下只会用到下面这种语法:

@media screen and (max-width: 1200px) {
    /* 当屏幕宽度 < 1200px 时应用的样式 */
}

screen 表示根据设备的屏幕宽度(视口宽度)使用指定的样式。(max-width: 1200px) 表示当视口宽度 ≤ 1200px 时,内部定义的样式生效。

如果是移动优先,则会用到下面语法:

@media screen and (min-width: 1200px) {
    /* 当屏幕宽度 ≥ 1200px 时应用的样式 */
}

CSS 媒体查询示例

​ 接下来,我们通过几个简单的例子来讲解 CSS 媒体查询是如何使用的。

示例 1:CSS 定义不同屏幕宽度下的样式

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        /* 默认情况下,body 背景色为粉红色 */
        body {
            background-color: hotpink;
        }
        /* 屏幕宽度小于 1200px 时,body 背景色为天蓝色 */
        @media screen and (max-width: 1200px) {
            body {
                background-color: lightskyblue;
            }
        }
    </style>
</head>
<body>
    <h1>绿叶网 - 为好教程,全力以赴</h1>
</body>
</html>

默认情况下,页面效果如下图 1 所示。当我们改变浏览器窗口大小,使其小于等于 1200px 时,页面效果如下图 2 所示。

CSS 定义不同屏幕宽度下的样式 1

CSS 定义不同屏幕宽度下的样式 2

分析:

在这个例子中,我们使用 @media 规则定义了一个媒体查询。

  • 当屏幕宽度大于 1200px 时,body 的背景色为 hotpink。
  • 当屏幕宽度小于等于 1200px 时,body 的背景色为 lightskyblue。

示例 2:CSS 定义不同设备方向下的样式

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        body {
            background-color: lightskyblue;
        }
        /* 设备处于横向时,body 背景色为橘色 */
        @media screen and (orientation: landscape) {
            body {
                background-color: orange;
            }
        }
        /* 设备处于纵向时,body 背景色为红色 */
        @media screen and (orientation: portrait) {
            body {
                background-color: red;
            }
        }
    </style>
</head>
<body>
    <div>
        <p>绿叶网</p>
    </div>
</body>
</html>

页面效果如下图所示。

CSS 定义不同设备方向下的样式

分析:

在这个例子中,我们使用 @media 规则定义了 2 个媒体查询,分别指定了设备处于横向和纵向时的样式。

  • 默认情况下(未触发媒体查询),背景色为浅蓝色(lightskyblue)。
  • 当设备处于横向(landscape)时,背景色为橘色(yellow)。
  • 当设备处于纵向(portrait)时,背景色为红色(red)。

示例 3:CSS 使用多个媒体特征

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title> 媒体查询示例 </title>
    <style>
        body {
            background-color: lightblue;
        }
        /* 屏幕宽度 ≤ 600px 且设备横向 */
        @media screen and (max-width: 600px) and (orientation: landscape) {
            body {
                background-color: yellow;
            }
        }
    </style>
</head>
<body>
    <div>
        <p>绿叶网 - 为好教程,全力以赴。</p>
    </div>
</body>
</html>

页面效果如下图所示。

CSS 使用多个媒体特征

分析:

在这个例子中,我们使用 and 关键字连接了两个媒体特征,表示需要同时满足屏幕宽度小于 600px 和设备处于横向这两个条件时,body 的背景色才会应用 yellow。

  • 当屏幕宽度小于 600px 且设备处于横向时,body 的背景色为 yellow。
  • 其他情况下,body 的背景色为 lightblue。

示例 4:响应式导航栏(实用场景)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        /* 默认样式:移动端(垂直导航) */
        nav ul {
            list-style: none;
            padding: 0;
            display: flex;
            flex-direction: column;
            gap: 10px;
        }
        nav a {
            text-decoration: none;
            color: white;
            background-color: #333;
            padding: 10px;
            display: block;
        }
        /* 桌面端(水平导航,≥768px) */
        @media screen and (min-width: 768px) {
            nav ul {
                flex-direction: row;
                justify-content: center;
            }
        }
    </style>
</head>
<body>
    <nav>
        <ul>
            <li><a href="#">首页</a></li>
            <li><a href="#">关于</a></li>
            <li><a href="#">服务</a></li>
            <li><a href="#">联系</a></li>
        </ul>
    </nav>
</body>
</html>

当浏览器尺寸大于等于 768px 时,页面效果如下图 1 所示。当浏览器尺寸小于 768px 时,页面效果如下图 2 所示。

CSS 媒体查询实现响应式导航栏 1

CSS 媒体查询实现响应式导航栏 2

分析:

上面例子使用了移动优先设计,也就是使用了 min-width 而不是 max-width 来定义断点。

  • 在移动端(<768px),导航栏为垂直排列。
  • 在桌面端(≥768px),导航栏变为水平排列,居中显示。

CSS 媒体查询进阶

1. 移动优先设计

在做响应式布局设计时,我们应该考虑移动优先设计,也就是推荐使用 min-width 而非 max-width,因为它可以减少 CSS 代码的层叠覆盖,提高网页加载性能。例如:

/* 移动端默认样式 */
body {
    font-size: 16px;
}
/* 桌面端 */
@media screen and (min-width: 768px) {
    body {
        font-size: 18px;
    }
}

2. 响应式图片

在 CSS 中,我们可以结合媒体查询与 picture 元素来实现图片的响应式加载。

<picture>
    <source media="(min-width: 768px)" srcset="large.jpg">
    <img src="small.jpg" alt="示例图片">
</picture>

3. 容器查询

CSS 容器查询(Container Queries)可以看成是 CSS 媒体查询的 “进阶版” ,它使得可以根据容器尺寸而非视口尺寸来应用样式(需先检查浏览器支持):

.container {
    container-type: inline-size;
}
@container (min-width: 300px) {
    .child {
        font-size: 18px;
    }
}

提示: 常用的断点推荐:手机 < 768px,平板 768px~992px,桌面 > 992px。这些断点来源于 Bootstrap 标准断点。

上一篇: CSS 动画

下一篇: CSS 变形

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号