css-媒体查询总结

目的

想实现如下图的上下布局,上面是图片介绍,下面是内容主体。在一般手机上显示稍微正常,但是在ipad(768x1024)ipad pro(1024x1366)`上,画风就有点奇怪了:图片被拉伸了,另外字体的变化也让人有点无法接受。我用的是媒体查询(media)解决这个问题的。先看下效果(源码在底部):

在iphone上

image.png

在ipad上

image.png

在ipad pro上

image.png

解决之后的效果

图片和字体在视觉上都不会有什么大问题。

在iphone上

image.png

在ipad上

image.png

在ipad pro上

image.png

核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style>
.header img{width: 100%;height: 11.6rem;}
.continer{width: 100%;height: 100vh;background: #4691ee;}
p {text-align: center;font-size: 1.2rem;margin: unset;}
/*这里高度计算并不是特别严谨,想真正做好还是需要专门进行计算的,但是按下面的至少不会影响用户体验*/
/*ipad*/
@media screen and (min-width:760px) and (max-width:1023px) {
/** 窗口宽度在760--1023px的样式 ipad为768 **/
.header img{height:22.5rem;width:100%}
p {font-size: 2.4rem;}
}
/*ipad pro*/
@media screen and (min-width:1024px) {
/** 窗口宽度1024px 以上,只适配到1024 **/
.header img{height:30.5rem;width:100%}
p {font-size: 3.2rem;}
}
</style>

媒体查询

CSS媒体查询是实现响应式设计的主要方法。响应式设计可根据所显示的屏幕大小而改变,他呈现的每个屏幕看起来并不相同。按照可用的屏幕属性,响应式设计提供了UI的最佳效果。

媒体查询包含一个可选的媒体类型,和满足css3规范的条件下,包含零个或多个表达式,这些表达式描述了媒体特征,最终会被解析为truefalse。如果媒体查询中指定的媒体类型匹配文档所使用的设备类型,并且所有的表达式的值都是true,那么该媒体查询结果为true

1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- link元素中的CSS媒体查询 -->
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" />

<!-- 样式表中的CSS媒体查询 -->
<style>
@media (max-width: 600px) {
.facet_sidebar {
display: none;
}
}
<!--@media 是媒体类型-->
<!--(max-width:600px)是包含媒体查询的表达式,如果浏览器屏幕小于600px,应用下面的样式。-->
</style>

当媒体查询为true时,其对应的样式表或样式规则就会遵循正常的级联规则进行应用。即使媒体查询返回false<link>标签指向的样式表也会被下载,但是不会被应用。

逻辑操作符

可以使用not、and、only、,等构造负责的媒体查询。

  • and操作符用来把多个媒体查询组合成一条媒体查询,对成链式的特征进行请求,只有当每个属性都为真时,结果才为真。
  • not操作符用来对一条媒体查询的结果进行取反。
  • only操作符仅在媒体查询匹配成功的情况下被用于应用的一个样式,这对于防止让选中的样式在老式浏览器中被应用到。
  • 逗号分隔符,与or等意义。满足其中之一即可。
  • 若用了notonly操作符,必须明确指定一个媒体样式。
and

and关键字用于合并多个媒体属性或合并媒体属性与媒体类型。

1
@media tv and (min-width: 700px) and (orientation: landscape) { ... }

上面媒体查询仅在电视媒体上,可视区域不小于700像素宽度并且是横屏时有效。

逗号分隔列表

媒体查询中使用逗号分隔效果等同于or逻辑操作符。当使用逗号分隔符的媒体查询时,如果任何一个媒体查询返回真,样式就是有效的。逗号分隔的列表中每个查询都是独立的,一个查询中的操作符并不影响其他的媒体查询。这意味着逗号媒体查询列表能够作用于不同的媒体属性、类型和状态。

例如,如果你想在最小宽度为700像素或是横屏的手持设备上应用一组样式,你可以这样写:

1
@media (min-width: 700px), handheld and (orientation: landscape) { ... }

如上文,如果是一个800px的屏幕设备,媒体语句将会返回真,因为第一部分相当于@media all and (min-width:700px)将会应用于该设备并且返回真,尽管屏幕的媒体类型并不与第二部分的手持媒体类型(handheld)相符。同样的,如果现在只是一个500px+横屏的手持设备,尽管第一部分因为宽度问题而不匹配,第二部分仍会成功,因此整个媒体查询返回真。

not

not关键字应用于整个媒体查询,在媒体查询为假时返回真not关键字仅能应用于整个查询,而不能单独应用于一个独立的查询。例如,not在下面的查询中最后被计算。

1
@media not all and (monochrome) { ... }

等价于

1
@media not (all and (monochrome)) { ... }
only

only关键字防止老旧的浏览器不支持带媒体属性的查询而应用到给定的样式。

1
<link rel="stylesheet" media="only screen and (color)" href="example.css" />

常见媒体查询

因为 Apple 首次向市场推出了用户智能手机和平板电脑产品,所以下列大多数媒体查询都是基于这些型号的设备。

如果目标是横向模式智能手机,则使用:

1
@media (min-width: 321px) { ... }

如果目标是纵向模式智能手机,则使用:

1
@media (max-width: 320px) { ... }

如果目标是横向模式 Apple iPad,则使用:

1
@media (orientation: landscape) { ... }

如果目标是纵向模式 iPad,则使用:

1
@media (orientation: portrait) { ... }

媒体类型

media-MDN文档

浏览器支持

目前支持的浏览器包括Mozilla、Firefox、AppleSafari、Google Chrome和Opera,查看完整的支持列表。不支持media的浏览器需要在项目内导入一个名为respond.jsJavascript polyfill

Respond.js是一个极小的增强 Web 浏览器的 JavaScript 库,使得原本不支持 CSS 媒体查询的浏览器能够支持它们。该脚本循环遍历页面上的所有 CSS 引用,并使用媒体查询分析 CSS 规则。然后,该脚本会监控浏览器宽度变化,添加或删除与 CSS 中媒体查询匹配的样式。最终结果是,能够在原本不支持的浏览器上运行媒体查询。

demo源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta charset="UTF-8">
<title>Media</title>
<style>
.header img{width: 100%;height: 11.6rem;}
.continer{width: 100%;height: 100vh;background: #4691ee;}
p {text-align: center;font-size: 1.2rem;margin: unset;}
/*这里高度计算并不是特别严谨,想真正做好还是需要专门进行计算的,但是按下面的至少不会影响用户体验*/
/*ipad*/
@media screen and (min-width:760px) and (max-width:1023px) {
/** 窗口宽度在760--1023px的样式 ipad为768 **/
.header img{height:22.5rem;width:100%}
p {font-size: 2.4rem;}
}
/*ipad pro*/
@media screen and (min-width:1024px) {
/** 窗口宽度1024px 以上,只适配到1024 **/
.header img{height:30.5rem;width:100%}
p {font-size: 3.2rem;}
}
</style>
</head>
<body style="font-size: 18px">
<div class="header">
<p>header</p>
<img src="../asset/paper.jpg">
</div>
<div class="continer">
<p>continer</p>
</div>
</body>
</html>

Reference

css媒体查询

@media

使用CSS媒体查询创建响应式网站