浅谈响应式Web设计与实现思路

是否还在为你的应用程序适配PC端,移动端,平板而苦苦思索呢,是否在寻找如何一套代码适配多终端方式呢,是否但愿快速上手实现你的跨终端应用程序呢,是的话,那就看过来吧,本文阐述响应式UI设计相关理论基础,包括:屏幕尺寸,物理,设备独立,CSS像素,dpr,视口等相关概念,还有响应式设计基础,常见设计模式,及响应式UI实现基本思路,但愿能加深对响应式的理解和实践思路。javascript

欢迎访问个人我的博客css

响应式(Responsive)

响应式是什么呢?顾名思义,响应式,确定会自动响应,响应什么?应用程序是在终端屏幕窗口中展现给用户,被用户访问的,那么就是响应屏幕的变化,不一样终端屏幕尺寸大小不一致,须要针对不一样尺寸屏幕进行不一样的展现响应。html

响应式(Responsive web design, RWD),是指一套应用程序用户界面(User Interface)能自动响应不一样设备窗口或屏幕尺寸(screen size)而且内容,布局渲染表现良好。java

自适应(Adaptive)

在响应式设计(RWD)以外,还有一种适配多设备屏幕的方式,自适应设计(Adaptive web design, AWD)css3

自适应设计(AWD),是指一个应用程序使用多版本用户界面,针对不一样设备屏幕,服务器端返回不一样版本用户界面,供用户访问。git

自适应vs响应式

自适应和响应式设计的不一样主要归纳以下:es6

  1. 自适应是多套用户界面,然后者则只有一套用户界面;
  2. 自适应须要服务端检测请求设备分辨率相关信息,而后选择对应版本返回;
  3. 自适应能够在不一样版本使用不一样适配方案,如在PC端使用百分比,在移动端使用rem等,而响应式则须要一个完美兼容的适配方案;
  4. 以头条网站为例,访问www.toutiao.comPC端会打开PC版本web应用,而在移动端打开,则服务端会重定向至m.toutiao.com,对应的返回的就是移动端版本web应用;

天然的,咱们本篇要关注的天然是响应式用户界面设计,即一套应用程序适配多设备。github

移动优先(Mobile first)

从2014年开始,移动设备使用访问率已经超过PC,因此在设计响应式页面程序时,一般都是移动优先,即先适配移动样式和布局,而后再调整适配PC端。web

渐进加强(Progress enhancement)

另外咱们知道移动设备众多,一些低版本或旧系统的设备并不支持JavaScript或CSS的新特性,如es6,media query等,因此一般实现一个基础版本,在大部分设备能知足基本功能后,针对性兼容的添加新功能,新特性,逐步拓展应用,这就是渐进加强。编程

屏幕(screen)

前面讲响应式就是响应屏幕尺寸,那么屏幕尺寸如何衡量呢?主要从尺寸单位,设备独立像素和像素密度等角度考虑。

物理尺寸(Display size /Physical size)

屏幕物理尺寸,指根据屏幕对角线(diagonal)测量的实际物理尺寸,就像咱们一般说的屏幕是多少寸的,是5.1仍是5.5,平板是10.1,电视是42仍是37寸,这里的寸都指(英寸),并且是以对角线长度计量的。

对角线长度,则能够根据三角公式,由宽和高计算得出:

Physical-screen-size

逻辑尺寸(Logic size /Display resolution)

和屏幕物理尺寸相对的则有逻辑尺寸概念,或者叫它展现分辨率(resolution),而和物理尺寸以长度inch为单位不一样,逻辑尺寸则以像素(pixel)为单位计量。

Dimension

和物理尺寸以对角线为方向计量屏幕大小不一样的是,逻辑尺寸分别从横向(宽),纵向(高)两个方向表示屏幕的尺寸:width,height。以一台“1024 × 768”分辨率的笔记本为例,这表示设备屏幕的宽是1024像素,高为768像素。

物理像素(device pixel)

物理像素,也叫设备像素实际像素,在计算机数字图像中,一个像素(pixel)或一个点(dot)是在一个光栅图片(raster image)中的一个物理点,它是图像在屏幕上展现的的最小可控制元素。

所谓的光栅(raster image)或位图(bitmapped image)图片,是指将图像定义为由点(或像素)组成,每一个点(或像素)能够由多种色彩表示,包括二、四、八、1六、24和32位色彩。例如,一幅1024×768分辨率的32位彩色图片,其所占存储字节数为:1024×768×32/(8*1024)=3072KB(一字节等于8位)。

