MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

CSS 媒体查询@media规则的响应式设计应用

2021-08-121.5k 阅读

CSS 媒体查询基础

CSS 媒体查询是一种 CSS3 引入的技术,它允许我们根据不同的设备特性(如屏幕宽度、高度、分辨率、方向等)来应用不同的 CSS 样式。这一特性在响应式设计中起着至关重要的作用,使得网页能够适配各种不同的设备,包括桌面电脑、平板电脑和手机等。

媒体查询使用 @media 规则来定义,其基本语法如下:

@media media - type and (media - feature) {
    /* CSS 样式 */
}
  • 媒体类型(media - type):指定应用查询的设备类型,常见的媒体类型有 all(所有设备)、screen(屏幕设备)、print(打印设备)等。
  • 媒体特性(media - feature):用于指定具体的设备特性,例如 width(屏幕宽度)、height(屏幕高度)、orientation(屏幕方向,如 portrait 纵向或 landscape 横向)等。特性后面跟一个冒号和具体的值。

媒体类型详解

  1. all:适用于所有设备类型。这是最常用的媒体类型之一,因为它允许我们定义适用于各种设备的通用样式,同时可以结合媒体特性进一步针对特定设备进行调整。例如:
@media all and (min - width: 768px) {
    body {
        font - size: 16px;
    }
}

上述代码表示当设备屏幕宽度大于或等于 768 像素时,应用 body 元素字体大小为 16 像素的样式,该样式适用于所有设备类型。

  1. screen:专门针对屏幕设备,如电脑显示器、平板电脑和手机屏幕等。我们可以利用这个媒体类型为屏幕设备设置特定的样式,而不会影响到打印或其他非屏幕设备。例如:
@media screen and (max - width: 480px) {
    .navbar {
        display: none;
    }
}

在屏幕宽度小于或等于 480 像素时,上述代码会隐藏类名为 navbar 的元素,通常用于手机等小屏幕设备上,简化导航栏显示。

  1. print:用于打印设备,如打印机。当网页被打印时,我们可以使用这个媒体类型来定义与屏幕显示不同的样式,以优化打印效果。例如:
@media print {
    body {
        color: black;
        background - color: white;
    }
}

这段代码确保在打印时,网页的文字颜色为黑色,背景颜色为白色,这是一种常见的打印样式设置,以节省墨水并提高可读性。

媒体特性深入

  1. width 和 height:这两个特性分别表示设备屏幕的宽度和高度。我们可以使用 min - widthmax - widthmin - heightmax - height 来设置范围。

例如,要在屏幕宽度介于 481 像素到 767 像素之间时应用特定样式:

@media screen and (min - width: 481px) and (max - width: 767px) {
    .container {
        width: 80%;
    }
}

上述代码中,当屏幕宽度满足条件时,类名为 container 的元素宽度将设置为其父元素宽度的 80%。

  1. orientation:用于检测设备的屏幕方向。取值为 portrait(纵向)或 landscape(横向)。例如,在横向屏幕时改变图片的显示样式:
@media screen and (orientation: landscape) {
    img {
        width: 50%;
        height: auto;
    }
}

在横向屏幕设备上,图片宽度将变为其原始宽度的 50%,高度自动适应,以适应不同的屏幕布局。

  1. resolution:表示设备的屏幕分辨率,单位可以是 dpi(每英寸点数)或 dpcm(每厘米点数)。例如,对于高分辨率屏幕(如视网膜屏),我们可以提供更高质量的图片:
@media screen and (min - resolution: 2dppx) {
    img {
        content: url(high - res - image.jpg);
    }
}

当屏幕分辨率达到或超过 2 倍像素密度(2dppx)时,img 元素将显示 high - res - image.jpg 图片,以提供更好的视觉效果。

  1. device - width 和 device - height:与 widthheight 不同,device - widthdevice - height 指的是设备的物理屏幕宽度和高度,而 widthheight 是指浏览器窗口的宽度和高度。这在处理一些特殊情况,如固定布局在不同设备上的适配时可能会用到。例如:
@media screen and (device - width: 320px) and (device - height: 568px) {
    body {
        font - size: 14px;
    }
}

上述代码针对屏幕物理尺寸为 320 像素宽、568 像素高的设备设置特定的字体大小。

