公司许多的业务都还停留在使用px
和弹性布局来进行样式处理的阶段,有些时候是由于视觉要求,有些时候是惧怕线上问题,所谓破然后立。css
移动端适配方案是一个老生常谈的话题,可是对于不一样的项目、不一样的业务场景可能会须要不一样的适配方案来进行移动端适配,向下兼容的baseline也须要提早订好。html
其实移动端适配就和下面的玩具同样,对应的形状塞到对应的容器里面就行了。可是有点小小的问题,就是这些积木的大小可能和容器不太同样,对于前端来讲,这些积木不是用木头作的,而应该是用橡皮泥作的。前端
业务环境是决定总体项目的适配方案的核心因素。一套代码到底须要兼容多少环境是在项目开始架构的时候就须要肯定的。git
世界最大程序员交友网站,github web端主站能够明显的看到,全部的内容都被限制到了一个980像素的内容区域里面。程序员
而其移动端也也很明显的是一个单独的布局方式,总体宽度再也不限制,即便到了iPad Pro这种宽度到达1024像素的设备上,仍然会占满整个屏幕。github
而淘宝的主站和github相似,分为移动端页面和PC端页面,PC端页面一样有着左右的留白,这也是为了让用户可以在宽屏的时候将注意力集中在中间区域。web
当前大部分站点都采用UA来判断用户的设备,而后定向到PC或者H5页面。浏览器
二者的惟一不一样点在于:淘宝会更加严格地将页面直接重定向到另一个连接,而github则是加载了一个不一样的CSS文件进行渲染。固然,这两种方案其实没有本质的差异,而单独的H5页面能够在客户端站内进行更好地复用。sass
因此,若是有足够的开发人员,开发适用于两种设备类型的页面是比较友好的方案。若是你的移动客户端是基于webview开发的话,那么H5页面还能够直接嵌入到webview中做为展现。架构
对于总体宽度,正常移动设备的宽高比都比较协调,而像iPad这种设备,其宽度过大,致使了正常的H5页面在上面显示会有比较奇怪的效果。好比淘宝的主站在iPad上的显示效果,能够看到上下两块的navigator被拉长了不少,致使了效果很差。可是若是考虑到成本问题,iPad用户更多地会使用APP来进行访问,因此H5页面的样式重要性就被缩减了。而github移动版对于宽屏设备的适配就会作得更好。
有兴趣的话,能够去看看淘宝的H5页面,这个页面有一个颇有趣的地方,这个地方后文会讲到,这里先提一下:
除了宽度仍旧占满屏幕宽度的方案,设置屏幕的最大宽度能够保证在宽屏设备上的显示效果,可是留白的部分就须要考虑处理方案。
因为有了固定最大宽度,仅仅须要对于超过宽度的具备留白的设备进行特殊处理(能够是背景、功能按钮等),中间具备最大宽度的部分就能够进行代码复用。
考拉团队的这篇blog写的已经很是清楚了,感谢考拉的小伙伴给咱们提供了便宜的海淘还有这么好的文档产出lol:
桌面浏览器中,正常的视口宽度就是整个浏览器的窗口宽度,会随着浏览器窗口的伸缩而缩放。默认状况下HTML标签会占满整个视口,若是没有设置HTML的静态width的话。
若是采用以前所述的,PC端页面设置最大宽度的话,那么当视口在最大宽度以外的时候缩放的话,不会影响可见区域的显示效果,可是若是缩小到比最大宽度小的时候,原页面的布局方案就很重要了。弹性布局和百分比的布局方式可以在页面缩小的时候,保证页面的布局不会崩溃。
在手机上,视口与移动端浏览器的宽度再也不关联,而是彻底独立的了。咱们称其为布局视口。
整个页面可能会变得很大,而后只有一部分显示在设备的可见区域内,整个页面的大小叫作Layout Viewport。这个大小能够经过document.documentElement.clientHeight/clientWidth
来获取。
PPK这篇很早的文章对于视口进行了很是清晰的描述。
上图可见,Layout Viewport的宽高实际上是可变的,当经过手势缩放页面的时候,Layout Viewport就会发生变化,当页面缩放到和设备的可见区域大小一致的时候,Layout Viewport就恰好等于Visual Viewport了。
Visual Viewport其实很好理解,就是整个屏幕的可见区域大小。因为设备的物理像素,也就是CSS中的pt
单位是固定的,页面在移动端被缩放了以后,页面中的CSS像素分布在设备上也发生了变化。
Ideal Viewport实际上是上面二者的结合,当咱们将Layout Viewport的宽度设置成屏幕的宽度,就保证了页面中CSS像素点的恒定。
这里就用到了移动端适配经常使用的<meta name="viewport" content="width=device-width">
这个标签能够保证在移动端设备中,页面的宽度与屏幕宽度相同。
在手机上进行放大的时候,页面中的CSS像素不变,可是可见视口的像素比例发生了变化,可是禁用缩放会致使某些用户的体验较差。保持缩放比例在必定范围以内比较合适。
基于如上所述的内容,结合目前的业务内容--主要针对移动端设备进行适配,采用设置最大宽度,而且在meta
标签中设置理想视口,能够保证在移动设备以及PC上面的总体布局效果。
目前对于移动端适配的内容布局效果是这样的:
以上几个方法各自都有各自的好处,咱们能够看一下实际应用时候的效果:
使用百分比做为内容大小的标准,在大部分条件下是可行的,百分比能够很好地让元素乖乖呆在本身的位置,不管屏幕的宽度大小。
可是文字就存在很是大的问题了,因为文字是固定大小,在屏幕dpr变化的时候,文字的CSS像素不变,就致使了文字在页面中的占位发生了变化。这样的结果就是,文字过多或者屏幕dpr太小的时候,会发生溢出;可是若是按照小屏幕为基准,又会发生字体过小这种状况。
百分比在当前移动端适配排版的时候,更多地会做为section
级别元素的兼容排版。这个也要和设计稿中的效果相关,若是设计稿中要求一个元素定宽,那么就直接用px
来保证宽度就能够了。
rem
这个单位和以前经常使用的em
有点相似,惟一的区别在于rem
及基于根元素的font-size
来进行计算的一个相对值。em
存在不少缺点,好比层层嵌套以后,可能就会忘记了上一层的font-size
究竟是多大。或者好比像如今的模块化开发,一个路由套在另外一个路由里面,甚至找父元素都须要到其余文件中去找。
为了解决em
存在的问题,标准中还有rem
这个单位来帮助排版。全部的元素大小都用rem
来做为单位,而后在页面的根元素中,咱们为根元素的font-size
进行肯定化地赋值,这样全部的rem
单位都是同一个明确的基准了。当屏幕进行适配的时候,只须要调整这个基准值,就能够保证每一个元素的大小自动按照比例调整。
阿里的lib-flexible解决方案实际上就是利用了这个方式,经过给<html>
标签绑定font-size
以及data-dpr
属性来进行整个页面的适配。
方案将整个页面宽度分红100份,分红100份的缘由能够看下面的另外一个方案。每10个单位宽度做为1rem
,也就是整个视觉稿的宽度会被分红10rem
的100份,假如拿到的视觉稿是750px
的,那么1rem
就表明75px
。这样获得的比例系数就是75/750
,也就是每次在进行设计稿到CSS的转换的时候,只须要对设计稿的像素值/10就能够获得对应的rem
值。
经过一个预先加载的JavaScript脚本,计算根节点的字体大小,document.documentElement.style.fontSize = window.innerWidth / 10 + 'px';
,而后咱们在写页面代码的时候只须要将原始的像素值/基准值就能够获得对应的rem
单位了。固然每次都要按计算器确定是不行的。若是想方便使用的话,能够用less或者sass这种预处理器来处理页面。
@function px2rem($px)
// 这里将设计稿的px转换为rem,
@return ($px / $unit-px) * 1rem
// 根据设备的dpr进行字体适配
@mixin font-dpr($font-size)
font-size: $font-size
[data-dpr="2"] &
font-size: $font-size / 2
复制代码
除了元素宽高能够获得比较好的还原,对于文字大小的适配也比较重要,因为每一个设备的dpr不一样(这里尤为是iOS设备),直接致使了不少文字在iPhone6+上显示正常,而在iPhone5上面却文字过大,致使文字溢出,上面的less mixin
就是进行字体样式适配的。
这种方法结合了sass
的函数功能和rem
的适配,再加上必要的百分比以及media query能够获得比较好的移动表现。
这是使用这种方法在iphone6上的显示效果,具体的总体显示效果能够戳这里,rem基准样式示例
若是对于文字在各类平台上的显示效果不满意,能够经过上面说的sass
的mixin
来让文字根据dpr
进行断点渲染。
而这样存在的问题就是仅仅适用于移动端,而且不可以进行横屏适配,由于横屏以后,页面的宽度发生了变化,可是基准值却还保持着本来绑定到根节点上面的基准值。
首先看看vw
的浏览器支持状况吧,can i use vw支持状况,使用这个单位意味着你放弃了IE11如下的PC用户,在如今一个主要兼容移动端的世界里,并无太大的反作用(这里吐槽一句,其实PC端的兼容远远要比移动端来的方便。移动端奇奇怪怪的分辨率以及2x,3x的屏幕,还有苦逼的ipad、横屏让我每次作兼容的时候想一跃解千愁)。
vw
自身将整个可见视口横向分红了100份,每个单位就是1vw
,这个单位最大的优点就是在移动端的时候,不管是竖屏或者横屏,vw
永远都是针对于横向的,比rem
的方案好在当屏幕大小发生变化(顺便兼容了之后的可调节屏幕大小的移动设备[手动斜眼])的时候,不会让页面崩掉。
对于移动设备来讲,好比iphone6+的375px
CSS像素宽度,1vw
就等于3.75px
,经过这个单位能够解决上面的依赖于脚本绑定根元素font-size
的问题,在竖屏和横屏下面都有比较好的效果。
在经过vw
解耦了CSS和JS以后,那么vw
是否能够独立解决全部问题呢?
// 首先,我司的设计稿目前都是以750px为宽度,实际为iPhone6+的375px为基准
$w-base: 375px
$w-base-design: 750px
@function px2vw($px)
@return ($px / $w-base-design) * 100vw
复制代码
首先,上面的sass
代码能够根据你设计稿上面的px
单位转换为vw
单位值。固然最简单的办法仍是直接按照视觉稿上面像素进行输入,而后直接输出对应的vw
值啦。vscode和sublime固然会有已经作好的插件,可是我的并非很喜欢这种方式,这样你就没办法获得这个视觉稿本来的像素值了。在后期进行维护的时候会增长不少不少不少麻烦。这就是写起来爽,改起来火葬场吧。。。vw的效果能够看下面的codepen。
目前来讲,vw
是确定不适合单独使用的,毕竟页面中仍是有不少元素须要绝对的大小定位的。px
永远是必不可少的,视觉不可能让你全部的东西都自适应。
那么vw
可以解决什么问题呢?首先是大部分取代%
在CSS中的使用,百分比在CSS中存在不少歧义,对于宽度,上下边距,左右边距,内外边距的处理方式不尽相同。即便是老练的前端有时候也得思考一下当前的百分比究竟是根据什么肯定的。而vw
则是一个绝对的数值,仅仅根据一个不太可能变化的屏幕宽度来肯定。
而百分比主要解决的弹性问题,就是vw
着力解决的问题。
vw
不可以兼顾全部的状况,因此这个单位目前还并非最终的解决方案,仍是须要和其余单位合做来帮助页面可以更加优雅地显示出来。
CSS的兼容性不在于解释器上,而是在于设备的屏幕上面。大部分时间不只须要将页面展现在用户的面前,而是须要将页面稳定且优雅地展现给用户。
不管是百分比,rem
仍是vw
,都是进行局部容器元素定位的,做为最底层的叶子元素或者单元元素来讲,更多时间仍是会使用px
来尽可能还原视觉稿。
长远考虑这个问题,vw
在仅进行移动端访问的状况下效果拔群,由于不考虑兼容,只须要考虑适配问题。工程中到底使用哪一个方法进行,取决于大部分业务须要兼容的环境。