BitMapped Image

如图,将屏幕放大至必定程度,能够看见是由不少个点(或像素)组成,屏幕上的这些一个一个的点(或像素)就是咱们说的物理像素,而像素数量的不一样及每一个像素的不一样色彩表示就构成图像展现,决定它的视觉表现。

CSS像素(CSS Pixel)

除了前面介绍的物理像素,还有一种像素常常被说起,那就是CSS像素,也做逻辑像素虚拟像素,它仅仅是描述图像单元信息的概念,一般描述图像中某一个小方框所须要展现的颜色值,而这一些列方框点合起来就能描述一幅图像,web编程中用来度量网页内容尺寸或位置的就是这个抽象单位

logical pixel

分辨率(resolution)

分辨率通厂都是指设备分辨率,即设备屏幕上显示的物理像素总和,以一台“1024 × 768”分辨率的笔记本为例,这表示设备屏幕的宽是1024物理像素,高为768物理像素,它展现的像素总数就是1024*768

像素密度(Pixel density)

屏幕上每英寸(PPI,Pixel per inch)或每厘米(PPCM,Pixel per centimeter)上拥有的物理像素(或点)的数量,称为像素密度,也做屏幕密度,计算公式为:

pixel density(pd) =  屏幕宽度物理像素 / 屏幕宽度英寸;
复制代码

如一个15英寸(对角线)大小的设备,有一个12英寸宽,9英寸高的屏幕,而且其分辨率为1024*768像素,则其像素密度则大概为85PPI:

pd = 102412 ~= 7689 ~= 85PPI
复制代码

固然横纵方向上的像素密度并不老是相同的,如将上面例子的分辨率改成1280×1024,则:

  1. 横向:pd = 1280 / 12 ~=107PPI;
  2. 纵向:pd = 1024 / 9 ~= 114PPI;

分辨率转换为像素密度

根据屏幕分辨率计算得出像素密度公式,如:

d_{p}={\sqrt  {w_{p}^{2}+h_{p}^{2}}}
V_{pd}={\frac  {d_{p}}{di}}PPI
  1. w<sub>p</sub>:分辨率横向像素数;
  2. h<sub>p</sub>:分辨率纵向像素数;
  3. d<sub>p</sub>:对角线分辨率像素数;
  4. di:对角线物理尺寸(inch);
  5. V<sub>pd</sub>:像素密度,单位为PPI;

密度等级划分

为简便起见,Android 将全部屏幕密度分组为六种通用密度: 低、中、高、超高、超超高和超超超高。而低密度屏幕在给定物理区域的物理像素少于高密度屏幕。

点密度(dots per inch)

另外咱们可能还听过点密度(dots per inch,dpi),它和前面介绍的像素密度类似,一般能够交叉使用,只是描述领域不一样,像素(pixel)一般在计算机视觉显示领域使用,而点(dot)则主要在打印或印刷领域中使用。

设备独立像素(dp/dip)

设备独立像素(device independent pixel,称为dp或dip),也叫密度无关像素,是基于屏幕物理密度的抽象单位。首先由Google提出适配众多Android设备屏幕的抽象单位。在定义 UI 布局时可使用的虚拟像素单位,表示布局维度或位置。

它是一个基于计算机坐标系统的物理度量单位,而且能够将物理像素抽象为虚拟像素以便在应用中使用,而后计算机内部系统能够将应用中使用的虚拟像素转换为实际物理像素

这中抽象使得移动设备能够在不一样屏幕缩放展现信息和用户交互界面,而内部图像系统能够将应用中的抽象像素度量转换为实际像素度量,所以应用能够直接使用抽象像素,而不用编码处理大量的物理像素差别化的设备。一般,安卓设备假设“中等”密度屏幕设备独立像素基准为:

一个设备独立像素(dp/dip)等于160 dpi(或PPI) 屏幕上的一个物理像素,即等于1 / 160英寸。
复制代码

而windows则定义一个设备独立像素为96dpi屏幕上的一个物理像素,即1dp等于1 / 96英寸;Apple系统则默认一个设备独立像素为72dpi屏幕上的一个物理像素。系统运行时,根据当前屏幕的实际密度以透明方式处理 dp 单位的任何缩放 。

计算设备独立像素

如何计算某一设备的设备独立像素呢?根据上面介绍能够获得dp和inch的以下等式:

1dp={\frac {1}{ratio}}inch
  1. *ratio*:即设备系统指定的默认比例;
  2. inch:物理尺寸,英寸;

