为什么需要设计响应式设计
响应式设计就是为了为了统一所有设备,给用户展示最优的交互界面。
- 即便是PC或Mac用户,有查显示只有一半的人会将浏览器全屏显示,而剩下的一般人使用多大的浏览器,很难预知;
- 台式机、投影、电视、笔记本、手机、平板、手表、VR......智能设备正在不断增加,"主流设备"的概念正在消失;
- 屏幕分辨率正飞速发展,同一张图片在不同设备上看起来,大小可能天差地别;
- 鼠标、触屏、笔、摄像头手势......不可预期的操控方式正在不断出现。
响应式设计就是RWD(Responsive Web Design),与此目标比较相似的另一个设计就是 自适应网页设计AWD(Adaptive Web Design)。
相同点: 两者的目标相同,都是针对不同的分辨率/device采用不同的样式和布局达到页面展示最优; 在布局方式本质没有差别(AWD 也 including responsive layout)。
差别点: RWD强调一套页面进行多端兼容展示(桌机、平板、手机都是用同一个 HTML 代码和同一个 CSS 文档,能依照不同屏幕宽度的条件,来改变排版),而AWD给出多套页面,对于不同device进行了分类处理(在不同的装置开启网页时,AWD 会先判定装置屏幕尺寸是哪一种,来读取不同的 CSS 文档,呈现网页设计排版); RWD使用流动网格、CSS、以及灵活的基础可能需要更多的代码和实施策略(「媒体设备查询 @media」是 CSS 重要的能力之一,透过它可分辨开启网页的浏览器宽度大小,实时读取不同的样式呈现,就能达成 RWD 响应式效果),而AWD一般是server side detection,一次性渲染既定布局和样式。
响应式设计实现方案
主要从响应式布局(媒体查询、流式布局)、相对单位、响应式文字、响应式图片几个方面来进行响应式设计实现。
页面布局
页面布局目前有:静态布局、流式布局、自适应布局、响应式布局、弹性布局(rem/em布局)。 简单介绍下:
静态布局
即传统Web设计,网页上所有元素的尺寸一律使用px作为单位;设置了最小宽度,小于这个宽度就会出现滚动条,如果大于这个宽度则内容居中外加背景,常见于PC端。
设计方法: PC:居中布局,所有样式使用绝对宽度/高度(px),设计一个Layout,在屏幕宽高有调整时,使用横向和竖向的滚动条来查阅被遮掩部分;
移动设备:另外建立移动网站,单独设计一个布局,使用不同的域名如wap.或m.。
在移动端开发中采用静态布局的两种方式:
(1)在viewport meta标签上设置width=320,页面的各个元素也采用px作为单位。通过用JS动态修改标签的initial-scale使得页面等比缩放,从而刚好占满整个屏幕。
(2)设在viewport meta标签上设置content"width=640,user-scalable=no,页面的各个元素也采用px作为单位。由于640px超出了手机宽度,浏览器会自动缩小页面至刚好全屏。
优点:这种布局方式对设计师和CSS编写者来说都是最简单的,亦没有兼容性问题。缺点:显而易见,即不能根据用户的屏幕尺寸做出不同的表现。
流式布局
是页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。代表作栅栏系统(网格系统)。
网页中主要的划分区域的尺寸使用百分数(搭配min- *、max-*属性使用),例如,设置网页主体的宽度为80%,min-width为960px。图片也作类似处理(width:100%, max-width一般设定为图片本身的尺寸,防止被拉伸而失真)。
布局特点:屏幕分辨率变化时,页面里元素的大小会变化而但布局不变。【这就导致如果屏幕太大或者太小都会导致元素无法正常显示】
分类
- 左侧固定,右侧自适应
- 右侧固定,左侧自适应
- 两侧固定,中间自适应(圣杯布局)
- 等分布
设计方法:
使用%百分比定义宽度,高度大都是用px来固定住,可以根据可视区域 (viewport) 和父元素的实时尺寸进行调整,尽可能的适应各种分辨率。往往配合 max-width/min-width 等属性控制尺寸流动范围以免过大或者过小影响阅读。
这种布局方式在Web前端开发的早期历史上,用来应对不同尺寸的PC屏幕(那时屏幕尺寸的差异不会太大),在当今的移动端开发也是常用布局方式,但缺点明显:主要的问题是如果屏幕尺度跨度太大,那么在相对其原始设计而言过小或过大的屏幕上不能正常显示。因为宽度使用%百分比定义,但是高度和文字大小等大都是用px来固定,所以在大屏幕的手机下显示效果会变成有些页面元素宽度被拉的很长,但是高度、文字大小还是和原来一样(即,这些东西无法变得"流式"),显示非常不协调。
自适应布局
自适应布局的特点是分别为不同的屏幕分辨率定义布局,即创建多个静态布局,每个静态布局对应一个屏幕分辨率范围。改变屏幕分辨率可以切换不同的静态局部(页面元素位置发生改变),但在每个静态布局中,页面元素不随窗口大小的调整发生变化。可以把自适应布局看作是静态布局的一个系列。
布局特点:屏幕分辨率变化时,页面里面元素的位置会变化而大小不会变化。
设计方法:使用 @media 媒体查询给不同尺寸和介质的设备切换不同的样式。在优秀的响应范围设计下可以给适配范围内的设备最好的体验,在同一个设备下实际还是固定的布局。
响应式布局
随着CSS3出现了媒体查询 技术,又出现了响应式设计的概念。响应式设计的目标是确保一个页面在所有终端上(各种尺寸的PC、手机、手表、冰箱的Web浏览器等等)都能显示出令人满意的效果,对CSS编写者而言,在实现上不拘泥于具体手法,但通常是糅合了流式布局+弹性布局,再搭配媒体查询技术使用。------分别为不同的屏幕分辨率定义布局,同时,在每个布局中,应用流式布局的理念,即页面元素宽度随着窗口调整而自动适配。即:创建多个流体式布局,分别对应一个屏幕分辨率范围。可以把响应式布局看作是流式布局和自适应布局设计理念的融合。响应式几乎已经成为优秀页面布局的标准。
布局特点:每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变。
设计方法:媒体查询+流式布局。通常使用 @media 媒体查询 和网格系统 (Grid System) 配合相对布局单位进行布局,实际上就是综合响应式、流动等上述技术通过 CSS 给单一网页不同设备返回不同样式的技术统称。
优点:适应pc和移动端,如果足够耐心,效果完美;优点:适应pc和移动端,如果足够耐心,效果完美。
响应式页面在头部会加上这一段代码:
ini
<meta name="applicable-device" content="pc,mobile">
<meta http-equiv="Cache-Control" content="no-transform ">
媒体查询
CSS3媒体查询可以让我们针对不同的媒体类型定义不同的样式,当重置浏览器窗口大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面。
在进行媒体查询实现前,需要考虑如何合理地选定分割点,可以根据你的设计需求和目标设备来定,也有一些常用的分割点,例如:480px、600px、768px、900px、1200px等。
常见屏幕尺寸
yaml
分辨率 比例 | 设备尺寸
1024 * 500 (8.9 寸)
1024 * 768 (4 : 3 | 10.4 寸、12.1 寸、14.1 寸、15 寸)
1280 * 800 (16 : 10 |15.4 寸)
1280 * 1024 (5:4 | 14.1寸、15.0寸)
1280 * 854 (15 : 10 | 15.2)
1366 * 768 (16:9 | 不常见)
1440 * 900 (16:10 17寸 仅苹果用)
1440 * 1050 (5:4 | 14.1寸、15.0寸)
1600 * 1024 (14:9 | 不常见)
1600 * 1200 (4:3 | 15、16.1)
1680 * 1050 (16:10 | 15.4寸、20.0寸)
1920 * 1200 (23寸)
具体语法如下所示:
移动优先
默认的样式为手机的样式
xml
<style>
body {
height: 100vh;
width: 100vw;
background: red;
}
@media screen and (min-width: 480px) {
body {
background: yellow;
}
}
@media screen and (min-width: 600px) {
body {
background: green;
}
}
@media screen and (min-width: 900px) {
body {
background: purple;
}
}
@media screen and (min-width: 1200px) {
body {
background: palevioletred;
}
}
</style>
PC优先
默认的样式为PC屏幕的样式
xml
<style>
body {
height: 100vh;
width: 100vw;
background: red;
}
@media screen and (max-width: 1200px) {
body {
background: yellow;
}
}
@media screen and (max-width: 900px) {
body {
background: green;
}
}
@media screen and (max-width: 780px) {
body {
background: blue;
}
}
@media screen and (max-width: 600px) {
body {
background: purple;
}
}
@media screen and (max-width: 480px) {
body {
background: palevioletred;
}
}
</style>
弹性布局(rem/em布局)
1、rem,em区别: rem,em都是顺应不同网页字体大小展现而产生的。其中,em是相对其父元素,在实际应用中相对而言会带来很多不便;而rem是始终相对于html大小,即页面根元素。
2、使用 em 或 rem 单位进行相对布局,相对%百分比更加灵活,同时可以支持浏览器的字体大小调整和缩放等的正常显示,因为em是相对父级元素的原因没有得到推广。
布局特点:包裹文字的各元素的尺寸采用em/rem做单位,而页面的主要划分区域的尺寸仍使用百分数或px做单位(同「流式布局」或「静态/固定布局」) 。早期浏览器不支持整个页面按比例缩放,仅支持网页内文字尺寸的放大,这种情况下。使用em/rem做单位,可以使包裹文字的元素随着文字的缩放而缩放。
浏览器的默认字体高度一般为16px
,即1em:16px,但是 1:16 的比例不方便计算,为了使单位em/rem更直观,CSS编写者常常将页面跟节点字体设为62.5%,比如选择用rem控制字体时,先需要设置根节点html的字体大小,因为浏览器默认字体大小16px*62.5%=10px。这样1rem便是10px,方便了计算。
因为有些浏览器默认的不是16px,或者用户修改了浏览器默认的字体大小(因浏览器分辨率大小,视力,习惯等因素)。如果我们将其设置为10px,一定会影响在这些浏览器上的效果,所以最好用绝大多数用户默认的16作为基数 * 62.5% 得到我们需要的10px。 (关于为什么一般多是 html{font-size:62.5%;} 而不是 html{font-size:10px;})
css
html {
font-size: 62.5%; /*10 ÷ 16 × 100% = 62.5% 即: 1rem = 10px */
}
body {
font-size: 1.4rem; /*1.4 × 10px = 14px */
}
h1 {
font-size: 2.4rem; /*2.4 × 10px = 24px*/
}
实际项目设置成 font-size: 62.5%可能会出现问题,因为chrome不支持小于12px的字体,计算小于12px的时候,会默认取12px去计算,导致chrome的em/rem计算不准确。
针对这个现象,可以尝试设置html字体为100px,body 修正为16px,这样 0.1rem 就是 10px,而body的字体仍然是默认大小,不影响未设置大小的元素的默认字体的大小。
代码如下:
css
html {
font-size: 625%; /* 100 ÷ 16 × 100% = 625% 即 1rem = 100px */
}
body {
font-size: 0.16rem; /* 0.16 × 100 = 16px */
}
相对单位
相对单位主要用的其实就是px的转换。
rem
rem是一个相对尺寸,相对于html根元素来进行计算。设置方法查看上面的 弹性布局(rem/em布局) 。
em
em是相对长度单位,但它取决于父字体大小,也是离它最近的元素的font-size大小。
vw
是一种视窗单位,也是相对单位,是视窗宽度的百分比的意思。也就是客户端浏览器的可视区域,视窗均分为100个单位,1vw就是视窗宽度的百分之一。
如果需要根据宽度变化来进行百分比调节相关单位,可以自定义一个函数,以scss为例:
less
@function rem($px) {
@if $px==0 {
@return 0;
}
@else if $px==1 {
@return 1px;
}
@return $px / 375 * 100vw; //如果设计图是375,按照宽度为375px进行计算,当设备为375px的时候,1vw=1px
}
//具体的样式中使用
.test{
font-size: rem(16); //相当于16px
width: rem(100);
height: rem(100); //以宽高为100px的正方形
}
VH
和vw一样是视口高度,以百分比方式工作。10vh相当于当前浏览器窗口屏幕高度的10%。
在响应式设计上来说,使用rem更加方便,可以统一更改整个网站的计算。
响应式文字
响应式文字更改的主要原理还是基于像素单位。
可以使用rem、em、使用vw转换px进行调整文字的大小。
css
<style>
html {
font-size: 625%; //相当于1rem=100px
}
body {
font-size: 0.16rem; //16px
}
.test {
font-size: 0.24rem; //24px
}
</style>
响应式图片
万能的100%
css
.image{
max-width: 100%;
width: 100%;
height: auto;
object-fit: contain;
}
如上图所示,无论容器根据媒体查询扩张还是缩小,图片都能自适应。当然纵使容器再宽大,图片尺寸也不会超出自己的原生尺寸,等比例缩放,可以解决响应式中的大部分图片适应性问题。
但是如果屏幕过小的情况下,图片中的字就会出现看不清的情况,如上面的图片,右边两张多少还是看的清楚里面的文字的,但是第一张的小屏幕上,已经不太能看得清楚里面具体写了什么,因此需要根据小屏幕更换更加突出重点的图片。也就是根据不同的视口大小、屏幕分辨率等情况下提供不同的图片给用户,如下图所示:
srcset语法
- 根据像素比选择相应的图片
ini
<img class="image" src="../source/images/bg/640.jpg" srcset="../source/images/bg/641.jpg 2x, ../source/images/bg/642.jpg 1x " alt="">
小提示:上面代码中,2x,1x是像素比,也就是设备像素比(devicePixelRatio,简称dpr),在js中可以通过window.devicePixelRadio来获取,在css中可以通过-webkit-min-device-pixel-ratio进行检测获取。
scss
@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-device-pixel-ratio: 2) {
/* CSS styles for devices with dpr of 2 */
}
- 根据视口大小选择相应的图片
ini
<img class="image" src="big.jpg" srcset="big.jpg 1024w, middle.jpg 640w, small.jpg 320w">
上面代码是优先PC,默认展示big.jpg,在屏幕大于640px的时候,展示big.jpg;屏幕处于640px~320px的时候,显示middle.jpg;屏幕小于320px的啥时候显示small.jpg。具体的优先展示参考前面的媒体查询的规则。
- 搭配sizes进行使用
ini
<img class="image" src="big.jpg" srcset="big.jpg 1024w, middle.jpg 640w, small.jpg 320w" sizes="(max-width: 640px) 100vw, (max-width: 960px) 50vw, calc(100vw / 3)">
上面代码搭配了sizes,翻译具体的显示逻辑为:当视口宽度不超过640时,图片宽度为视口的100%;当视口宽度大于640但小于960时,图片宽度为视口宽度的50%;当视口宽度大于960时(默认情况),图片宽度为视口的1/3。浏览器会根据当前的情况,自主地从提供的图片中选择,给出一个最优的图片。
<picture>
和<source>
元素
在响应式图片当中,如果需要基于同一张图片裁剪出多种尺寸的版本。并且针对裁剪后每种尺寸的图片,又要考虑三种用例的情况,将不同尺寸的图片等比例缩放。就需要用到picture和source元素进行展示。
ini
<picture>
<source media="(max-width:640px)" srcset="small.jpg 320w" />
<source media="(max-width:960px)" srcset="middle.jpg 640w" />
<source srcset="big.jpg 1024w" />
<img src="default.jpg" alt="">
</picture>
如上述代码,浏览器会根据当前的视口去获取相应的图片数据源,展示给用户。小提示 :必须加上img标签哦~~否则不会展示图片。原因是<source>
只为<picture>
提供数据源,但是并没有展示的能力,只有选择了恰当的来自<source>
的素材并把它加载至<image>
上,图片才能显现;另外,当浏览器不支持<picture>
的时候,其中的image仍然可以被识别,确保时钟有图片显示在页面上。
ini
<picture>
<source media="(max-width:640px)" srcset="small.jpg 2x, small-1.jpg 1x " />
<source media="(max-width:960px)" srcset="middle.jpg 2x, middle-1.jpg 1x" />
<source srcset="big.jpg 2x, big-1.jpg 1x" />
<img class="image" src="default.jpg" alt="">
</picture>
上述代码获取图片数据源的逻辑为:当视口宽度不超过640时,dpr为2的时候选择small.jpg,dpr为1的时候选择small-1.jpg;当视口宽度大于640但小于960时,,dpr为2的时候选择middle.jpg,dpr为1的时候选择middle-1.jpg;当视口宽度大于960时,dpr为2的时候选择big.jpg,dpr为1的时候选择big-1.jpg。
上述方案实现了多种屏幕视口的情况下,为不同屏幕像素的设备选择更加合适的图片。
放弃图片
- 使用数据URI
通过将图片自身通过Base64编码转化为文本作为元素图片的URI使用。好处是节省了HTTP请求,坏处是,浏览器也无法缓存图片(当页面需要多次引用同一张图片时, 不得不在多出粘贴代码并且占用传输带宽),同时增大了样式文件体积。
设置响应式的时候根据图片的宽高进行合适的显示。
- 使用css形状
通过CSS样式属性来把元素模拟为不同的平面几何图形,如圆形、三角形、菱形。
设置响应式的时候使用相对单位即可实现。
- 使用图标字体
大部分常用的图标使用图标字体,可以设置相应的颜色和形状,简单的可以在iconfont-阿里巴巴矢量图标库,进行寻找。
使用的时候结合响应式文字以及相对单位进行响应式设置。
由于高清图片体积巨大,能够使用其他方式减少体积尽量使用其他方式。图片性能过程中,对比相应的体积大小,相应来说,图标字体、css是请求文件比较小的方式。也可以对图片进行优化,比如将png-32(位)的图片转化为png-8格式,来进行减少体积。
目前对响应式的理解和实现就暂时到此结束了,后续可能还会有更好的响应式的实现方式,不断学习进步~~
附录: