根据UI图对移动端的h5页面作样式重构,是前端工程师的本职工做,看似简单,不过想作好却并不容易。下面总结一下其中要点。css
rem是一种相对长度单位,参考的基准是<html>
标签订义的font-size
。好比:html
html { font-size: 16px; } .intro { font-size: 1.2rem; margin-top: 0.2rem; }
那么实际效果就是:前端
.intro { font-size: 16px * 1.2rem = 19.2px; margin-top: 16px * 0.2rem = 3.2px; }
作移动端的h5,一般会在HTML文件中指定一个<meta>
标签:sass
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximun-scale=1.0, user-scalable=no">
关于Viewport,能够参考更专业的教程:前端工程师
http://www.cnblogs.com/chengkun101/p/5461500.html函数
http://www.cnblogs.com/2050/p/3877280.html工具
手机屏幕的分辨率愈来愈高,好比iPhone 5为640*1136 px
、iPhone 6/6S为750*1334 px
。我拿到的UI图,其参考分辨率为1440*2560 px
。字体
而在写CSS时,一般是以屏幕宽度为参考的。打开Chrome的响应式设计工具,就能够看到各类设备的屏幕宽度,好比iPhone 5的屏幕宽度是320*568 px
,iPhone 6/6S的屏幕宽度为375*667 px
。分辨率和屏幕宽度之间,是有一个倍屏系数换算的。scala
设计师给了一张宽为1440px的UI图,而作不一样设备的适配,就是前端工程师的职责了。设计
好比UI图上标注了某个段落的字体大小为64px。为了保证在各类屏幕上的不失真,就要根据实际屏幕宽度作等比例换算,才能写进CSS,即知足:
写入CSS的尺寸/屏幕宽度 = UI图标注的尺寸/UI图宽度 所以: 写入CSS的尺寸 = UI图标注的尺寸/UI图宽度*屏幕宽度
好比上例,当标注尺寸为64px、UI图宽度为1440px时,针对不一样屏幕宽度,写入CSS的属性分别为:
font-size: 64/1440*320 = 14.22px
font-size: 64/1440*360 = 16px
font-size: 64/1440*375 = 16.67px
font-size: 64/1440*1440 = 64px
因而天然想到媒体查询:
@media (min-width: 320px) { p.intro { font-size: 14.22px; } } @media (min-width: 360px) { p.intro { font-size: 16px; } } @media (min-width: 375px) { p.intro { font-size: 16.67px; } } @media (min-width: 1440px) { p.intro { font-size: 64px; } }
天啊,若是这样写,若是UI图上标注了另外一个段落的字体大小为60px
,岂不又要写一遍媒体查询!
解决方法是,在<html>
标签上只作一次媒体查询,而在p.intro
上使用rem单位。
// 对html作媒体查询,定义基准的font-size @media (min-width: 320px) { html { font-size: 14.22px; } } @media (min-width: 360px) { html { font-size: 16px; } } @media (min-width: 375px) { html { font-size: 16.67px; } } @media (min-width: 1440px) { html { font-size: 64px; } } // CSS单位使用rem p.intro { font-size: 1rem; }
这样一来,其余元素也能够共享<html>
的基准font-size
,无需媒体查询,只需引入rem单位,如:
// 另外一个段落 p.another-intro { font-size: 0.9375rem; // UI图上标注60px height: 1.5625rem; // UI图上标注100px margin: 0.5rem; // UI图上标注32px }
有点匪夷所思?先来看看如上换算是否知足等比例性。再回顾一下公式:
写入CSS的尺寸/屏幕宽度 = UI图标注的尺寸/UI图宽度
以p.another-intro
的margin
属性为例:
margin: 14.22*0.5 = 7.11px
,而7.11/320 = 32/1440
margin: 16*0.5 = 8px
,而8/360 = 32/1440
margin: 16.67*0.5 = 8.335px
,而8.335/375 = 32/1440
margin: 64*0.5 = 32px
,而32/1440 = 32/1440
完美。
能够发现一个规律:在媒体查询中,min-width: 1440px
时定义了html { font-size: 64px; }
,那么UI图上标注的尺寸,直接除以64,就能够带个rem尾巴,写入到CSS中。记住64这个参考值,很是有用,下文会常常用到。
固然,你也能够不使用64做为参考值,只要符合等比例规则就能够。下文均是以64为例的。
以上只以320px、360px、375px为例,获得了<html>
的基准font-size
。对于iPhone 6s Plus,其屏幕宽度为414px,如何计算font-size
?
很简单:屏幕宽度/UI图宽度*64
。
因而,又多了一条媒体查询规则:
@media (min-width: 414px) { html { font-size: 18.4px; // 414/1440*64 } }
查阅常见移动设备的屏幕尺寸规格,能够获得一个较为完整的媒体查询规则:
html { font-size: 12px; } @media (min-width:320px){ html{ font-size: 14.2222px; } } @media (min-width:360px){ html{ font-size: 16px; } } @media (min-width:375px){ html{ font-size: 16.6667px; } } @media (min-width:412px){ html{ font-size: 18.2857px; } } @media (min-width:480px){ html{ font-size: 21.3333px; } } @media (min-width:640px){ html{ font-size: 28.4444px; } } @media (min-width:720px){ html{ font-size: 32px; } } @media (min-width:768px){ html{ font-size: 34.1333px; } } @media (min-width:1440px){ html{ font-size: 64px; } }
以前所讲的内容,已经可使你作出移动端适配的h5页面了,但并不优雅。由于CSS是不支持计算的,“标注尺寸/64”只能手工计算,也就意味着UI图上的每一个标注都要手动换算,你会疯掉。
不过,借助CSS预编译工具,如Less/Sass,能够避免这种重复劳动。如下以Scss为例,好比:
p.intro { font-size: 64px/64px * 1rem; } p.another-intro { font-size: 60px/64px * 1rem; // UI图上标注60px height: 100px/64px * 1rem; // UI图上标注100px margin: 32px/64px * 1rem; // UI图上标注32px }
固然也可使用变量:
// 计算rem的基准字体 $rem-base-font-size: 64px; p.intro { font-size: 64px/$rem-base-font-size * 1rem; } p.another-intro { font-size: 60px/$rem-base-font-size * 1rem; // UI图上标注60px height: 100px/$rem-base-font-size * 1rem; // UI图上标注100px margin: 32px/$rem-base-font-size * 1rem; // UI图上标注32px }
这样作的好处是,若是某一天不使用64px做为参考值,只需修改$rem-base-font-size
变量。
以上代码看着很冗余,不如写一个函数,隐藏计算过程:
// 将设计图标注的px尺寸,转换为相应的CSS @function convertPxFormUI($px) { $rem-base-font-size: 64px; @return $px / $rem-base-font-size * 1rem; } p.intro { font-size: convertPxFormUI(64px); } p.another-intro { font-size: convertPxFormUI(60px); // UI图上标注60px height: convertPxFormUI(100px); // UI图上标注100px margin: convertPxFormUI(32px); // UI图上标注32px }
这样作的好处是,若是某一天摒弃了rem,使用了其余换算规则,只需修改convertPxFormUI()
函数体便可。
既然Sass帮助咱们计算,那么媒体查询中的一堆font-size
,Sass是否能够代劳呢?
以前介绍了计算规则:屏幕宽度/UI图宽度*64
。OK,看来能够这样写:
// 计算rem的基准字体 $rem-base-font-size: 64px; // UI设计图的分辨率宽度 $UI-resolution-width: 1440px; @mixin html-font-size() { @media (min-width:320px){ html{ font-size: 320px / $UI-resolution-width * $rem-base-font-size; } } @media (min-width:360px){ html{ font-size: 360px / $UI-resolution-width * $rem-base-font-size; } } @media (min-width:375px){ html{ font-size: 375px / $UI-resolution-width * $rem-base-font-size; } } @media (min-width:412px){ html{ font-size: 412px / $UI-resolution-width * $rem-base-font-size; } } @media (min-width:480px){ html{ font-size: 480px / $UI-resolution-width * $rem-base-font-size; } } @media (min-width:640px){ html{ font-size: 640px / $UI-resolution-width * $rem-base-font-size; } } @media (min-width:720px){ html{ font-size: 720px / $UI-resolution-width * $rem-base-font-size; } } @media (min-width:768px){ html{ font-size: 768px / $UI-resolution-width * $rem-base-font-size; } } @media (min-width:1440px){ html{ font-size: 1440px / $UI-resolution-width * $rem-base-font-size; } } }
很冗余,用循环来实现:
// 计算rem的基准字体 $rem-base-font-size: 64px; // UI设计图的分辨率宽度 $UI-resolution-width: 1440px; // 须要适配的屏幕宽度 $device-widths: 320px, 360px, 375px, 412px, 480px, 640px, 720px, 768px, 1440px; @mixin html-font-size() { @each $current-width in $device-widths { @media (min-width: $current-width) { html { $x: $UI-resolution-width / $current-width; // 计算出是几倍屏 font-size: $rem-base-font-size / $x; } } } }
这样作的好处是,若是某一天老板说,屏幕宽度450px时效果不理想。你只需在$device-widths
中新增一个宽度便可。
_variables.scss
:定义变量// 计算rem的基准字体 $rem-base-font-size: 64px; // UI设计图的分辨率宽度 $UI-resolution-width: 1440px; // 须要适配的屏幕宽度 $device-widths: 240px, 320px, 360px, 375px, 412px, 480px, 540px, 640px, 720px, 768px, 1024px, 1440px;
_utils.scss
:定义函数与mixin// 根据不一样设备的屏幕宽度,定义<html>的基准font-size @mixin html-font-size() { @each $current-width in $device-widths { @media (min-width: $current-width) { html { $x: $UI-resolution-width / $current-width; // 计算出是几倍屏 font-size: $rem-base-font-size / $x; } } } } // 将设计图标注的px尺寸,转换为相应的CSS @function convertPxFormUI($px) { @return $px / $rem-base-font-size * 1rem; }
index.scss
:Scss入口文件@import 'utils', 'variables'; @include html-font-size(); p.intro { font-size: convertPxFormUI(64px); } p.another-intro { font-size: convertPxFormUI(60px); height: convertPxFormUI(100px); margin: convertPxFormUI(32px); }
rem + viewport + 媒体查询 + Sass