因此能够获得dp和物理像素的转换关系:

1dp={\frac {V_{pd}}{ratio}}(PPI*inch)={\frac {V_{pd}}{ratio}}pixel
  1. V<sub>pd</sub>:设备像素密度;
  2. PPI*inchpixel/inch * inch = pixel;

如,当屏幕密度为240dpi(或PPI),即V<sub>pd</sub> = 240时,1 dip 则等于1.5个物理像素(pixel)。

设备像素比(dpr)

关于物理像素,设备独立像素或CSS像素,有一个很常见的概念,设备像素比(device pixel ratio,dpr),它描述的是使用多少实际像素渲染一个设备独立像素,它的计算方式为:

dpr={\frac {N_{dp}}{N_{px}}}
  1. N<sub>dp</sub>: 设备屏幕实际像素数;
  2. N<sub>px</sub>: 屏幕设备独立像素数(PC端一般等于CSS像素数);
  3. dpr:设备像素比;

在浏览器中,咱们可使用window.devicePixelRatio获取其dpr值,dpr更高的设备屏幕会使用更多物理像素展现一个设备独立像素,因此其效果更细腻,更精致。如在一个dpr=2的设备上,1个设备独立像素须要使用4个物理像素展现,由于宽高各为2倍。

设备独立像素与CSS像素

上一小节介绍的设备像素比(dpr),一般指物理像素和设备独立像素的比例,咱们知道,CSS像素最终是须要转换为物理像素展现的,那么CSS像素如何对应物理像素呢?

  1. 根据前文设备独立像素小节所介绍,在具体设备上,设备独立像素与物理像素的比例是固定的;
  2. 在PC端,一般设备独立像素和CSS像素比例是1:1,CSS像素能以正常比例转换为物理像素展现;
  3. 在移动端,为了更好的展示页面,默认状况下会进行缩放,这时设备独立像素和CSS像素比例并非1:1,因此CSS像素与物理像素的比例就变了,因此咱们看到的效果就变了;
  4. 当咱们使用viewport meta明确设置视口width为理想视口时,视口宽度单位为设备独立像素,同时设置intial-scale=1.0即代表将CSS像素和设备独立像素比例设置为1.0,那么CSS像素到物理像素的转换就能很好的展示咱们的UI了。

UI度量(UI Dimension)

计量屏幕或屏幕内某一区域大小时,咱们能够说长,宽多少寸,可是寸只是一个物理长度概念,而在开发UI界面时,因为须要适配诸多不一样设备,因此可衡量,可比较的UI度量则须要使用数字加抽象计量单位,咱们能够称之为UI维度(UI Dimension)。

A dimension is specified with a number followed by a unit of measure

维度使用一个数字加上一个度量单位声明,如100px,10pt,10in,10dp等。

英寸(in)

Inches - Based on the physical size of the screen.

基于屏幕物理尺寸的度量单位,in

UI像素(px)

UI像素px,是一个相对单位,与之相对的是设备像素(device pixels)。一个px在不一样设备上可能对应不一样的物理像素数或(点),这取决于设备像素比(device pixel ratio)。开发页面时,常用该单位定义UI的布局和内容尺寸,文字大小,能够在浏览器中实现像素展现良好的UI界面。

可是因为不一样设备上使用px单位时不会根据设备屏幕大小进行自适应,尤为是PC和移动端差异比较大,因此通常响应式界面较少用px单位。

磅(pt)

磅,pt,即point,是印刷行业经常使用单位,等于1/72英寸,它是长度单位,是绝对大小,而px则是相对大小。

px与pt

前面说了,px是相对大小,pt是绝对大小,因此在不一样设备上,他们的关系可能不一样,以Android设备为例,一个dp等于160dpi屏幕上的一个物理像素,则:

1dp = 1 / 160 inch
复制代码

而结合前面介绍的pt单位:

1pt = 1 / 72 inch 
复制代码

对于240PPI的屏幕,则:

  1. 1dp = 1 / 160 inch = 240 / 160 px = 1.5物理像素
  2. 1px = 1 / 240 inch
  3. 1pt = 0.35物理像素 = 0.35 / dpr CSS像素(px)

em

em是在web文档中使用的一个缩放单位,1em等于最近父元素的font-size字体尺寸,如最近父元素字体为14pt,则1em=14pt。使用em单位表示的尺寸能够较好的在多终端浏览器进行样式适配。

rem

