响应式布局的实现依赖于媒体查询(MediaQueries),选择主流设备宽度大小作为断点并编写额外的样式进行适配,但是这样会比较麻烦,只能呈现所选主流设备尺寸下的最佳适配。即使通过rem单元实现适配,也需要嵌入一个脚本来动态计算根元素的大小。近年来,随着移动端对viewportunits的支持越来越成熟和广泛,我们可以尝试一种新的方式来真正适配所有设备尺寸。了解视口单位(Viewportunits)首先,我们需要了解什么是视口。在业界,一个备受推崇的理论是Peter-PaulKoch(人称“PPK大神”)对viewport提出的解释——在桌面端,viewport指的是桌面端,指的是浏览器的viewport.可视区域;而在移动端就比较复杂了,涉及三个视口:LayoutViewport(布局视口)、VisualViewport(视觉视口)、IdealViewport。视口单元中的“视口”,在桌面端,无疑是指浏览器的可视区域;但在移动端,指的是三个Viewport中的LayoutViewport。视口单元中的“视口”根据CSS3规范,视口单元主要包括以下四种:vw:1vw等于视口宽度的1%vh:1vh等于视口高度的1%vmin:选择vw和vh的最小值vmax的vmax:选择vw和vh的视口单位与%单位不同。视口单位取决于视口的大小,根据视口大小的百分比定义;而%单位取决于元素的祖先元素。以视口为单位测量,视口的宽度为100vw,高度为100vh(左侧为竖屏,右侧为横屏)。比如桌面浏览器的视口大小是650px,那么1vw=650*1%=6.5px(这是理论上计算出来的,如果浏览器不支持0.5px,实际渲染结果可能是7px)。兼容性其兼容性如下图所示。可以知道在移动端iOS8及以上版本和Android4.4及以上版本均支持,在微信x5内核中也完全支持***。截图来自CanIUse截图来自X5内核——CanIUse使用视口单元适配页面。对于移动端开发来说,最重要的一点就是如何适配页面来实现多端兼容。不同的适配方法各有优缺点。也有缺点。对于主流的响应式布局和弹性布局来说,通过MediaQueries实现的布局需要配置多个响应断点,带来的体验也很不友好:布局在分辨率范围内响应断点保持不变,但是在响应断点切换的那一刻,布局带来了错误的切换变化,就像卡带播放器一次又一次地“咔哒”。而使用rem单元动态计算的弹性布局,需要在head中嵌入一个脚本,监听分辨率的变化来动态改变根元素的字体大小,这样CSS和JS就耦合在一起了。有什么办法可以解决这样的问题吗?答案是肯定的,通过使用视口单元实现适配页面,不仅可以解决响应式故障的问题,还可以解决脚本依赖的问题。方法一:只使用vw作为CSS单位在这种只使用vw单位作为唯一应用的CSS单位的实践中,我们遵循:1.将设计稿的尺寸转换为vw单位,我们使用Sass函数来compile//iPhone6的尺寸作为设计基准$vm_base:375;@functionvw($px){@return($px/375)*100vw;}2.是否是文字,布局高度,宽度,spacing等,vw作为CSS的单位flex:1;text-align:center;font-size:vm(10);//字体大小&_logo{display:block;margin:0auto;width:vm(40);//widthheight:vm(40);//heightimg{display:block;margin:0auto;max-width:100%;}}&_name{margin-top:vm(2);}}}}3.1物理像素线(即普通屏幕下1px,0.5pxunderhigh-definitionscreen)通过transform属性scale实现。.mod_grid{position:relative;&::after{//实现1个物理像素内容的下边框线:'';position:absolute;z-index:1;pointer-events:none;background-color:#ddd;高度:1px;左:0;右:0;上:0;@mediaonlyscreenand(-webkit-min-device-pixel-ratio:2){-webkit-transform:scaleY(0.5);-webkit-transform-origin:50%0%;}}...}4。对于需要保持纵横比的图片,应该使用padding-top代替。mod_banner{position:relative;padding-top:percentage(100/700);//使用padding-topheight:0;overflow:hidden;img{width:100%;height:auto;position:absolute;left:0;top:0;}}这样,我们就可以实现一个常见布局的页面效果如下:体验地址请点击这里。方法二:用vw和rem,布局更优化。虽然这样的页面看起来适配的很好,但是你会发现,因为它使用视口单元来实现布局,所以它会根据视口大小自动缩放,无论视口太大或太小,它也会随着视口太大或太小而失去最大最小宽度限制。当然,你不必在意这么小的不友好的用户体验,但让我们尝试修复这样的小缺陷。所以想到还是结合rem单元来实现布局比较好?rem灵活布局的核心是动态改变根元素的大小,那么我们可以:为随视口变化而变化的根元素的大小设置vw单位,这样就可以实现动态改变其尺寸。限制根元素的最大最小字号,配合body加上最大宽度和最小宽度,这样我们就可以实现布局宽度的最大最小限制。因此,根据以上条件,我们可以得出代码实现如下://rem单位转换:75px只是为了方便,750px-75px、640-64px、1080px-108px等等$vm_fontsize:75;//iPhone6size根元素大小的参考值@functionrem($px){@return($px/$vm_fontsize)*1rem;}//根元素大小使用vw单位$vm_design:750;html{font-size:($vm_fontsize/($vm_design/2))*100vw;//同时通过MediaQueries限制根元素***最小值@mediascreenand(max-width:320px){font-size:64px;}@mediascreenand(min-width:540px){font-size:108px;}}//body也增加了最小宽度限制,避免默认100%宽度的块元素跟随body出现过大或过小的body{max-width:540px;min-width:320px;}此处不再截图,可点此在线地址体验。总结相比方法一,我个人更喜欢方法二,原因有二:***,方法二对于用户的视觉体验相对更好,增加了***的最小宽度限制;其次,更重要的是,如果选择主流的rem灵活布局方式作为项目开发的适配页面方式,那么第二种方式更适合后期项目从rem单元到vw单元的过渡。仅仅通过改变根元素大小的计算方式,就可以无缝过渡到另一个CSS单元而无需任何其他处理,更何况使用vw单元肯定会成为更好的适配方式,目前只是没有被广泛使用因为兼容性支持。原文链接:https://aotu.io/notes/2017/04/28/2017-4-28-CSS-viewport-units/作者:Tingglelaoo联系原作者获取授权】点此阅读更多好文由作者
