前端适配-自适应与响应式

1,125 阅读9分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

两大概念

  • 自适应:匹配不同尺寸大小的屏幕,显示对应的大小与布局,常用于开发多套页面

  • 响应式:根据浏览器页面的大小动态改变页面布局与元素大小,常用于开发一套页面

适配情况

  • pc端适配

  • 移动端适配

  • pc端与移动端的适配(全适配),跨设备适配

    不建议采用第三种适配情况,首先代码量十分巨大,需要大量的css媒体查询来匹配不同设备的样式。
    
    其次,往往在移动端许多pc端的元素需要被隐藏,这些元素在移动端是不需要的,耗费浏览器性能。
    
    注:根据实际项目情况为准!!!
    

图片适配

场景

  • 缩小(放大)时若没有按照图片宽高比进行缩小(放大)会出现图片变形的现象。

  • 图片按照等比例缩小(放大)后会出现图片模糊的现象。

      场景一很容易理解,当图片不按照固定宽高比缩放后,
      
      图片或多或少肯定会被挤压或者拉伸,也就出现了变形的情况。
    

位图和矢量图

  • 位图

位图在浏览器上是由像素点组成,就是说一个像素点显示一个颜色,最终所有的像素点组成我们看到的图片。将图片缩放后,像素点会被压缩重叠或者拉伸扩散,导致图片出现模糊。常见的位图格式有jpg、png等

  • 矢量图

矢量图是由几何图形(线段、曲线)组成,与分辨率无关可以任意缩放图片大小而不影响清晰度。常见的矢量图格式有svg。

解释场景二:

位图放大时,由于栅格被放大,因此图像看起来由许多方格组成,马赛克化明显;

位图缩小时,由于图形被压缩,造成栅格重叠,无法完全显示图形内容,表现为看起来图像扭曲或模糊。

位图与矢量图的区别

既然矢量图可以任意缩放、不模糊且大部分体积小,这不就达到了网站图片高清显示的效果了吗?那么为何不把网站全部图片换成矢量图呢?

  • 位图表现的色彩比较丰富,可以显示更加丰富的图像;而矢量图色彩相对不丰富,无法表现逼真事物。位图常用来展示色彩鲜艳、元素较多的大图,而矢量图常用来展示图标、logo等简单图像。

  • 位图由于要显示更多的色彩,所占的空间会比较大;而矢量图则所占的空间较小。

  • 矢量图可以任意缩放,是因为需要完整记录细节繁多的图像信息,刻意去绘制每一个细节。而忽略了需要在何种显示器上显示,比如电影院屏幕和手表屏幕使用的矢量图就可能是同样大小的矢量图;而位图相当于和屏幕一对一匹配,显示固定的像素,可以通过压缩图像进行缩放。

浏览器图片缩放算法

浏览器对图片进行缩放时,不同浏览器会采用不同的图片缩放算法。

常见的算法有:

  • 最近临近算法
  • 双线性插值算法

在css中有一个属性可以修改浏览器的缩放算法,就是image-rendering。

属性值:

  • auto:默认值,表示图片进行平滑缩放,不同浏览器采用不同的算法。

  • crisp-edges:使用算法达达到在绽放时保持对比度和边缘,设置后图片缩小后不会变的模糊,而是锐化像素边缘,此属性主要是处理的图片缩小时的算法类型。

  • pixelated:放大图像时, 使用最近邻居算法,就是多出来的像素有邻近的像素点色值进行填充,并不做模糊处理,此属性主要处理图片放大时的算法类型

解决方案

1、采用2倍图,然后前端根据需要缩放到相应的尺寸,此时缩放图片不会模糊。(图片体积大,影响首屏加载速度)

2、pc端和移动端采用两套图片,媒体查询时显示对应设备的图片。(推荐)

3、采用svg图片,矢量图缩放不会影响图片清晰度。(存在浏览器兼容问题)

字号适配

场景

  • 大屏幕显示更多的内容,而小屏保证字体清晰可见的情况下显示内容,此时字号往往不需要变化。

  • 根据屏幕分辨率的不同对应显示不同字号的字体,此时字号需要动态变化。

     具体业务需要根据业务场景决定!
    

浏览器对字号的限制

谷歌浏览器对小于12px的字体不具备识别能力,默认最小字体字号为12px。最小字号针对中文,英文没有限制。