rem也是一个缩放单位,与em类似,都是基于字体尺寸,不一样的是rem是基于文档根元素字体尺寸,而与父元素字体尺寸无关,如文档根元素<html>font-size属性为12pt,而最近父元素字体为14pt,则1rem=12pt

因为rem基于根元素字体大小计算,因此在文档中,任何一处使用rem单位计算基准都同样,使得尺寸计算获得统一,而前面的em则在文档中都是基于最近父元素font-size属性值,这说明在font-size值不一样的父元素中使用em单位,计算并不能统一,这也是为何在目前的PC,移动端多设备适配方案中,rem比em更常见。

百分比(%)

还有一个%百分比单位,基于最近父元素的相关属性尺寸,乘以分配的百分比数,如父元素width为10pt,font-size:14pt,则width:10%就是1pt,font-size: 110%为15.4pt(浏览器实际渲染会化为整数渲染)。特别注意的是margin,padding属性值为百分比时,是基于当前元素width值的。

%单位也是一个缩放单位,因此也经常使用于样式适配。

视口(viewport)

在实现响应式设计以前,咱们还须要了解一些视口相关概念。

视口(viewport),便可视区域的大小,指浏览器窗口内的内容区域,不包含工具栏、标签栏等,也就是网页实际显示的区域。

视口类型

在开发移动端wap应用时,为了开发体验更友好的界面,须要了解更多视口相关概念,一般将视口分为三种:视觉视口,布局视口,理想视口。

视觉视口(visual viewport)

visual viewport定义如:

The visual viewport is the part of the page that’s currently shown on screen. The user may scroll to change the part of the page he sees, or zoom to change the size of the visual viewport。

视觉视口是指当前屏幕上页面的可见区域。用户能够滚动来改变当前页面可见部分,或者缩放来改变视觉视口的尺寸。

visual viewport默承认以经过window.innerWidth来获取,另外用户能够经过缩放来改变visual viewport的尺寸,缩小时,visual viewport值变大,放大时,visual viewport值变小。

在目前新的草案文档中,已经定义了window.visualViewportAPI能够获取视觉窗口对象,在Chrome61以上便可访问:

console.log(window.visualViewport.width);
复制代码

window.visualViewport对象属性如:

visualViewport 属性 说明
offsetLeft 视觉视口与布局视口左边界的间距以CSS pixels表示;
offsetTop 视觉视口与布局视口上边界的间距以CSS pixels表示;
pageLeft 视觉视口左边界和文档左边线的偏移距离,以CSS pixels表示;
pageTop 视觉视口上边界和文档上边线的偏移距离,以CSS pixels表示;
width 视觉视口的宽度,以CSS pixels表示;
height 视觉视口的高度,以CSS pixels表示;
scale 缩放比例,好比文档被放大2被,则返回值 2. 这个值不受设备像素比devicePixelRatio的影响。

布局视口(layout viewport)

layout viewport的定义以下:

In the CSS layout, especially percentual widths, are calculated relative to the layout viewport, which is considerably wider than the visual viewport.

在CSS布局中,好比百分比宽度是相对于布局视口来计算的,布局视口一般比视觉视口宽。

layout viewport宽度能够经过document.documenElement.clientWidthdocument.body.clientWidth来获取。

为何说布局视口一般比视觉视口宽呢,看图很容易理解:

Visual VS Layout Viewport

当给定文档内容宽度大于视觉窗口宽度时,会出现如图状况,视觉视口就是屏幕内文档可见区域,而布局视口则包括文档不可见区域,只有滚动才能查看其内容。

一般浏览器默认设置布局视口为980px或1024px,因此一般你会看到它大于设备屏幕可视区域,尤为是在移动设备上,另外从上面给的多种实例图片能够看出顶部position:fixed导航栏,始终跟随布局视口,width: 100%对应的是布局视口宽度。

理想视口(ideal viewport)

理想视口,是指设备的屏幕尺寸,单位为设备独立像素(虚拟像素,实际会被转换为物理像素展现)。

ideal viewport宽度可使用screen.width来获取,其值是由设备决定,是对设备来讲最理想的布局视口尺寸。如,iphone5理想视口为320,iphone6为375,IPhone7plus为414