逻辑操作符的使用

  1. and:用于连接多个媒体特性,表示所有条件都必须满足才应用样式。前面的例子中已经多次使用到 and,如 @media screen and (min - width: 481px) and (max - width: 767px),只有当设备是屏幕设备且屏幕宽度在指定范围内时,才会应用相应样式。

  2. or:使用 , 来表示逻辑或操作。例如,以下代码表示在屏幕宽度小于 480 像素或者屏幕宽度大于 1200 像素时应用样式:

@media screen and (max - width: 480px), screen and (min - width: 1200px) {
    .hero - image {
        background - size: cover;
    }
}
  1. not:用于否定一个媒体查询。例如,以下代码表示除了屏幕宽度小于 600 像素的屏幕设备外,其他设备都应用样式:
@media not screen and (max - width: 600px) {
    .footer {
        display: flex;
        justify - content: space - between;
    }
}

响应式设计中的常见应用

  1. 布局适配:通过媒体查询可以轻松实现不同屏幕尺寸下的布局变化。例如,在小屏幕设备上,将多列布局转换为单列布局。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
    <meta name="viewport" content="width=device - width, initial - scale = 1.0">
    <title>Responsive Layout</title>
    <style>
        .container {
            display: flex;
        }

        .sidebar {
            width: 25%;
            background - color: lightgray;
        }

        .main - content {
            width: 75%;
            background - color: lightblue;
        }

        @media screen and (max - width: 768px) {
            .container {
                flex - direction: column;
            }

            .sidebar,
           .main - content {
                width: 100%;
            }
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="sidebar">Sidebar</div>
        <div class="main - content">Main Content</div>
    </div>
</body>

</html>

在上述代码中,当屏幕宽度大于 768 像素时,使用 flex 布局实现两列布局,侧边栏占 25%宽度,主内容占 75%宽度。当屏幕宽度小于等于 768 像素时,通过媒体查询改变布局方向为纵向,并且侧边栏和主内容都占据 100%宽度,以适应小屏幕设备。

  1. 图片适配:为不同设备提供合适尺寸的图片是优化网页性能和用户体验的重要一环。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
    <meta name="viewport" content="width=device - width, initial - scale = 1.0">
    <title>Responsive Images</title>
    <style>
        @media screen and (max - width: 480px) {
            img {
                content: url(small - image.jpg);
            }
        }

        @media screen and (min - width: 481px) and (max - width: 768px) {
            img {
                content: url(medium - image.jpg);
            }
        }

        @media screen and (min - width: 769px) {
            img {
                content: url(large - image.jpg);
            }
        }
    </style>
</head>

<body>
    <img src="default - image.jpg" alt="Responsive Image">
</body>

</html>

上述代码根据不同的屏幕宽度加载不同尺寸的图片,在小屏幕设备上加载小尺寸图片,以减少加载时间,提高网页性能。

  1. 字体大小调整:根据屏幕大小调整字体大小可以提高可读性。
body {
    font - size: 14px;
}

@media screen and (min - width: 768px) {
    body {
        font - size: 16px;
    }
}

@media screen and (min - width: 1200px) {
    body {
        font - size: 18px;
    }
}

随着屏幕宽度的增加,逐步增大字体大小,以确保在大屏幕设备上文字更加清晰易读。

嵌套媒体查询

在 CSS 中,媒体查询也可以嵌套在其他样式规则内部。这种方式在一些复杂的布局中非常有用,例如当我们只想在特定的容器内应用响应式样式时。

.container {
    background - color: white;

    @media screen and (max - width: 600px) {
        background - color: lightgray;
    }
}

在上述代码中,类名为 container 的元素在屏幕宽度大于 600 像素时背景颜色为白色,当屏幕宽度小于等于 600 像素时,其背景颜色变为浅灰色。这种嵌套媒体查询使得样式的作用范围更加精准。

多组媒体查询的优先级

当存在多个媒体查询规则同时作用于一个元素时,CSS 的优先级规则依然适用。一般来说,更具体的媒体查询会优先应用。例如:

@media screen and (min - width: 768px) {
    body {
        font - size: 16px;
    }
}

@media screen and (min - width: 992px) {
    body {
        font - size: 18px;
    }
}

在屏幕宽度大于等于 992 像素时,body 元素的字体大小会是 18 像素,因为第二个媒体查询更具体(针对更大的屏幕宽度),具有更高的优先级。

与 HTML 的 meta 标签配合

在 HTML 中,<meta> 标签中的 viewport 设置对于响应式设计也非常重要。viewport 元数据允许我们控制视口的大小和缩放。常见的设置如下:

<meta name="viewport" content="width=device - width, initial - scale = 1.0">
  • width=device - width:将视口宽度设置为设备的宽度,确保网页在不同设备上以正确的比例显示。
  • initial - scale = 1.0:设置初始缩放比例为 1.0,即不进行初始缩放,用户可以根据需要自行缩放页面。

通过合理设置 viewport 以及结合 CSS 媒体查询,我们能够创建出在各种设备上都具有良好用户体验的响应式网页。

响应式排版技巧

  1. 相对单位的使用:在响应式排版中,使用相对单位(如 emrem)比绝对单位(如 px)更合适。em 单位基于父元素的字体大小,而 rem 单位基于根元素(通常是 html 元素)的字体大小。

例如:

html {
    font - size: 16px;
}

body {
    font - size: 1em; /* 16px,与 html 元素字体大小相同 */
}

h1 {
    font - size: 2rem; /* 32px,是 html 元素字体大小的 2 倍 */
}

当根元素字体大小改变时,所有使用 rem 单位的元素字体大小都会相应改变,这在响应式设计中便于整体调整字体大小。

  1. 行高与字间距:适当调整行高和字间距可以提高文本的可读性,特别是在不同屏幕尺寸下。
body {
    line - height: 1.5;
    letter - spacing: 0.05em;
}

上述代码设置了合适的行高和字间距,使得文本在各种设备上都能清晰可读。

  1. 字体选择:选择合适的字体对于响应式设计也很重要。一些字体在小屏幕上可能显示效果不佳,因此可以考虑使用系统字体,它们在不同设备上都有较好的兼容性。
body {
    font - family: - apple - system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen - Sans, Ubuntu, Cantarell, "Helvetica Neue", sans - serif;
}

这段代码使用了系统字体栈,优先使用苹果系统字体,然后依次尝试其他常见的系统字体,以确保在不同设备上都有合适的字体显示。

响应式导航栏设计

  1. 汉堡菜单:在小屏幕设备上,汉堡菜单是一种常见的导航栏设计方式。通过媒体查询和 CSS 样式切换来实现汉堡菜单的显示与隐藏。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
    <meta name="viewport" content="width=device - width, initial - scale = 1.0">
    <title>Responsive Navbar</title>
    <style>
        nav {
            background - color: #333;
            color: white;
            padding: 10px;
        }

        .nav - list {
            list - style - type: none;
            margin: 0;
            padding: 0;
            display: flex;
        }

        .nav - item {
            margin - right: 20px;
        }

        .hamburger {
            display: none;
            cursor: pointer;
        }

        .bar {
            width: 25px;
            height: 3px;
            background - color: white;
            margin: 5px;
        }

        @media screen and (max - width: 768px) {
            .nav - list {
                display: none;
            }

            .hamburger {
                display: block;
            }
        }
    </style>
</head>

<body>
    <nav>
        <div class="hamburger">
            <div class="bar"></div>
            <div class="bar"></div>
            <div class="bar"></div>
        </div>
        <ul class="nav - list">
            <li class="nav - item">Home</li>
            <li class="nav - item">About</li>
            <li class="nav - item">Services</li>
        </ul>
    </nav>
</body>

</html>

在上述代码中,当屏幕宽度大于 768 像素时,导航栏以水平列表形式显示。当屏幕宽度小于等于 768 像素时,导航列表隐藏,汉堡菜单显示,用户可以点击汉堡菜单展开导航列表。

  1. 下拉菜单:在一些情况下,我们可能需要在导航栏中添加下拉菜单,同样可以通过媒体查询和 CSS 样式来实现响应式的下拉菜单设计。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
    <meta name="viewport" content="width=device - width, initial - scale = 1.0">
    <title>Responsive Dropdown Navbar</title>
    <style>
        nav {
            background - color: #333;
            color: white;
            padding: 10px;
        }

        .nav - list {
            list - style - type: none;
            margin: 0;
            padding: 0;
            display: flex;
        }

        .nav - item {
            margin - right: 20px;
            position: relative;
        }

        .dropdown {
            display: none;
            position: absolute;
            background - color: #444;
            min - width: 160px;
            box - shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
            z - index: 1;
        }

        .dropdown - item {
            color: white;
            padding: 12px 16px;
            text - decoration: none;
            display: block;
        }

        .nav - item:hover .dropdown {
            display: block;
        }

        @media screen and (max - width: 768px) {
            .nav - list {
                display: none;
            }

            .nav - item {
                width: 100%;
                text - align: center;
            }

            .dropdown {
                position: relative;
                width: 100%;
                min - width: auto;
            }

            .dropdown - item {
                background - color: #555;
            }
        }
    </style>
</head>

<body>
    <nav>
        <ul class="nav - list">
            <li class="nav - item">Home</li>
            <li class="nav - item">
                Products
                <div class="dropdown">
                    <a href="#" class="dropdown - item">Product 1</a>
                    <a href="#" class="dropdown - item">Product 2</a>
                </div>
            </li>
            <li class="nav - item">Contact</li>
        </ul>
    </nav>
</body>

</html>

在大屏幕上,当鼠标悬停在“Products”菜单项上时,下拉菜单显示。在小屏幕上,通过媒体查询重新调整了下拉菜单的布局,使其适应小屏幕设备的操作。

响应式图片优化

  1. 使用 picture 元素picture 元素允许我们根据不同的媒体条件选择不同的图片资源。
<picture>
    <source media="(min - width: 1200px)" srcset="large - image.jpg">
    <source media="(min - width: 768px)" srcset="medium - image.jpg">
    <img src="small - image.jpg" alt="Responsive Image">
</picture>

在上述代码中,当屏幕宽度大于等于 1200 像素时,浏览器会加载 large - image.jpg;当屏幕宽度大于等于 768 像素且小于 1200 像素时,加载 medium - image.jpg;否则加载 img 标签中的 small - image.jpg

  1. srcset 和 sizes 属性srcset 属性用于指定多个图片资源,sizes 属性用于指定不同屏幕宽度下图片的尺寸。
<img srcset="small - image.jpg 480w, medium - image.jpg 768w, large - image.jpg 1200w"
    sizes="(max - width: 480px) 100vw, (max - width: 768px) 50vw, 33vw"
    src="medium - image.jpg" alt="Responsive Image">

srcset 中的 480w768w1200w 表示图片的固有宽度。sizes 属性根据屏幕宽度定义了图片在不同情况下应占据的视口宽度比例。浏览器会根据这些信息选择最合适的图片资源进行加载。

跨设备测试与优化

  1. 使用模拟器和真机测试:在开发响应式网页时,使用模拟器(如 Chrome DevTools 的设备模拟器)可以快速在不同设备尺寸和类型上进行初步测试。但模拟器并不能完全模拟真实设备的所有特性,因此真机测试是必不可少的。通过在各种手机、平板电脑和电脑上实际浏览网页,能够发现并解决一些在模拟器中未出现的问题,如字体渲染差异、触摸交互问题等。

  2. 性能优化:响应式设计不仅要考虑布局和样式的适配,还要关注性能。在不同设备上,网络速度和硬件性能差异较大。我们可以通过压缩图片、优化 CSS 和 JavaScript 文件、减少 HTTP 请求等方式来提高网页性能。例如,对于小屏幕设备,可以进一步压缩图片尺寸,以减少加载时间。同时,避免在小屏幕设备上加载过多复杂的脚本和样式,确保网页快速加载和流畅运行。

  3. 用户反馈与持续改进:收集用户反馈是优化响应式设计的重要环节。用户可能会在使用过程中发现一些布局不合理、操作不方便等问题。通过分析用户反馈,我们可以针对性地对网页进行改进,不断提升用户体验,确保网页在各种设备上都能满足用户需求。

综上所述,CSS 媒体查询的 @media 规则在响应式设计中是一个强大而灵活的工具。通过合理运用媒体类型、媒体特性、逻辑操作符以及与 HTML 的配合,我们能够创建出适配各种设备的高质量响应式网页。同时,在设计过程中要注重排版、导航栏、图片优化等方面,并通过跨设备测试和用户反馈不断进行优化,以提供最佳的用户体验。