在移动互联网时代,我们使用各种不同尺寸的设备浏览网页 - 从智能手机到平板电脑,从笔记本电脑到台式机,甚至智能电视和可穿戴设备。如何让同一个网页在这些尺寸各异的屏幕上都能提供优秀的用户体验?CSS 媒体查询就是解决这个问题的关键技术。
媒体查询
媒体查询是 CSS3 中的一项强大功能,它允许我们根据设备的特定特性(如屏幕宽度、高度、设备方向等)来应用不同的 CSS 样式。简单来说,媒体查询就像是给浏览器安装了一个"智能感应器",让网页能够"感知"到正在使用的设备类型,并相应地调整布局和样式。
基本语法结构
媒体查询的基本语法非常简单,由媒体类型和一个或多个表达式组成:
@media 媒体类型 and (条件表达式) {
/* 满足条件时应用的 CSS 样式 */
}
媒体类型
媒体类型指定了样式表的目标设备类型:
| 类型 | 解释 |
|---|---|
| all | 所有设备(默认值) |
| 打印机和打印预览 | |
| screen | 电脑屏幕、平板、智能手机等 |
| speech | 屏幕阅读器等发声设备 |
常用媒体特性
以下是一些最常用的媒体特性:
| 特性 | 解释 |
|---|---|
min-width | 视口最小宽度 |
max-width | 视口最大宽度 |
orientation | 设备方向(portrait/landscape) |
aspect-ratio | 视口宽高比 |
resolution | 设备分辨率 |
代码示例
示例1:基础响应式布局
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>响应式布局示例</title>
<style>
/* 基础样式 - 移动设备优先 */
.container {
width: 100%;
padding: 15px;
box-sizing: border-box;
}
.box {
background-color: #f0f0f0;
padding: 20px;
margin-bottom: 15px;
border-radius: 5px;
}
/* 平板设备 - 768px 及以上 */
@media screen and (min-width: 768px) {
.container {
max-width: 720px;
margin: 0 auto;
}
.box {
padding: 30px;
}
}
/* 桌面设备 - 992px 及以上 */
@media screen and (min-width: 992px) {
.container {
max-width: 960px;
}
.box {
float: left;
width: 48%;
margin-right: 2%;
}
.box:nth-child(2n) {
margin-right: 0;
}
}
/* 大屏幕设备 - 1200px 及以上 */
@media screen and (min-width: 1200px) {
.container {
max-width: 1140px;
}
.box {
width: 23.5%;
margin-right: 2%;
}
.box:nth-child(2n) {
margin-right: 2%;
}
.box:nth-child(4n) {
margin-right: 0;
}
}
</style>
</head>
<body>
<div class="container">
<div class="box">内容区块 1</div>
<div class="box">内容区块 2</div>
<div class="box">内容区块 3</div>
<div class="box">内容区块 4</div>
</div>
</body>
</html>
示例2:根据设备方向调整样式
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>设备方向响应示例</title>
<style>
body {
margin: 0;
padding: 20px;
font-family: Arial, sans-serif;
transition: all 0.3s ease;
}
.orientation-message {
padding: 20px;
text-align: center;
border-radius: 10px;
margin-bottom: 20px;
}
/* 竖屏模式 */
@media screen and (orientation: portrait) {
body {
background-color: #e8f4fd;
}
.orientation-message {
background-color: #4a90e2;
color: white;
}
.orientation-message::before {
content: "当前为竖屏模式";
}
}
/* 横屏模式 */
@media screen and (orientation: landscape) {
body {
background-color: #fde8e8;
}
.orientation-message {
background-color: #e24a4a;
color: white;
}
.orientation-message::before {
content: "当前为横屏模式";
}
.content {
display: flex;
}
.content > div {
flex: 1;
padding: 15px;
}
}
</style>
</head>
<body>
<div class="orientation-message"></div>
<div class="content">
<div>
<h2>左侧内容</h2>
<p>在横屏模式下,内容会分为两列显示。</p>
</div>
<div>
<h2>右侧内容</h2>
<p>在竖屏模式下,这些内容会堆叠显示。</p>
</div>
</div>
</body>
</html>
示例3:打印样式优化
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>打印样式示例</title>
<style>
/* 屏幕样式 */
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: #333;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.header {
background-color: #4a90e2;
color: white;
padding: 20px;
border-radius: 5px;
margin-bottom: 20px;
}
.sidebar {
float: right;
width: 30%;
background-color: #e9e9e9;
padding: 15px;
border-radius: 5px;
margin-left: 20px;
}
.content {
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.advertisement {
background-color: #ffeb3b;
padding: 10px;
text-align: center;
margin: 20px 0;
border: 2px dashed #ffc107;
}
/* 打印样式 */
@media print {
body {
background-color: white;
color: black;
font-size: 12pt;
line-height: 1.4;
padding: 0;
}
.header {
background-color: white !important;
color: black !important;
border-bottom: 2px solid #000;
border-radius: 0;
}
.sidebar {
float: none;
width: auto;
background-color: white;
border: 1px solid #ccc;
margin: 10px 0;
}
.content {
box-shadow: none;
padding: 0;
}
.advertisement {
display: none; /* 打印时隐藏广告 */
}
a::after {
content: " (" attr(href) ")"; /* 打印时显示链接地址 */
}
/* 避免在打印时出现分页问题 */
h1, h2, h3 {
page-break-after: avoid;
}
.page-break {
page-break-before: always;
}
}
</style>
</head>
<body>
<div class="header">
<h1>我的网页标题</h1>
<p>这是一个演示打印样式的页面</p>
</div>
<div class="sidebar">
<h3>侧边栏</h3>
<p>这里是一些辅助内容。</p>
<ul>
<li>相关链接一</li>
<li>相关链接二</li>
<li>相关链接三</li>
</ul>
</div>
<div class="content">
<h2>主要内容区域</h2>
<p>这是一段示例文本,展示了网页的主要内容。<a href="https://example.com">这是一个示例链接</a>。</p>
<div class="advertisement">
这是一个广告区域 - 打印时不会显示
</div>
<p>更多内容...</p>
<div class="page-break"></div>
<h2>第二页内容</h2>
<p>这部分内容在打印时会出现在新的一页上。</p>
</div>
</body>
</html>
案例三运行结果:
媒体查询的注意事项
- 移动优先原则:建议采用移动优先的设计方法,先为小屏幕设备编写基础样式,然后使用
min-width媒体查询为更大屏幕添加或覆盖样式。 - 断点选择:不要盲目使用流行设备的尺寸作为断点,而应根据内容自身的特点来确定断点。当布局开始看起来不协调时,就是添加断点的好时机。
- 注意媒体查询的顺序:在多个媒体查询规则匹配时,后面定义的规则会覆盖前面的规则,因此需要注意媒体查询在样式表中的顺序。
- 考虑高分辨率屏幕:使用
min-resolution或-webkit-min-device-pixel-ratio为高分辨率屏幕提供更清晰的图像。