这里设置视口为设备独立像素,那如何与UI使用的CSS像素匹配呢?首先设备独立像素和物理像素的比例在具体某台设备上是固定的,而后咱们知道设备独立像素和CSS像素都是虚拟单位,在PC端,一般设备独立像素和CSS像素比例是1:1,CSS像素能以正常比例转换为物理像素展现;可是在移动端,为了更好的展示页面,默认状况下会进行缩放将内容调整为适合屏幕的大小,这时设备独立像素和CSS像素比例并非1:1,因此CSS像素与物理像素的比例就变了,因此咱们看到的效果就变了,当咱们使用viewport meta明确设置视口width为理想视口时,视口宽度单位为设备独立像素,同时设置intial-scale=1.0即代表将CSS像素和设备独立像素比例设置为1.0,那么CSS像素到物理像素的转换就能很好的展示咱们的UI了。

viewport meta

在如今的移动端网页中,咱们常常能够看到这么一句代码:

<meta name="viewport", width=device-width, initial-scale=1.0>
复制代码

device-width返回的就是设备的ideal viewport宽度,这句代码就是声明当前布局使用设备理想视口宽度,在这种状况下,以iphone6理想视口为375为例,html设置width: 100%,最终获得的宽度就是320px

对于未设置meta元视口代码的页面,在移动端访问时,布局视口为默认值980px,文档被缩小以彻底展现内容,此时CSS像素与物理像素的比例变大,即一物理像素展现更多CSS像素,展现效果如图:

blog ui

此时visualViewport对象信息以下:

visualViewport

视口与布局

在iphone以前,都是经过调整内容,适配PC端网站使其在手机浏览器上也能够友好访问;后来iphone提出在“虚拟窗口”(视口)上展示网页内容,并提供viewport元信息元素以控制虚拟窗口大小。

在桌面浏览器中,浏览器窗口宽度就是咱们CSS布局时,能使用的最大宽度,若是内容宽度超出视口宽度,则会出现滚动条,以查看全部内容;在移动浏览器中则不一样,咱们能够额外使用viewport控制视口以知足展现需求。

默认布局视口

以下对于一个PC网站,PC端正常展现以下:

PC Blog

而在移动端默认状况下,展现如图:

Mobile Blog

  1. 咱们给文档html,body宽度设置为width:100%,因此html,body的宽度是980px,这是浏览器默认设置的布局视口宽度

  2. 默认,移动端浏览器布局视口为980px,而后根据页面内容进行缩放以使页面内容能在当前可视窗口彻底展现;当明确设置宽度width时:

    1. 若width大于980:咱们设置html等元素width: 1200px后,视口将缩小布局以支持更多CSS像素,即一个物理像素将对应更多CSS像素,视觉上看就是页面被缩小了,这也验证了CSS像素只是一个虚拟像素;

      Mobile 1200 px

    2. 若width小于980:咱们设置html等元素width: 400px后,内容在视口的一部分展现,剩余部分空白,视觉上并无被缩放,只是在更小的区域展现,致使文本换行,高度增长;

      Mobile 400px

比较特殊的是position:fixed;定位的顶部导航栏元素,其始终对应于布局视口。

添加meta

加入给页面添加元视口代码:

<meta name="viewport" content="width=device-width,initial-scale=1.0> 复制代码

添加如上代码后,明确设置布局视口为理想视口宽度,这样浏览器就能完美展现咱们的页面,页面也不会被缩放处理。固然,咱们设置元素样式时,其宽度便不能超过该布局视口宽度,对于iphone6,为375px;若是超出则会出现滚动条。

device-width

CSS3 媒体查询(media query)

CSS3 中的 Media Queries 增长了更多的媒体查询,就像if条件表达式同样,咱们能够设置不一样类型的媒体条件,并根据对应的条件,给相应符合条件的媒体调用相对应的样式表。如:

  1. 视口宽度大于 800px 的纵向显示屏,加载特定css文件:

    <link rel="stylesheet" media="screen and (orientation: portrait) and (min-width: 800px)" href="800wide-portrait-screen.css" />
    复制代码
  2. 打印设备特定css文件:

    <link rel="stylesheet" type="text/css" media="print" href="print.css" />
    复制代码
  3. 视口在375和600之间,设置特定字体大小18px:

    @media screen (min-width: 375px) and (max-width: 600px) {
      body {
        font-size: 18px;
      }
    }
    复制代码

响应式实现基础

响应式设计实现一般会从如下几方面思考:

  1. 组合流式布局、弹性盒子(包括图片、表格、视频)和媒体查询等技术;
  2. 使用百分比布局建立流式布局的弹性UI,同时使用媒体查询限制元素的尺寸和内容变动范围;
  3. 使用相对单位使得内容自适应调节;
  4. 选择断点,针对不一样断点实现不一样布局和内容展现;

响应式设计模式

