1.关于自适应布局的一些基本概念

  • px (pixel):像素,是屏幕上显示数据的最基本的点,表示相对大小。不同分辨率下相同长度的px元素显示会不一样,比如同样是14px大小的字,在1366✖768显示屏下会显示的小,在1024×768尺寸的显示器下会相对大点。也称为物理像素(设备像素),是分辨率的尺寸单位。

  • pt是一种固定长度的度量单位,能够使用测量设备测得的长度,等于1/72英寸。

  • css像素,在不同屏幕上,css像素呈现的物理尺寸一致,但css像素对应的物理像素具数不同。标准的显示密度下,1个css像素对应一个物理像素,缩放时,1个css像素对应的物理像素会减增。css像素称为设备独立像素(device independent pixels: DIPs)

  • PPI (pixel per inch),像素密度,每英寸所拥有的像素数。值越高,屏幕越细腻。

  • DPI(dot per inch),打印设备每英寸印刷出来的点有多少个,值越高,图片越细腻。

  • DPR 设备物理像素和设备独立像素比,即,window.devicePixelRatio = 物理像素/css像素,是指在理想布局宽度,使用多少个物理像素来渲染一个设备独立像素。js中通过window.devicePixelRatio获取,css中通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio,-webkit-max-device-pixel-ratio进行媒体查询

  • 屏幕分辨率:若屏幕分辨率是1024×768,即设备屏幕的水平方向上有1024个像素点,垂直方向上有768个像素点。

  • em 相对父元素的font-size

  • rem 相对长度单位,相对于根元素font-size计算值的倍数

  • 视口 viewport 属性值提供有关视口初始大小的信息。PC端视口指的是浏览器可视区域,宽度与浏览器窗口保持一致。移动端涉及布局视口(Layout Viewport)、视觉视口(Visual ViewPort)和理想视口(Ideal ViewPort)。布局视口是指用 用视口元标签(viewport meta)来进行布局视口设置,视觉视口是指用户当前看到的区域,理想视口是屏幕分辨率的值,通过设置 <meta name = "viewport" content = "width = device-width, initial-scale = 1.0">实现。参考文章
    https://www.quirksmode.org/mobile/viewports2.html

  • vw(viewport width) 视窗宽度,1vw = 视窗宽度的1%
  • vh(viewport height) 视窗高度,1vh = 视窗高度的1%

方案

viewport方案 配置默认根字号、默认字号、默认设计稿宽度,然后使用postcss插件将代码中的px自动转换成rem,这种方法可以完成使用1080p设计稿再不同手机下的适应方案,所有元素大小均按照1080p下的大小来定义px。配置上述插件后,px单位在编译后会默认转为rem单位,如果不需要被转换,可以将小写的px改成大写的PX或Px。取消使用viewport.js文件,如果遇到不能适配的公共组件,则拷贝一个新的版本,适配新的方案,逐步淘汰老版本。

