首先,什么是响应式设计?
网上对响应式设计的介绍很多,鄙人也看过不少,最终,本人所找到的认为的最佳答案是:
“如果将屏幕看作容器,那么内容就像水一样”
为什么要设计响应式界面?
经过多方查询,总结出以下几点:
1.台式机、投影、电视、笔记本、手机、平板、手表、VR……智能设备正在不断增加,“主流设备”的概念正在消失。
2.屏幕分辨率正飞速发展,同一张图片在不同设备上看起来,大小可能天差地别。
3.鼠标、触屏、笔、摄像头手势……不可预期的操控方式正在不断出现。
4.即便是使用浏览器,用户对浏览器的缩放使用习惯不同,有的人喜欢全屏有的人则喜欢半屏。
对应以上四点,响应式界面大概要考虑四个层次问题:
1.同一页面在不同大小和比例上看起来都应该是舒适的;
2.同一页面在不同分辨率上看起来都应该是合理;
3.同一页面在不同操作方式(如鼠标和触屏)下,体验应该是统一的;
4.同一页面在不同类型的设备(手机、平板、电脑)上,交互方式应该是符合习惯的
响应式界面的基本规则
1.可伸缩的内容区块:内容区块的在一定程度上能够自动调整,以确保填满整个页面
2.可自由排布的内容区块:当页面尺寸变动较大时,能够减少/增加排布的列
3.适应页面尺寸的边距:到页面尺寸发生更大变化时,区块的边距也应该变化
4.能够适应比例变化的图片:对于常见的宽度调整,图片在隐去两侧部分时,依旧保持美观可用
5.能够自动隐藏/部分显示的内容:如在电脑上显示的的大段描述文本,在手机上就只能少量显示或全部隐藏
6. 能自动折叠的导航和菜单:展开还是收起,应该根据页面尺寸来判断
渐进增强 vs. 优雅降级
-
渐进增强(progressive enhancement):针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
-
优雅降级(graceful degradation):一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
区别:优雅降级是从复杂的现状开始,并试图减少用户体验的供给,而渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带。
渐进增强/优雅降级通常是 AWD 会牵扯到的另一个技术术语。本质上而言即是随着屏幕的大小的改变,功能会一点一点增强。
也通常会用在一些高级 CSS3 属性上,我们对一些 CSS 属性进行特性检测,甚至不进行特性检测直接使用。后果是在支持它的网页上该属性正常展示,而不支持它的网页该属性不生效,但也不影响用户的基本使用。
典型的例子是 CSS3 逐渐被大众认可并被使用,PC端页面开始由 IE678 向兼容性更好的IE9+,chrome,firefox浏览器转变的时期。我们可以对页面元素直接使用阴影,圆角等属性。对于不支持它的低版本 IE 而言,没有什么损失,而对于支持它的高级浏览器而言,带给了用户更好的交互视觉体验,这就是渐进增强。
移动端屏幕适配方案
通常而言,设计师只会给出单一分辨率下的设计稿,而我们要做的,就是以这个设计稿为基准,去适配所有不同大小的移动端设备。
在此之前,有一些基础概念需要理解。
设备独立像素
以 iPhone6/7/8为例,这里我们打开 Chrome 开发者工具:
这里的 375 * 667
表示的是什么呢,表示的是设备独立像素(DIP),也可以理解为 CSS 像素,也称为逻辑像素:
设备独立像素 = CSS 像素 = 逻辑像素
也就是说,我们设定一个宽度为 375px 的 div,刚好可以充满这个设备的一行,配合高度 667px ,则 div 的大小刚好可以充满整个屏幕。
物理像素
OK,那么,什么又是物理像素呢。我们到电商网站购买手机,都会看一看手机的参数,以 JD 上的 iPhone7 为例:
可以看到,iPhone7 的分辨率是 1334 x 750
,这里描述的就是屏幕实际的物理像素。
物理像素,又称为设备像素。显示屏是由一个个物理像素点组成的,1334 x 750
表示手机分别在垂直和水平上所具有的像素点数。通过控制每个像素点的颜色,就可以使屏幕显示出不同的图像,屏幕从工厂出来那天起,它上面的物理像素点就固定不变了,单位为pt。
设备像素 = 物理像素
DPR设备像素比
DPR = 物理像素 / 设备独立像素
适配不同屏幕大小
适配不同屏幕大小其实只需要遵循一条原则,确保页面元素大小的与屏幕大小保持一定比例。也就是:按比例还原设计稿。
按照等量百分比还原出来的界面总是正确的。
然而,理想很丰满,现实很骨感。实现上述百分比方案的核心需要一个全局通用的基准单位,让所有百分比展示以它为基准,但是在 CSS 中,根据CSS Values and Units Module Level 4的定义:
提示:百分比值总要相对于另一个量,比如长度。每个允许使用百分比值的属性,同时也要定义百分比值参照的那个量。这个量可以是相同元素的另一个属性的值,也可以是祖先元素的某个属性的值,甚至是格式化上下文的一个度量(比如包含块的宽度)。
具体来说:
-
宽度(width)、间距(maring/padding)支持百分比值,但默认的相对参考值是包含块的宽度;
-
高度(height)百分比的大小是相对其父级元素高的大小;
-
边框(border)不支持百分值;
-
边框圆角半径(border-radius)支持百分比值,但水平方向相对参考值是盒子的宽度,垂直方向相对参考值是盒子的高度;
-
文本大小(font-size)支持百分比值,但相对参考值是父元素的font-size的值;
-
盒阴影(box-shadow)和文本阴影(text-shadow)不支持百分比值;
首先,支持百分比单位的度量属性有其各自的参照基准,其次并非所有度量属性都支持百分比单位。所以我们需要另辟蹊径。
rem 适配方案
rem根据网页的根元素(<html>)来设置字体大小,和 em的区别是,em 是根据其父元素的字体大小来设置,而 rem 是根据网页的跟元素(html)来设置字体大小。
不完美的地方:
1.需要引入一定的 Javascript 代码,根据 document.documentElement.clientWidth
动态修改 <html>
的 font-size ,页面其他元素使用 rem 作为长度单位进行布局,从而实现页面的等比缩放
2.rem 的设计初衷并非是用于解决此类问题,用 rem 进行页面的宽度适配多少有一种 hack 的感觉
3.存在一定的兼容性问题,对于安卓 4.4 以下版本系统不支持 viewport 缩放(当然,flexible 处理 Android 系列时,始终认为其 dpr 为 1,没有进行 viewport 缩放)
vw 适配方案
百分比适配方案的核心需要一个全局通用的基准单位,rem 是不错,但是需要借助 Javascript 进行动态修改根元素的 font-size
,而 vw/vh(vmax/vmin) 的出现则很好弥补 rem 需要 JS 辅助的缺点。
根据 CSS Values and Units Module Level 4:vw
等于初始包含块(html元素)宽度的1%,也就是
-
1vw
等于window.innerWidth
的数值的 1% -
1vh
等于window.innerHeight
的数值的 1%
根据相关的测试,可以使用 vw 进行长度单位的有:
-
容器大小适配,可以使用 vw
-
文本大小的适配,可以使用 vw
-
大于 1px 的边框、圆角、阴影都可以使用 vw
-
内距和外距,可以使用 vw
不完美的地方:
vw 确实看上去很不错,但是也是存在它的一些问题:
-
也没能很好的解决 1px 边框在高清屏下的显示问题,需要自行处理
-
由于 vw 方案是完全的等比缩放,在完全等比还原设计稿的同时带来的一个问题是无法很好的限定一个最大最小宽度值,由于 rem 方案是借助 Javascript 的,所以这一点 rem 比 vw 会更加的灵活
1px线
上面说到使用 vw 适配屏幕大小方案,其中有一个缺点就是在 Retina 屏下,无法很好的展示真正的 1px 物理像素线条。
设计师想要的 retina 下 border: 1px
,其实是 1 物理像素宽,而不是 1 CSS 像素宽度,对于 CSS 而言:
-
在 dpr = 1 时,此时 1 物理像素等于 1 CSS 像素宽度;
-
在 dpr = 2 时,此时 1 物理像素等于 0.5 CSS 宽度像素,可以认为
border-width: 1px
这里的 1px 其实是 1 CSS像素宽度,等于 2 像素物理宽度,设计师其实想要的是border-width: 0.5px
; -
在 dpr = 3 时,此时 1 物理像素等于 0.33 CSS 宽度像素,设计师其实想要的是 border: 0.333px
然而,并不是所有手机浏览器都能识别 border-width: 0.5px
,在 iOS7 以下,Android 等其他系统里,小于 1px 的单位会被当成为 0px 处理,那么如何实现这 0.5px、0.33px 呢?
这里介绍几种方法:
-
渐变实现
-
使用缩放实现
-
使用图片实现(base64)
-
使用SVG实现(嵌入 background url)
图片适配及优化
图像通常占据了网页上下载资源的绝大部分。优化图像通常可以最大限度地减少从网站下载的字节数以及提高网站性能。
通常可以,有一些通用的优化手段:
-
消除多余的图像资源
-
尽可能利用 CSS3\SVG 矢量图像替代某些光栅图像
-
谨慎使用字体图标,使用网页字体取代在图像中进行文本编码
-
选择正确的图片格式
-
为不同 DPR 屏幕提供最适合的图片尺寸
如何在不同的 dpr 屏幕下,让图片看起来都不失真?
首先就是上述的第二点,尽可能利用 CSS3\SVG 矢量图像替代某些光栅图像。某些简单的几何图标,可以用 CSS3 快速实现的图形,都应该尽量避免使用光栅图像。这样能够保证它们在任何尺寸下都不会失真。
其次,实在到了必须使用光栅图像的地步,也是有许多方式能保证图像在各种场景下都不失真。
无脑多倍图
在移动端假设我们需要一张 CSS 像素为 300 x 200
的图像,考虑到现在已经有了 dpr = 3 的设备,那么要保证图片在 dpr = 3 的设备下也正常高清展示,我们最大可能需要一张 900 x 600
的原图。
这样,不管设备的 dpr 是否为 3,我们统一都使用 3 倍图。这样即使在 dpr = 1,dpr = 2 的设备上,也能非常好的展示图片。
当然这样并不可取,会造成大量带宽的浪费。现代浏览器,提供了更好的方式,让我们能够根据设备 dpr 的不同,提供不同尺寸的图片。
布局发展历程
简单来说,前端的布局发展历程经历了下面几个过程:
表格布局 --> 定位布局 --> 浮动布局 --> flexbox布局 --> gridbox布局
每一种布局在特定时期都发挥了重要的作用,而每一种新的布局方式的出现,往往都是因为现有的布局方式已经在该时期已经无法很好的满足开发者的需求,无法满足越来越潮流的页面布局的方式。