目前,响应式设计实践大体可总结为五类:mostly fluid、column drop、layout shifter、tiny tweaks 和 off canvas,一般,咱们选择其中的某一种或几种组合实现咱们的响应式UI。

微调式(Tiny Tweaks)

Tiny Tweaks布局模式主要表现为单一列展现大部份内容,随着视口宽的的增长,改变font-size值和padding间距,以保证内容的持续可读性。

微调式针对单列布局,简单的修改字体大小,padding和margin间距,保证内容可读性。

Tiny taeaks

.c1 {
  padding: 10px;
  width: 100%;
}

@media (min-width: 600px) {
  .c1 {
    padding: 20px;
    font-size: 1.5rem;
  }
}

@media (min-width: 960px) {
  .c1 {
    padding: 40px;
    font-size: 2rem;
  }
}
复制代码

浮动式(Mostly Fluid)

Mostly Fluid布局是一种多列布局,在大屏幕上设置较大margin,可是在移动端则会浮动后续列,垂直堆叠排列。该模式很常见,由于一般只须要设置一个断点。

浮动式布局,精髓在于浮动,随着屏幕缩小,浮动后续列,一般float/flex + width而后使用media query设置不一样width值实现。

Mostly fluid

以以下html结构为例:

<!--Pattern HTML-->
<div id="pattern" class="pattern">
  <div class="c">
    <div class="main">
      <h2>Main Content (1st in source order)</h2>
      <p>1</p>
    </div>
    <div class="c2">
      <h3>Column (2nd in source order)</h3>
      <p>3</p>
    </div>
    <div class="c3">
      <h3>Column (3nd in source order)</h3>
      <p>4.</p>
    </div>
  </div>
</div>
<!--End Pattern HTML-->
复制代码

其样式一般有以下方式:

.main {
  background-color: #8e352e;
}

.c2 {
  background-color: #c84c44;
}

.c3{
  background-color: #a53d36;
}

@media screen and (min-width: 37.5em) {
  .c2, .c3 {
    float: left;
    width: 50%;
  }
}
复制代码

当屏幕宽度大于31.42em,浏览器默认font-size为16px,则为37.5 * 16 = 600px,大于600px像素时下面两个div则浮动并列显示,不然垂直堆叠展现。

断列式(Column Drop)

Column Drop也是一种多列布局方式,在移动端垂直堆叠排列,随着屏幕增大将各列平铺排列,这种模式就须要咱们选择多个断点并选择变化列。

断列士核心是将内容划分为多列,而后随着屏幕变小,依次将左/右列断开堆叠至主列下方。

Column drop

<!--Pattern HTML-->
  <div id="pattern" class="pattern">
    <div class="c">
      <div class="main">
        <h2>Main Content (1st in source order)</h2>
        <p>1</p>
      </div>
            <div class="sb">
                <h3>Column (2nd in source order)</h3>
                <p>2</p>
            </div>
            <div class="sb-2">
                <h3>Column (3nd in source order)</h3>
                <p>3</p>
                
            </div>
        </div>
    </div>
    <!--End Pattern HTML-->
复制代码

样式如:

.main {
  background-color: #8e352e;
}

.sb {
  background-color: #c84c44;
}

.sb-2 {
  background-color: #a53d36;
}
@media screen and (min-width: 42em) {
  .main {
    width: 75%;
    float: left;
    padding: 0 1em 0 0;
  }
  .sb {
    float: left;
    width: 25%;
    
  }
  .sb-2 {
    clear: both;
  }
}
@media screen and (min-width: 62em) {
  .main {
    width: 50%;
    margin-left: 25%;
    padding: 0 1em;
  }
  .sb {
    margin-left: -75%;
  }
  .sb-2 {
    float: right;
    width: 25%;
    clear: none;
  }
}
复制代码

移位式(Layout Shifter)

Layout Shifter响应式设计是指针对不一样屏幕进行不一样布局和内容展现,一般须要设置多个断点,而后针对不一样大小屏幕,进行不一样设计,和前面几种模式在处理小屏幕时自动将后面列往下堆叠不一样,在每类断点之间都须要涉及布局和内容二者的修改;这意味着咱们须要作更多的编码工做,固然咱们的可控性也更强。

移位式核心在于肯定不一样屏幕须要何种布局及内容展现方式,而后在各断点使用media query进行控制。

Layout Shifter

分屏式(Off Canvas)