// 引用该mixin,其中包含了默认的变量等
$default-font-size: 100;    // 默认根字号大小,用于换算vw单位
$baseFontSize: 100px;   // 默认字号大小,用于计算rem值
$pageWidth: 1080;       // 默认的设计稿宽度
@import '@oppobrowser/lib-browser-scss/src/mixins.scss';//项目的vue.config.js中增加如下postcss配置
// 在css配置项中增加postcss配置,用于px转rem单位,后续合到master后就统一配置了
css: {loaderOptions: {sass: {data: '@import "@/common/scss/variables.scss";',},postcss: {plugins: [require('postcss-pxtorem')({// 把px单位换算成rem单位rootValue: 100, // 换算的基数(设计图1080的根字体为100)selectorBlackList: [], // 忽略转换正则匹配项propList: ['*'],}),],}
}
  • rem方案 针对Android4.4以下版本,全部使用rem单位兼容方案,并在head标签内添加脚本重写html根字号的大小,1080p下为100px。并且针对受影响的公共组件写出兼容性代码。
<script type="text/javascript">(function(doc, win) {var basicWidth = 1080;var minWidth = 360;var htmlElement = doc.documentElement;var dpr = parseInt(window.devicePixelRatio || 1, 10);var recalc = function() {var clientWidth = htmlElement.clientWidth || (basicWidth / 2);window.rootFontSize = 100 * (clientWidth / basicWidth);clientWidth = clientWidth < minWidth? minWidth : clientWidth;htmlElement.style.fontSize = 100 * (clientWidth / basicWidth) + 'px';htmlElement.setAttribute("data-dpi", dpr);};recalc();if (!win.addEventListener) return;win.addEventListener('resize', recalc, false);})(document, window);
</script>

HTML5 移动端自适应方案与踩坑

各种适配方案比较

  • rem方案,根据屏幕宽度设置html标签的font-size,再布局时使用rem单位布局,达到自适应的目的。是弹性布局的一种实现方式

使用Flexible实现手淘H5页面的终端适配
lib-flexible

实现原理:

(function flexible (window, document) {var docEl = document.documentElement //文档对象根元素的只读属性var dpr = window.devicePixelRatio || 1 //获取设备dpr// adjust body font sizefunction setBodyFontSize () {if (document.body) {document.body.style.fontSize = (12 * dpr) + 'px'//浏览器有最小字体限制,css在pc上font-size是12,也就是css像素是12,其DPR为1,在移动端dpr有可能为2和3,为了保证字体不变小,需要用12*dpr进行换算。在普通屏幕下1个CSS像素对应1个物理像素,而在Retina屏幕下,1个CSS像素对应的却是4个物理像素。}else {document.addEventListener('DOMContentLoaded', setBodyFontSize)}}setBodyFontSize(); //在html文档加载和解析完成后设置body元素字体大小// set 1rem = viewWidth / 10function setRemUnit () { //将页面元素分为100份,每份为a,1rem=10avar rem = docEl.clientWidth / 10 docEl.style.fontSize = rem + 'px'}setRemUnit()// reset rem unit on page resizewindow.addEventListener('resize', setRemUnit)window.addEventListener('pageshow', function (e) { //当一条会话历史纪录被执行的时候出发事件,包括后退/前进按钮,同时会在onload页面触发后初始化页面时触发if (e.persisted) {setRemUnit()}})
//当页面缩放/前进/后退的时候调整rem大小// detect 0.5px supportsif (dpr >= 2) {var fakeBody = document.createElement('body')var testElement = document.createElement('div')testElement.style.border = '.5px solid transparent'fakeBody.appendChild(testElement)docEl.appendChild(fakeBody)if (testElement.offsetHeight === 1) { //offsetHeight返回元素像素高度,高度包含元素边框/内边距和水平滚动条docEl.classList.add('hairlines')//只读属性,返回一个类属性的实时DOMTokenList集合}docEl.removeChild(fakeBody)}
}(window, document))

具体来讲就是

  • 获取文档根元素和设备dpr,在html文档加载和解析完成后调整body字体大小
  • 获取元素的内部宽度,不包括垂直滚动条,边框和外边距
  • 在页面缩放/回退/前进的时候重新调整rem大小
    *用css处理器或npm包将页面css样式中的px自动转换成rem
  • 文本字号不建议使用rem,在制作H5的页面中,rem并不适合用到段落文本上,在整个flexible适配方案中,文本使用px作为单位i,使用[data-dpr]属性来区分不同dpr下的文本字号。
(function(win, lib) {var doc = win.document;var docEl = doc.documentElement;var metaEl = doc.querySelector('meta[name="viewport"]');var flexibleEl = doc.querySelector('meta[name="flexible"]');var dpr = 0;var scale = 0;var tid;var flexible = lib.flexible || (lib.flexible = {});if (metaEl) { //meta名称为viewport的标签设置了scale时,将根据scale手动设置dpr(dpr用于实现flexible其他功能)console.warn('将根据已有的meta标签来设置缩放比例');var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/);if (match) {scale = parseFloat(match[1]);dpr = parseInt(1 / scale);}} else if (flexibleEl) {   //meta名称为flexible的标签存在时,手动设置dprvar content = flexibleEl.getAttribute('content');if (content) {var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);if (initialDpr) {dpr = parseFloat(initialDpr[1]);scale = parseFloat((1 / dpr).toFixed(2));    }if (maximumDpr) {dpr = parseFloat(maximumDpr[1]);scale = parseFloat((1 / dpr).toFixed(2));    }}}if (!dpr && !scale) { //根据js获取到的devicePixelRatio设置dpr及scale,scale是dpr的倒数。(ios系统根据dpr的值设置为1、2、3,Android统一设置dpr为1)var isAndroid = win.navigator.appVersion.match(/android/gi);var isIPhone = win.navigator.appVersion.match(/iphone/gi);var devicePixelRatio = win.devicePixelRatio;if (isIPhone) {// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                dpr = 3;} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){dpr = 2;} else {dpr = 1;}} else {// 其他设备下,仍旧使用1倍的方案dpr = 1;}scale = 1 / dpr;}docEl.setAttribute('data-dpr', dpr);if (!metaEl) {//添加meta标签,设置name为viewport,content根据scale设置缩放比(默认、最大、最小缩放比)metaEl = doc.createElement('meta');metaEl.setAttribute('name', 'viewport');metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');if (docEl.firstElementChild) {docEl.firstElementChild.appendChild(metaEl);} else {var wrap = doc.createElement('div');wrap.appendChild(metaEl);doc.write(wrap.innerHTML);}}function refreshRem(){//resize事件与pageshow事件延时300毫秒触发fontSize的重置(这里用了防抖函数,防止resize事件被高频触发可能引起的性能问题) var width = docEl.getBoundingClientRect().width;if (width / dpr > 540) {width = 540 * dpr;}var rem = width / 10;docEl.style.fontSize = rem + 'px';flexible.rem = win.rem = rem;}win.addEventListener('resize', function() {clearTimeout(tid);tid = setTimeout(refreshRem, 300);}, false);win.addEventListener('pageshow', function(e) {if (e.persisted) {clearTimeout(tid);tid = setTimeout(refreshRem, 300);}}, false);if (doc.readyState === 'complete') {doc.body.style.fontSize = 12 * dpr + 'px';} else {doc.addEventListener('DOMContentLoaded', function(e) {doc.body.style.fontSize = 12 * dpr + 'px';}, false);}refreshRem();//为body设置fontSize,值为12*dpr+”px” 7.扩展一些方法:获取页面dpr,获取rem基准值,rem与px相互转换,重置dpr,这些方法可以在引入flexible.js之后调用,使用方式参考api文档。flexible.dpr = win.dpr = dpr;flexible.refreshRem = refreshRem;flexible.rem2px = function(d) {var val = parseFloat(d) * this.rem;if (typeof d === 'string' && d.match(/rem$/)) {val += 'px';}return val;}flexible.px2rem = function(d) {var val = parseFloat(d) / this.rem;if (typeof d === 'string' && d.match(/px$/)) {val += 'rem';}return val;}})(window, window['lib'] || (window['lib'] = {}));

当然针对高清屏,它还会设置“viewport scale”,以缩放页面,解决类似高清屏下无法实现1px边框等问题。

响应式针对的是不同分辨率设备而进行的适配式设计,以利用@media规则为主要手段,而自适应则忽略@media以比例布局为主,目的是适应不同的浏览器窗口大小。

存在的问题
https://juejin.im/post/5c8870c1e51d453ce668cc7f
http://dwbbb.com/blog/flexible/

这个方案存在的问题:

    1. 小数像素问题,浏览器渲染最小的单位是像素,元素根据屏幕宽度自适应,通过rem计算后的距离值出现小数像素,浏览器会对这部分小数四舍五入,按照整数渲染颜色。浏览器在渲染时所做的摄入处理只是应用在元素的尺寸渲染上,其真实占据的空间依旧时原始大小。也就是说如果一个元素尺寸是 0.625px,那么其渲染尺寸应该是 1px,空出的 0.375px 空间由其临近的元素填充;同样道理,如果一个元素尺寸是 0.375px,其渲染尺寸就应该是 0,但是其会占据临近元素 0.375px 的空间。会导致:缩放到低于1px的元素时隐时现(指定最小转换像素,对于比较小的像素,不转换为rem或vw);两个同样宽度的元素因为各自周围的元素宽度不同,导致两元素相差1px;宽高相同的正方形,长宽不等了;border-radius: 50% 画的圆不圆。
    1. 包含在小数像素问题中的0.5px问题 目前的解决方案有: viewport放大为device-width的dpr倍数,然后缩小1/dpr倍显示;border-image(svg绘制)设为一个一半透明一半显示的图片;媒体查询配合伪元素,为伪元素设置1px的边框,然后缩小1/dpr倍显示;
    1. Android浏览器下line-height垂直居中偏离的问题。常用的垂直居中方式就是使用line-height,这种方法在Android设备下并不能完全居中。
    1. 不是纯css移动适配方案,需要引入js文件 也就是说css样式和js代码有一定的耦合性。且必须将改变font-size的代码放在css样式之前。
    1. 宽高比变化引起呈现变化,常见高宽比16:9,其他情况有ipad的4:3,魅族16:10,手机横屏显示
    1. 不支持响应式设计方案,响应式设计需要用到css3媒体查询,根据查询到的设备宽度使用不同的css样式,引入flexible的页面会根据dpr进行缩放,css3媒体查询得到的是缩放前的宽度而不是缩放后的宽度
    1. cursor:pointer 元素点击背景变色的问题,对添加了cursor:pointer属性的元素,在移动端点击时,背景会高亮。为元素添加-webkit-tag-highlight-color:transparent 属性可以隐藏背景高亮。
  • 8. 富文本编辑器适配问题

需要注意的是,浏览器有最小字体限制,PC上是12px,移动端是8px。并且大屏小屏隐含的意思是手机屏幕的分辨率不一样,也就是dpr不一样。

移动端H5开发,在不同分辨率,不同手机屏幕下会遇到的问题

  • retina下,图片高清问题,通过css媒体查询或js条件判断,在不同的dpr下,加载不同尺寸的图片。还可以使用srcset、Image异步加载图片,
  • 0.5px border问题,通过设置tramsform: scaleY(.5)缩小0.5倍来达到0.5px的效果,同时会导致字体大小和页面布局被缩放
  • 多屏适配布局问题 基于rem原理,针对不同手机屏幕尺寸和dpr动态改变根节点html的font-size大小(基准值)
    https://juejin.im/post/5b6503dee51d45191e0d30d2

拉勾网:文字流式,控件弹性,图片等比缩放
网易新闻:rem+vw+媒体查询(这里可以放一个截图)
font-size需要额外的媒介查询,且font-size不能用rem,当deviceWidth大于设计稿的横向分辨率时,html的font-size始终等于横向分辨率/body元素宽。
淘宝

控件弹性指的是,navigation、cell、bar等适配过程中垂直方向上高度不变;水平方向宽度变化时,通过调整元素间距或元素右对齐的方式实现自适应。这样屏幕越大,在垂直方向上可以显示更多内容,发挥大屏幕的优势。

按照上述默认适配规则,大中小三种屏幕显示效果均相同。有时候想在大屏幕显示更多内容,需要设计出特殊适配效果。比如App store首页焦点图,从iPhone 6适配到iPhone 6 plus时焦点图尺寸和排版做了特殊处理。底下应用列表也从一排3+个变成一排4+个,真正实现了大屏幕显示更多内容的理念。这些就需要设计师给出相应设计稿。

https://www.zhihu.com/question/25308946

进阶部分:

  1. 设计给的稿子双倍的原因是iphone6屏幕属于高清屏,dpr比较大,显示的像素较为清晰
  2. 一般手机的dpr是1,iphone4,iphone5高清屏是2,iPhone6s高清屏是3,可以通过js的window.devicePixelRatio获取到当前设备的dpr,所以iphone6给的视觉稿大小是(*2)750✖1334
  3. 取到dpr之后,在viewport meta头里,取消让浏览器自动缩放页面,自己去设置viewport的content,这样设置是因为给border设置1px,在scale的影响下,高清屏会显示成0.5px的效果

兼容性这一部分

  • ios: 6.1系统以上都支持
  • android: 2.1系统以上都支持
  • 大部分主流浏览器都支持

https://3g.163.com/touch/news?version=v_standard

查找各个方法的兼容性网址

vh,vw实现移动端适配

视口:浏览器中用于呈现网页的区域叫视口,移动端的视口通常指的是布局视口

  • vw : 1vw 等于视口宽度的1%
  • vh : 1vh 等于视口高度的1%
  • vmin : 选取 vw 和 vh 中最小的那个
  • vmax : 选取 vw 和 vh 中最大的那个

视口单位区别于%单位,视口单位是依赖于视口的尺寸,根据视口尺寸的百分比来定义,%单位则是依赖元素的祖先元素。

就主流的响应式布局、弹性布局来说,通过 Media Queries 实现的布局需要配置多个响应断点,而且带来的体验也对用户十分的不友好:布局在响应断点范围内的分辨率下维持不变,而在响应断点切换的瞬间,布局带来断层式的切换变化。

而通过采用rem单位的动态计算的弹性布局,则是需要在头部内嵌一段脚本来进行监听分辨率的变化来动态改变根元素字体大小,使得 CSS 与 JS 耦合了在一起。

通过利用视口单位实现适配的页面,是既能解决响应式断层问题,又能解决脚本依赖的问题。

实现原理

    1. 用相关工具将设计稿尺寸转化为vw单位,包括文本,布局高宽,间距等
  • 2.物理像素线,普通屏幕下1px,高清屏幕下0.5px的情况,采用transform属性scale实现,

物理像素线(也就是普通屏幕下 1px ,高清屏幕下 0.5px 的情况)采用 transform 属性 scale 实现。

<style>
div.x{@media only screen and (-webkit-min-device-pixel-ratio: 2){-webkit-transform: scale(0.5);-webkit-transform-origin: 50% 0%}
}
</style>
  • 3.对于需要保持高宽比的图,使用padding-top实现
    padding-left/right/top/left的值为百分比形式时,当值为百分数时,是以父元素宽度为参考的,意为父元素宽度 ➗ 左/右/上/下边距,如设置width: 10%; padding-top: 20%;,则出现的是宽高比为1:2的矩形。
    在默认的水平文档流方向下,CSS margin和padding属性的垂直方向的百分比值都是相对于父元素宽度计算的。

搭配vw+rem实现

实现vw实现移动端自适应,由于是利用视口单位实现的布局,依赖于视口大小而自动缩放,无论视口过大还是过小,它也随着视口过大或者过小,失去了最大最小宽度的限制。
结合rem单位来实现布局,rem 弹性布局的核心在于动态改变根元素大小,那么我们可以通过:

  • 给根元素大小设置随着视口变化而变化的 vw 单位,这样就可以实现动态改变其大小。
  • 限制根元素字体大小的最大最小值,配合 body 加上最大宽度和最小宽度

第一,做法二相对来说用户视觉体验更好,增加了最大最小宽度的限制;

第二,更重要是,如果选择主流的rem弹性布局方式作为项目开发的适配页面方法,那么做法二更适合于后期项目从 rem 单位过渡到 vw 单位。只需要通过改变根元素大小的计算方式,你就可以不需要其他任何的处理,就无缝过渡到另一种CSS单位,更何况vw单位的使用必然会成为一种更好适配方式,目前它只是碍于兼容性的支持而得不到广泛的应用。

如果要做到弹性布局,当然是推荐vw,如果仍然希望达到更高兼容性,则应该使用post css把它处理成rem。
一个好的弹性布局,应该能够根据实际设计语义,综合运用以下css/html特性:
Media Query正常流排版(display:inline-block、display:block、display:inline)最大最小宽高(min-width、max-width)多栏(column-width等)flexbox(display:flex)相对单位(% em rem vw wh wmax vmin)图片集(srcset、imageset)SVG

rem 在封装组件时会和html字体耦合
使用vm/vh就完全的解耦了

calc也基本可以使用了

https://yanhaijing.com/css/2017/09/29/principle-of-rem-layout/

目前的理解是,rem方案兼容性好,但是不是纯css适配方案,需要引入js文件,要保证加载体验,需要头部内联,为了保证实时性,需要多个浏览器变化事件监测,并且字体的大小需要分别设置。vw方案在屏幕较大或较小时体验不好,无法实现对屏幕最大最小限制,而rem可以通过控制html根元素的font-size最大值,解决这个问题。

  • calc()函数在声明css属性时执行一些计算,用于计算不确定值,如外边距为10px,宽度为100%的元素,设置
width: 100%;
margin: 10px;

用calc()函数解决溢出问题

width: 800px;
width: calc(100% - (10 * 2)px)
margin: 10px;

同时要给出基于iphone6计算的样例,rem/vw等
https://www.zhihu.com/question/25308946

https://aotu.io/notes/2017/04/28/2017-4-28-CSS-viewport-units/index.html

https://yanhaijing.com/css/2017/09/29/principle-of-rem-layout/

百分比方案

响应式布局的常用解决方案对比

  • 子元素height和width的百分比 基于子元素的直接父元素,width相对于父元素的width,height相对于父元素的height。
  • top和bottom 、left和right 相对于直接非static定位(默认定位的)父元素的高度/宽度。
  • padding和margin 不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,而与父元素的height无关。
  • border-radius border-radius不一样,如果设置border-radius为百分比,则是相对于自身的宽度

方法:使用百分比定义宽度,高度用px固定,根据可视区域和父元素的实时尺寸进行调整,尽可能适应各种分辨率,配合max-width和min-width属性控制尺寸流动范围过大或过小影响阅读。

缺点:

  1. 如果屏幕尺度跨度太大,相对设计稿过大或者过小的屏幕不能正常显示,宽度使用百分比定义,高度和文字大小用px固定,在大屏手机下显示效果会变成有些元素被拉长,高度,文字大小还是一样。
  2. 设置盒模型的不同属性,其百分比设置的参考元素不唯一,容易使布局问题变得复杂

基于媒体查询的响应式设计 样例

响应式设计是基于流式布局+弹性布局+媒体查询技术使用,使得一个网站同时适配多种设备和多个屏幕,让网站的布局和功能随用户的使用环境(屏幕大小、输出方式、设备/浏览器能力而变化),使其视觉合理,交互方式符合习惯。如使得内容区块可伸缩与自由排布,边距适应页面尺寸,图片适应比例变化,能够自动隐藏/部分显示内容,能自动折叠导航和菜单,放弃使用像素作为尺寸单位,使用dp。

主要实现是通过媒体查询,通过给不同分辨率的设备编写不同的样式实现响应式布局,用于解决不同设备不同分辨率之间兼容问题,一般是指PC、平板、手机设备之间较大的分辨率差异。比如给小屏幕手机设置@2x图,为大屏手机设置@3x图

@media only screen and (min-width: 401px){样式1
}
@media only screen and (min-width: 428px){样式2
}

其中,会应用到flex布局实现宽度自适应。

浏览器页面前端自适应方案中的图片处理

加载网页时,平均60%以上的流量都来自加载图片。指定图像宽度时使用相对单位,防止意外溢出视口。如, width: 50%; 将图片宽度设置为包含元素宽度的 50%。因为css允许内容溢出容器, 需要使用max-width: 100%来保证图像及其他内容不会溢出。

<style>img, embed, object, video{max-width: 100%}
</style>

使用 img 元素的 alt 属性提供描述,描述有助于提高您的网站的可访问性,能提供语境给屏幕阅读器及其他辅助性技术。https://developers.google.com/web/fundamentals/design-and-ux/responsive/images?hl=zh-cn

  • 对于img引入的图片,使用属性——srcsesizes 来提供更多额外的图像资源,帮助浏览器选择合适的图片
    针对不同大小屏幕,使用不同分辨率版本的图片,高DPI设备上使用srcset来增强img。
    srcset 定义了允许浏览器选择的图像集(文件名),以及每个图像的大小(使用w单位)。
    sizes定义了一组媒体条件(例如屏幕宽度),指明当某些媒体条件为真时,什么样的图片尺寸是最佳选择。
<img srcset = "elva-fairy-320w.jpg 320w,elva-fairy-480w.jpg 480w,elva-fairy-800w.jpg 800w"sizes = "(max-width: 320px) 280px,(max-width: 480px) 440px,800px"src = "elva-fairy-800w.jpg" alt="Elva dressed as a fairy">

浏览器的查询过程:1.查看设备宽度; 2.检查sizes列表中哪个媒体条件是第一个为真;3.查看给予该媒体查询的槽大小;4.加载srcset列表中引用的最接近所选的槽大小的图像

如果想要针对不同像素密度的屏幕,使用<img>的srcset属性用来指定多张图像,适应不同像素密度的屏幕。它的值是一个逗号分隔的字符串,每个部分都是一张图像的 URL,后面接一个空格,然后是像素密度的描述符。

<img srcset="foo-320w.jpg,foo-480w.jpg 1.5x,foo-640w.jpg 2x"src="foo-640w.jpg">

srcset属性给出了三个图像 URL,适应三种不同的像素密度。图像 URL 后面的像素密度描述符,格式是像素密度倍数 + 字母x。1x表示单倍像素密度,可以省略。浏览器根据当前设备的像素密度,选择需要加载的图像。如果srcset属性都不满足条件,那么就加载src属性指定的默认图像。

  • 对于<img>引入标签的图片高清解决方案,使用js自带的异步加载图片
<img id="img" data-src1x="xxx@1x.jpg" data-src2x="xxx@2x.jpg" data-src3x="xxx@3x.jpg"/>
var dpr = window.devicePixelRatio;
if(dpr > 3){dpr = 3;
};var imgSrc = $('#img').data('src'+dpr+'x');
var img = new Image();
img.src = imgSrc;
img.onload = function(imgObj){$('#img').remove().prepend(imgObj);//替换img对象
};

如果是img标签引入的图片,可以使用延迟加载的方式来加载,在实际加载图片之前先用js检查窗口宽度,然后加载不同分辨率的图片,比如宽度<=480,就加载80px宽度的图片,480 < 宽度 <= 768,加载120px的图片, 宽度> 768则加载160px的图片,如果宽度是600px怎么办呢,通过百分比来缩放120px的图片达到合适的结果。这样做的好处是对于移动设备来说,下载的图片会小一些,减少网页加载的时间。但是问题是竖屏向横屏切换或者扩大浏览器窗口宽度时图片会由于放大而产生一定的模糊感。

  • 为不同的视口提供不同的图片,使用<picture>标签。<picture>是html5中定义的一个容器标签,内部使用<source>和<image>,浏览器会匹配<source>type,media,srcset等属性,找到最适合当前布局/视口宽度/设备像素密度的图像进行加载.这里的<img>标签是浏览器不支持picture元素,或者支持picture但没有合适的媒体定义时的后备,不能省略。
<picture><source media="(min-width: 30px)" srcset="cat-vertical.jpg"><source media="(min-width: 60px)" srcset="cat-horizontal.jpg"><img src="cat.jpg" alt="cat">
</picture>
  • 对于背景图片,使用image-set根据用户设备的分辨率匹配合适的图像 同时要考虑兼容性问题
<style>
.css {background-image: url(1x.png); /*不支持image-set的情况下显示*/background: -webkit-image-set(url(1x.png) 1x,/* 支持image-set的浏览器的[普通屏幕]下 */url(2x.png) 2x,/* 支持image-set的浏览器的[2倍Retina屏幕] */url(3x.png) 3x/* 支持image-set的浏览器的[3倍Retina屏幕] */);
}
</style>
  • 对于背景图片,使用media query自动切换不同分辨率的版本
<style>
/* 普通显示屏(设备像素比例小于等于1)使用1倍的图 */
.css{background-image: url(img_1x.png);
}/* 高清显示屏(设备像素比例大于等于2)使用2倍图  */
@media only screen and (-webkit-min-device-pixel-ratio:2){.css{background-image: url(img_2x.png);}
}/* 高清显示屏(设备像素比例大于等于3)使用3倍图  */
@media only screen and (-webkit-min-device-pixel-ratio:3){.css{background-image: url(img_3x.png);}
}
</style>
  • 维护自适应页面中图片宽高比固定比较常用的方法是使用padding设置

对字体的设置

百分比方案的字体设置如果按照百分比来定义,当屏幕宽度过大时,需要另外设置自适应方案,如根据em设置字体大小
rem方案和vw/vh方案的字体,在屏幕大小发生改变时,可以依据调整后的根元素字体大小和vw/vh值进行适配
响应式设计可以根据媒体查询给不同的分辨率指定不同的字体样式。

https://segmentfault.com/a/1190000006824046

calc()函数

calc()函数在声明css属性值时执行一些计算,可以用在如下场合 length/frequency/angle/time/number/integer,语法 : property: calc(expression),用一个表达式作为参数,用这个表达式的结果作为值。例 :

  • 使用指定的外边距定位一个对象,使用calc()可以为一个对象设置一个左右两边相等的外边距
<style>div{left: calc(40px);width: calc(100% - 80px);}
</style>
  • 确保表单域的大小适合当前的可用空间,不会在保持合适外边距的同时,因挤压超出容器的边缘
<style>父元素 {width: calc(100%/6);}子元素 {width: calc(100% - 1em)}
</style>

https://segmentfault.com/a/1190000006824046
这个是对字体的处理,后面要分开总结一下.


对图片的处理

移动端高清/多屏适配方案

各个网站采用的方案,然后看下知乎上那个关于px和rem方案的对比,这个很重要

https://juejin.im/post/5bc07ebf6fb9a05d026119a9

浏览器页面前端自适应方案相关推荐

  1. 解决浏览器页面缩放前端页面大小自适应改变的问题

    平时写前端页面的时候,css大小都在用px,现在可以采用rem的方法解决这个问题 首先需要明白px与rem的区别: px是固定的像素,一旦设置了就无法适应页面的大小而进行改变. em和rem是相对长度 ...

  2. 前端页面生成pdf方案

    前端页面生成pdf方案 使用jsPDF的html方法生成 直接将html节点传入jsPDF生成pdf,效果一般 const pdf = new jsPDF('p', 'pt', 'a4'); cons ...

  3. 【前端页面缓存技术方案】

    前端页面缓存技术方案 关于页面缓存数据的纯前端技术方案 背景 项目存在的现有方案 思考

  4. 前端一HTML:三: 浏览器页面的本质-html,html语言规则

    浏览器页面上只有一句,但实际的html文件不止一句代码. 浏览器所做的事情就是将服务器响应回来的response进行从上到下的解析(渲染) ,将最后的结果显示出来. html:在浏览器上运行的一种脚本 ...

  5. 浏览器页面渲染机制-前端原理剖析

    浏览器页面渲染机制 前言 浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分,一是渲染引擎,另一个是JS引擎.渲染引擎在不同的浏览器中也不是都相同的.目前市面上常见的浏览器内核可以分为这四种: ...

  6. 手机端页面的自适应设计的开发思路

    一直在找有关手机端页面自适应写得比较好的文章,今天终于找到一篇,个人觉得写得很详细.如果想要拿到需求就知道要适用什么方法,除了要熟练规则.多参考一些优秀网站,还要动手实践几次. 以下为转发的正文: 互 ...

  7. 移动端页面适配———多方案解析

    移动互联网快速发展的今天,手机的种类和尺寸越来越多,作为前端的小伙伴们可能会越来越头疼,但又不得不去适配一款又一款的新机型.对于移动端适配,不同的公司.不同的团队有不同的解决方案.我在项目中也用了一部 ...

  8. electron 打开调试_构建基于 iOS 模拟器的前端调试方案

    作者:imyzf 本文将为大家介绍自动化控制 iOS 模拟器的原理,为开发基于 iOS 模拟器的前端调试方案提供帮助. 我们在开发 iOS App 内的前端页面时,有一个很大的痛点,页面无法使用 Sa ...

  9. 移动端页面性能优化方案

    移动端页面性能优化方案 加载优化 使用首屏加载 按需加载 预加载 压缩图片 减少Cookie 异步加载第三方资源 脚本执行优化 CSS优化 JavaScript执行优化 渲染优化 SEO(搜索引擎优化 ...

  10. csrutil是什么_CSR、SSR、NSR、ESR傻傻分不清楚,一文帮你理清前端渲染方案!

    01 引言 随着前端系统的越发复杂,前端的性能也受到越来越多的重视.Google也不断在推进新的性能相关指标,从原先的Performance API中的指标逐步演进成用户性能体验相关的指标. 对于用户 ...

最新文章

  1. java.lang.NullPointerException: Attempt to invoke virtual method ‘boolean java.lang.String.equals(j
  2. AI从业者需要应用的10种深度学习方法
  3. [NOIP2009] 最优贸易 (最短路,分层图)
  4. js保存当前html,JavaScript保存当前页面
  5. 新建MVC项目与发布
  6. Keras-6 IMDB, a binary classification example
  7. python--字符串为空
  8. Mongoose使用——nodejs结合mongodb
  9. 使用Python搭建人脸识别考勤系统
  10. Quill富文本编辑器-图片上传-可编辑图片大小、排版
  11. 数据可视化Error:matplotlib is required for plotting when the default backend “matplotlib“ is selected
  12. 计算机二级买那几本书,计算机二级公共基础知识买哪本书复习好?重点在哪..._公共英语考试_帮考网...
  13. HiveSql面试题11详解(count(1)、count(*)和count(列名)的区别)
  14. php webcam,如何使用Dynamic Web TWAIN附加组件构建PHP Webcam App
  15. 入门避雷需知:如何选择关于Python机器学习的书
  16. 【分治思想】12627 Erratic Expansion
  17. 支持向量机(SVM)之核函数
  18. Linux QT 4G发送HTTP POST请求发送JSON格式的数据
  19. 九针串口公母对应接口
  20. 实现h5端播放rtsp流视频--通过ffmpeg转流实现

热门文章

  1. 电脑桌面计算机点开一直在刷新,Win10系统桌面一直在刷新怎么办
  2. 深入理解Zend执行引擎
  3. 支付业务与技术架构学习总结(7)——从金融牌照(三方支付牌照),看互联网巨头的金融布局
  4. 算法系列:Reservoir Sampling
  5. 微信小程序图片懒加载插件
  6. 利用python-docx和docxcompose实现word合并,自动化办公
  7. memory leak check tools 详解
  8. 《经济学通识》:人类会受到“东西不够、生命有限、相互依赖、需要协调”四方面的限制,影响我们的衣食住行
  9. 服务器上设置密码策略不能修改,Window Server 2008 R2 在Active Directory域中不能更改服务器密码策略...
  10. python爬取招聘网信息并保存为csv文件