由于中文字体的复杂性,过于小的字体识别难度高
其实,开发人员可以通过谷歌浏览器设置调整谷歌浏览器的默认最小字号,
但是当页面展示给用户的时候,我们不能指望用户通过设置调整默认字号。

既然无法设定更小的字号,那么我们可以考虑到缩放的情况,给字体缩小对应的比例,可以达到缩小字号的效果。

缩放的方式

  1. zoom:%
  2. -webkit-transform:scale(%)

区别:

  • zoom是相对于元素左上角缩放;而scale是相对于元素中间缩放。
  • zoom缩放改变了元素占据空间的大小;而scale缩放保持原始占据的空间大小。
  • zoom缩放受限于浏览器最小字号限制;而scale纯粹对元素比例进行缩放。
  • zoom缩放会引起页面重排,影响页面渲染性能;而scale只会重绘。

解决方案

采用rem+媒体查询的形式适配字号,将设计稿上的px单位转换成rem单位,相对于root的字号(默认root字号为16px)。媒体查询匹配不同分辨率的屏幕,修改root的字号。

布局适配

在传统布局方案中中,要确定一个元素的布局位置。

  • 通过position然后设置偏移量固定到具体的位置;
  • 通过float将元素固定在左侧或右侧;
  • 通过margin隔出一定的距离,使元素到具体的位置;

缺点:

  • 元素的尺寸以及布局单位通常是px,属于绝对单位。但是不同屏幕的分辨率不同,对于固定单位的元素会产生不同的展示效果。
  • 脱离文档流,影响整体页面的布局,加大布局的难度。

flex、grid布局方案

何为弹性布局?元素的布局位置不需要借助固定的绝对单位长度,确定元素的位置。且根据容器的变化,容器内的项目布局会根据容器的变化进行相应改变。

flex

属于一种轴线布局方案,可以看作一维空间布局,用于指定容器内的项目相对于轴线进行布局。默认轴线为水平方向,可以改变轴线的方向。flex中在响应式布局的一个重要属性是flex属性:flex:x;表示占据轴线的比例

比例代表着是一个动态变化的值,也就达到了响应式布局的效果。

推荐文章(阮一峰):Flex 布局教程:语法篇

grid

属于一种网格布局方案,可以看作二维空间布局,将元素划分为行和列,交错产生单元格。用于指定项目所在的单元格,以及项目在单元格内的布局方式。布局方式比flex更加强大,但是存在着浏览器的兼容性问题。grid中在响应式布局中的一个重要属性值是fr关键字: grid-template-columns: xfr;表示占据一列的比例

推荐文章(阮一峰):CSS Grid 网格布局教程

百分比布局方案

常用的做法:宽度设置百分比,高度固定单位

  • 子元素width、height的百分比:子元素的width或height中使用百分比,是相对于子元素的直接父元素

  • margin和padding的百分比:在垂直方向和水平方向都是相对于直接父亲元素的width,而与父元素的height无关

  • border-radius的百分比:border-radius的百分比是相对于自身宽度,与父元素无关

vw布局方案

vw视口宽度单位,表示占据视口宽度的比例,100vw表示占满视口。

%与vw相比:

相同点:都需要计算百分比

区别:

  • 百分比方案相对于直接父元素
  • vw相对于视口宽度

其他适配方案

  1. 纯媒体查询 + px

  2. 媒体查询设置根节点字号 + rem

  3. js动态计算屏幕宽度设置根节点字号 + rem

  4. 设置meta缩放比例,将设备窗口调整为设计图大小。

  5. postcss-px-to-viewport插件,将px转为vw,需要webpack配置

  6. amfe-flexible + flexiable

最佳适配思路:尽最大努力实现弹性可伸缩布局(响应式),并在媒体查询的各个断点区间内指定响应的尺寸(自适应)。

因此,使网页可以在不同设备上适配,只需要在断点区间加媒体查询即可。由于我们的布局是弹性可伸缩的,适配网页在小屏幕上的显示,无非就是把一些外边距收缩到最小,然后把因为屏幕太窄而无法完整显示的内容调整为单栏布局而已。若需要大量的媒体查询才可以设计适应大大小小屏幕,那不妨退一步,重新看看自己的代码结构。