前言
2004年,Cameron Adams写了一篇题为《Resolution dependent layout》的帖子,描述了一种可以创造适应多种屏幕分辨率的设计的方式。这种方式需要JavaScript来探测屏幕的分辨率,载入恰当的CSS。
2008年,Zoe Mickley Gillenwater发布了她的著作,在里面描述并标准化了可变站点建立的不同方式,试图在充满屏幕和完全保持固定尺寸之间找到最佳平衡。
“响应式设计”这个词是Ethan Marcotte在2010年首度提出的,他将其描述为三种技术的混合使用:流式布局+弹性布局,再+媒体查询。,但是在这篇文章写就的几乎十年以后,Web的响应式工作已经成为了默认做法。现代的CSS布局方式基本上就是响应式的,而且我们在Web平台上内置了新的东西,使得设计响应式站点变得容易。
一、AWD与RWD
自适应web设计(Adaptive Web Design)响应式网页设计(Responsive web design,RWD)比较相似,但两者又是有区别的。
技术原理 | 特点 | 设计方法 | ||
---|---|---|---|---|
自适应布局 | 创建多个静态布局,每个静态布局对应一个屏幕分辨率范围。 改变屏幕分辨率可以切换不同的静态局部(页面元素位置发生改变),但在每个静态布局中,页面元素不随窗口大小的调整发生变化。 | 屏幕分辨率变化时,页面里面元素的位置会变化而大小不会变化 | 使用 @media 媒体查询给不同尺寸和介质的设备切换不同的样式。在优秀的响应范围设计下可以给适配范围内的设备最好的体验,在同一个设备下实际还是固定的布局。 | |
响应式布局 | 糅合了流式布局+弹性布局,再搭配媒体查询技术使用。 分别为不同的屏幕分辨率定义布局,同时,在每个布局中,应用流式布局的理念,使页面元素宽度随着窗口调整而自动适配。即:创建多个流体式布局,分别对应一个屏幕分辨率范围。可以把响应式布局看作是流式布局和自适应布局设计理念的融合。 | 每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变 | 媒体查询+流式布局。通常使用媒体查询和网格系统配合相对布局单位进行布局,实际上就是综合响应式、流动等技术通过 CSS 给单一网页不同设备返回不同样式的技术统称。 |
区别
最根本差别
- 自适应设计是网页内容根据设备进行”适应“,
- 响应式设计则是网页的布局针对屏幕大小的尺寸进行响应。
应用场景:
- 自适应:从页面个性化多功能方面考虑,当网站功能复杂、用户交互频繁、用户量较大。自适应设计更合适。例如电商类网站,这样可以更好的为客户提供功能全面、良好交互体验服务。
- 响应式:从运营和维护的便利性考虑,当网页交互少、功能少、升级不频繁时建议使用响应式。例如展示类公司主页等。
响应式布局处理布局和内容的三种方法:
换行:我们可以通过改变页面结构布局来更好的适配可视区域,大多数情况会导致内容堆叠。
调整大小:调整组件、html元素大小,填充空白空间并在必要时换行;
显示/隐藏:可视区域隐藏或显示组件(组件仍然存在)
二、响应式布局的实现
1、CSS3
媒体查询 media queries
在样式表上加入多条媒体查询,通过设置断点(媒体查询及样式改变时的点),调整整个页面或者部分页面以达到适应各式屏幕尺寸的最佳效果。
媒体查询常用匹配特征
mdedia features | 描述 |
---|---|
width/height | 浏览器宽高 |
max-width | 小于最大宽度时生效 |
min-width | 小于最小宽度时生效 |
device-width/device-height | 设备屏幕分辨率宽高 |
resolution | 设备分辨率 |
orientation | portrait(纵向),高度大于宽幅时;landcsape(横向),高度小于宽度时 |
特征匹配操作符
and
// 表示最小宽度限制在700px,当浏览器宽度大于等于700px且为横向时CSS代码生效
@media (min-width: 700px) and (orientation: landscape) {
...
}
- 逗号
,
分隔
// 表示最大宽度限制在500px,当浏览器宽度小于等于500px或者手持设备且为横向时生效
@media (max-width: 500px), handheld and (orientation: landscape) {
...
}
媒体查询引入
- link 引入方式
<link rel="stylesheet" type="text/css" href="styleB.css" media="screen and (min-width: 600px) and (max-width: 800px)">
- @media导入
@media screen and (max-width: 990px){
.container{
background: orange;
}
}
2、网格视图
响应式网格视图:首先确保所有的 HTML 元素都有 box-sizing 属性且设置为 border-box,确保边距和边框包含在元素的宽度和高度间。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<style>
* {
box-sizing:border-box;
}
.gridwrapper {
overflow:auto;
position:relative;
height:250px;
}
.gridcontent {
width:8.33%;
margin:0;
xborder-left:1px solid grey;
border-right:1px solid grey;
height:100%;
float:left;
background-color:#84c754;
background-color:#f1f1f1;
}
</style>
</head>
<body>
<div style="position:absolute;opacity:0.9;width:auto;left:8px;right:10px;">
<div class="gridcontainer">
<div class="gridwrapper" style="height:90px;">
<div class="gridcontent" style="width:100%;background:#9933cc;border-right-color:transparent;">
</div>
</div>
<div class="gridwrapper" style="height:230px;">
<div class="gridcontent" style="background-color:#ffffff;border:none;width:25%;padding-top:15px;">
<div style="background-color:#33b5e5;border:none;width:100%;height:15%;margin-bottom:10px;"></div>
<div style="background-color:#33b5e5;border:none;width:100%;height:15%;margin-bottom:10px;"></div>
<div style="background-color:#33b5e5;border:none;width:100%;height:15%;margin-bottom:10px;"></div>
<div style="background-color:#33b5e5;border:none;width:100%;height:15%;"></div>
</div>
<div class="gridcontent" style="background-color:#ffffff;border:none;"></div>
<div class="gridcontent" style="background-color:#ffffff;border:none;"></div>
<div class="gridcontent" style="background-color:#ffffff;border:none;"></div>
<div class="gridcontent" style="background-color:#ffffff;border:none;"></div>
<div class="gridcontent" style="background-color:#ffffff;border:none;"></div>
<div class="gridcontent" style="background-color:#ffffff;border:none;"></div>
<div class="gridcontent" style="background-color:#ffffff;border:none;width:25%;padding-top:15px;">
<div style="background-color:#33b5e5;border:none;width:100%;height:92%;"></div>
</div>
</div>
<div class="gridwrapper" style="height:50px;">
<div class="gridcontent" style="width:100%;background:#0099cc;border-right-color:transparent;">
</div>
</div>
</div>
</div>
<div class="gridcontainer" style="opacity:0.1;">
<div class="gridwrapper" style="height:370px;">
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;border-left:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
<div class="gridcontent" style="background-color:#ffffff;border-right:1px solid #000000;"></div>
</div>
</div>
<p>重置浏览器窗口大小网格会自动伸缩。</p>
</body>
</html>
3、多栏布局 column-count
这些布局方式中最老的一个是多个列,即当你指定一个column-count
的时候,这意指你希望把你的内容分成多少列。浏览器之后会算出这些列的大小,这是一个随着屏幕尺寸变化的尺寸。
.container {
column-count: 3;
}
如果你却去指定column-width
的话,你是在指定一个最小宽度。浏览器会尽可能多数量地创建这一宽度的列,只要它们可以恰当地放进容器里面,然后将所有列之间的剩余空间共享出去。因而列的数量会随着空间的多少而改变。
.container {
column-width: 10em;
}
4、flex布局
参考:https://blog.csdn.net/qq_38987146/article/details/113990426
5、栅格系统
参考:https://blog.csdn.net/qq_38987146/article/details/113990426
6、响应式图像
最简单的处理响应式图像的方式:用一张有着所需最大尺寸的图像,然后缩放它。这仍然是今日所使用的一种方式
Image/video {
max-width: 100%;
height: auto;
}
这样处理有两个弊端:
- 图像有可能会显示得比它的原始尺寸小很多,以至于浪费带宽;
- 在移动端和桌面端的图像宽高比例不一定会保持一致、展示图像也未必一致。这两者不能简单通过缩放图像解决。
合理的响应式图像,使用了<picture>
元素和<img>``srcset
和sizes
特性,解决了这两个问题,允许浏览器选择对设备最合适的图像,以确保用户下载尺寸适合他们使用的设备的图像。
srcset
:<img-URL>
<A width descriptor >
/<A pixel density descriptor)>
- width descriptor:image的宽度,数值为正整数,单位
w
;- pixel density descriptor:图片像素密度,数值为正浮点数,单位
x
。
sizes: <media-condition> <source-size-value>,<default>
- media-condition:媒体查询的条件设置
- source-size-value:满足查询条件时的图像选择值
- default: 不满足查询条件时的默认选择值
显示相同图像
-
分辨率切换:不同尺寸
想要显示相同的图像内容,根据设备的不同,只是更大或更小,使用
img
两个新属性:srcset
及sizes
,来提供一些额外的源图像以及提示,以帮助浏览器选择正确的图像。<img srcset="elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w" sizes="(max-width: 600px) 480px, 800px" src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
浏览器将检查设备宽度,确定
sizes
列表中第一个为真的媒体条件,拿到媒体查询插槽大小,加载srcset
列表中引用的与插槽大小相同的图像,如果没有,则加载第一个大于所选插槽大小的图像。即:如果视口宽度为480px,则(max-width: 600px)
媒体条件将为 true,因此浏览器选择480px
插槽,elva-fairy-480w.jpg
将被加载,因为其固有的宽度(480w
)是最接近位尺寸。 -
相同尺寸,不同分辨率
支持多种显示分辨率,但每个人都在屏幕上以相同的实际尺寸看到您的图像,您可以允许浏览器通过使用srcset
x 描述符和不使用x 描述符来选择合适的分辨率图像sizes
——一种更简单的语法!<img srcset="elva-fairy-320w.jpg, elva-fairy-480w.jpg 1.5x, elva-fairy-640w.jpg 2x" src="elva-fairy-640w.jpg" alt="Elva dressed as a fairy">
显示不同图像
要更改显示的图像以适应不同的图像显示尺寸
<picture>
<source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
<source media="(min-width: 800px)" srcset="elva-800w.jpg">
<img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
</picture>
media
包含媒体条件的属性: 如果视口宽度为 799px 或更小,<source>
将显示第一个元素的图像。如果视口宽度为 800px 或更大,它将是第二个。如果没有任何媒体条件返回 true或者浏览器不支持该<picture>
元素时,将默认显示elva-800w.jpg
。srcset
图像路径。此处的srcset
也可以配合图像的sizes
属性进行使用。
7、响应式排版
-
em
/rem
响应式排版html { font-size: 1em; } h1 { font-size: 2rem; } @media (min-width: 1200px) { h1 { font-size: 4rem; } }
-
vw
响应式排版使用视口单位实现响应式排版使用视口单位
vw
同样可以实现响应式排版。1vw
等同于视口宽度的百分之一,即如果你用vw
来设定字体大小的话,字体的大小将总是随视口的大小进行改变。h1 { font-size: 6vw; }
这样做存在一个问题,文本与viewport强相关,而放缩对仅使用vw定义的文本无效。所以你永远都不要只用viewport单位设定文本。
可以使用
calc()
,并将vw
单位与可放缩单位(例如em
或者rem
)进行组合来解决这个问题。h1 { font-size: calc(1.5rem + 3vw); }
9、设置viewport
viewport 是用户网页的可视区域。设置目的:避免手机浏览器虚拟的"窗口"(viewport)中,通常这个虚拟的"窗口"(viewport)比屏幕宽时带来的问题。
<meta name="viewport" content="width=device-width, initial-scale=1">
该属性可以控制视窗口宽度的大小。它可以被设置为实际的具体像素 width= 600 或为特殊设备设置宽度值。
viewport 设置属性如下:
- width:控制 viewport 的大小,可以指定的一个值,如 600,或者特殊的值,如 device-width 为设备的宽度(单位为缩放为 100% 时的 CSS 的像素)。
- height:和 width 相对应,指定高度。
- initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。
- maximum-scale:允许用户缩放到的最大比例。
- minimum-scale:允许用户缩放到的最小比例。
- user-scalable:用户是否可以手动缩放
参考:
- https://www.zhihu.com/question/20976405
- https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Responsive_Design
- https://www.zhihu.com/question/20976405
- https://www.runoob.com/css/css-rwd-images.html