在这以前的四种设计思路都是在大屏铺开展现,而后随着屏幕缩小,将其他列垂直堆叠展现,用户须要上下滚动才能查看页面全部内容,而Off Canvas模式则换了一个思路:分屏:

  1. 在小屏幕设备,将不经常使用或非主要的内容(如导航和菜单之类)放在屏幕外左右两侧,点击能够切换显示/隐藏;
  2. 在大屏幕可选择性的铺开展现;

分屏式精华是划分主要内容(如文章列表)和非主要内容(如导航栏),而后优先展现主要内容,非主要内容能够在左右两侧隐藏,支持用户主动点击/滑动切换显示/隐藏。

Off Canvas

一般的作法是,在小屏幕,设置不经常使用内容display: none;transform: translate(-200px, 0);,而后点击打开按钮时,添加恢复样式display: block;transform: translate(0, 0);,便可展现;在大屏幕则可选择性设计展现方式,一般是直接平铺。

响应式实现

理论知识基本准备的差很少了,接下来实现一个简单的例子。

设置视口

在html内添加元视口代码:

<meta name="viewport" content="width=device-width, initial-scale=1.0">
复制代码
  1. width=device-width 指定视口为理想视口,以便使用当前视口(设备独立像素为单位)能展示良好的页面;
  2. initial-scale=1 指定将 CSS 像素与设备独立像素比例设为 1:1。

intial-scale=1.0 即阻止移动浏览器自动调整页面大小 ,浏览器将按照视口的实际大小(此处设置为理想视口)来渲染页面。

固然还能够经过CSS@viewport方式声明,与meta标签效果相同:

@viewport {
  width: device-width;
  zoom: 1;
}
复制代码

其中,zoom属性等同于 viewport meta 标签的 initial-sacale 属性。

媒体查询

当前各主流浏览器基本都支持meida query,可是若是你指望网站在IE8甚至如下版本也展现良好,则须要添加兼容,能够用 media-queries.js 或 respond.js:

<!--[if lt IE 9]> <script src="//css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script> <![endif]-->
复制代码

设置断点(breakpoints)

响应式设计还有一个重要的问题是如何肯定视图断点,是以设备为依据吗?固然不行,设备是无穷无尽的,最好的实践是之内容为依据,而后从移动设备开始,从小到大依次增长一屏展现内容,肯定咱们指望的多个视图断点及布对应设计UI。

以material-ui为例,分为:

  1. xs, extra-small: > 0
  2. sm, small: >= 600
  3. md, medium: >= 960
  4. lg, large: >= 1280
  5. xl, xlarge: >= 1920

Breakpoints

能够自由选择断点并使用media query设置响应式布局,如:

/* for 1280px or less */
@media screen and (max-width: 1280px) {
  #pagewrap {
    width: 95%;
  }
  #content {
    width: 65%;
  }
  #sidebar {
    width: 30%;
  }
}
/* for 960px or less */
@media screen and (max-width: 960px) {
  #content {
  	width: auto;
  	float: none;
  }
  #sidebar {
  	width: auto;
  	float: none;
  }
}
 
/* for 600px or less */
@media screen and (max-width: 600px) {
  h1 {
    font-size: 0.8em;
  }
  #sidebar {
    display: none;
  }
}
复制代码

固然这并不意味着咱们只能使用这几个断点,也许咱们但愿在特定状况下,进行一些特定处理:

@media (min-width: 360px) {
  body {
    font-size: 1rem;
  }
}
复制代码

相对单位

既然是响应式设计,须要实现响应式视图,那么固定值的长度单位就必然很难知足指望;若是使用固定单位,如px,则须要针对每一种状况进行不一样处理,多了不少工做,不然就没法实现响应式。

例如,给在容器div设置width: 100%;能够确保其填充视口宽度,相对视口而言不会太大也不会过小,不管设备是宽度为320像素的 iPhone五、宽度为375像素的iPhone6,仍是宽度为360像素的 Nexus 5,div 均会适应于这些设备屏幕;此外,使用相对单位能够自动调整内容尺寸空间,而不会出现横向滚动条的状况。

.wrap {
  width: 320px;
  font-size: 20px;
}
// 相对单位
.wrap {
  width: 100%;
  font-size: 1.25rem;
}
复制代码

相对单位有百分比(%),em,rem等。

响应式文本

针对网站可读性的调研发现,阅读体验友好段落行内应该包含 70 到 100 个字符,一般是8-15个英文单词,20-50个中文汉字,因此须要针对视图断点进行控制:

width: 100%;
padding: 10px;
@media screen (max-width: 600px) {
  .article {
    width: 100%;
    papdding: 15px;
    margin: 0 auto;
    font-size: 1rem;
  }
}

@media screen (min-width: 600px) and (max-width: 960px) {
  .article {
    max-width: 700px;
    margin-left: 0 auto;
  }
}
复制代码

如上,在较小的屏幕上,大小为1rem的字体可使每行完美地呈现约20-30中文,而在较大的屏幕上就须要添加断点了,如,当浏览器宽度超过 600px,则内容理想宽度是100%,最大理想宽度是700px。

响应式图片

由于布局是响应式的,因此图片也须要根据布局进行响应式展示。

弹性图片布局

首先在布局上,咱们的图片确定须要随着布局变动而弹性变化,因此不能设置固定尺寸,一般使用相对单位,设置以下样式:

.img-wrap {
  width: 100%;
}
img { max-width: 100%; }
复制代码

设置宽度100%,宽度自适应,不设置高度,图片高度将按照图片分辨率比例自适应,因而,图片即可以自动跟随容器缩放良好展示。

同时咱们也有必要为图片容器设置最大宽度,避免出现图片拉伸过大,损失质量的状况:

.img-wrap {
  max-width: 200px;
}
复制代码

图片响应式

是否是这样就结束了呢?固然不是,一般,PC端须要使用大尺寸图片展示,可是在移动端限于带宽和网络流量缘由,必然不适合使用大尺寸图,图片内容也须要响应式,咱们应该为不一样的屏幕尺寸提供不一样的图片,为大屏幕准备大尺寸图片,小屏幕准备尺寸更小的清晰图片,另外高分辨率 (2x, 3x) 显示屏上高分辨率图片可保证清晰度。

Responsive imgs

srcset

srcset 属性加强了 img 元素的行为,咱们能够针对不一样设备提供不一样尺寸图片。相似于 CSS 原生的 image-set CSS 函数srcset 也容许浏览器自动根据设备特性选择最佳图像,例如,在 2x 显示屏上使用 2x 图像。

<img src="photo.png" srcset="photo@2x.png 2x" />
复制代码

在不支持 srcset 的浏览器上,浏览器需使用 src 属性指定的默认图像文件,因此须要始终包含一个在任何设备上都能显示的默认图像。若是 srcset 受支持,则会在进行任何请求以前对逗号分隔的图片条件列表进行解析,而且只会下载和显示默认图片。

固然该方式目前兼容性实在不乐观,比较少使用。

艺术方向(picture)

艺术方向是指使用 picture 元素,根据设备特性选择特定图像。 picture 元素支持声明式方式定义,根据设备大小、设备分辨率、屏幕方向等不一样特性来提供一个图片的多尺寸版本:

<picture>
  <source media="(max-width: 599px)" srcset="profile-s.png">
  <source media="(min-width: 600px)" srcset="profile-600w.png">
  <img src="profile-600w.png" alt="Progile">
</picture>
复制代码
  1. picture元素包含了source元素列表,浏览器能够根据当前设备特性选择特定源图片,而后须要声明一个img元素提供默认图片;
  2. <source>元素包含一个media属性,该属性是一个媒体条件,根据这个条件决定显示哪张图片,从上至下,遇到匹配条件为真,则显示对应图片。在如上实例,若视口宽度不超过599px,则显示第一个<source>元素srcset指定的图片,若视窗宽度大于或等于600px,则显示第二张图片;
  3. srcset属性包含要显示图片的路径。请注意,正如咱们在<img>上面看到的那样,<source>可使用引用多个图像的srcset属性,还有sizes属性。因此支持经过一个 <picture>元素提供多个图片,也能够给每一个图片提供多分辨率的图片,不过一般需求比较少;
  4. 最后一点须要注意的是,咱们应该老是在 </picture>前面提供一个<img>元素以及它的srcalt属性,不然不会有图片显示,而且当媒体条件都不匹配时,会加载img提供的图片,;另外,若是浏览器不支持 <picture>元素,也会默认使用该img元素替换;

更多关于响应式图片信息能够查阅参考资料

总结

本文主要介绍了响应式设计相关理论基础,包括:屏幕尺寸,物理,CSS像素等相关概念,视口,响应式设计基础,常见设计模式,及响应式UI实现基本思路等,目前最多见的多屏适配rem方式,博主计划后续继续介绍。

参考

  1. Responsive Design
  2. Respinsive Web Design
  3. A tale of two viewports
  4. Display Size
  5. Viewport Meta tag
相关文章
相关标签/搜索