rem(font size of the root element)是指相对于根元素的字体大小的单位。我们根元素就是<html>
,例如我们在 html 设置了字体大小属性
html {
font-size: 20px;
}
那么 1rem = 20px。
假设我们美术设计搞的屏幕宽度为750,html根字体大小为40px
750 = 40px = 1rem
那么当前获取到可展示宽度为760,则html设置字体大小为:
750/40 = 760/n
n = 760*40/750
n = 40.5333px
所以我们加载网页时,js动态设置根字体大小的代码如下:
// 设置根节点<html>的字体大小
function windowResize() {
var innerWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth;
if( !innerWidth ){ return false;}
document.documentElement.style.fontSize = ( innerWidth*40/750 ) + 'px';
}
// 初始调用窗口监听
function setWindowFontSize() {
windowResize();
window.onresize = function() {
windowResize();
}
}
现在我们在写css时,为了能基于rem动态去设配移动端,我们会采用rem作为单位。例如
.demo_class {
height: 10rem;
}
如果我们不想每次都需要自己去用计算器换算一次然后写到css里,这里我们采用 sass
语法,定义一个 px2rem
的接口,在写css时,还是基于px来写,但是都加入 px2rem 接口就可以自动换算出对应的rem值。
@function px2rem($px){
@return $px*750/$designWidth/40 + rem;
}
$designWidth : 750;
designWidth
为我们的美术设计稿的宽度,我们在编写html时就可以直接根据设计稿来制作
我们使用 sass 语法进行编写样式,在输出css时,可使用一个辅助开源工具协助我们进行转换为css koala
我们在开发移动设备的网站时,最常见的的一个动作就是把下面这个东西复制到我们的head标签中:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
属性 | 描述 |
---|---|
width | 设置layout viewport 的宽度,为一个正整数,或字符串"width-device" |
initial-scale | 设置页面的初始缩放值,为一个数字,可以带小数 |
minimum-scale | 允许用户的最小缩放值,为一个数字,可以带小数 |
maximum-scale | 允许用户的最大缩放值,为一个数字,可以带小数 |
height | 设置layout viewport 的高度,这个属性对我们并不重要,很少使用 |
user-scalable | 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许 |
Window.devicePixelRatio = 物理像素[设备像素] / 逻辑像素[CSS像素]
此属性返回当前显示设备的 物理像素
与 CSS像素
的比值。该值也可以被解释为像素大小的比例:即一个 CSS像素的大小 相对于一个物理像素的大小的比值。
可以用javascript中的window.devicePixelRatio来获取
为什么1px变粗了?
在网上有一篇文章讲解了 移动端1像素边框问题 ,文章也提供了解决的方案
为什么移动端CSS里面写了1px,实际上看起来比1px粗;其实这两个px的含义其实是不一样的,UI设计师要求的1px是指设备的物理像素1px,而CSS里记录的像素是逻辑像素,它们之间存在一个比例关系,也就是 window.devicePixelRatio ,比例多少与设备有关。
在手机上border无法达到我们想要的效果。这是因为 devicePixelRatio 特性导致,iPhone的 devicePixelRatio==2,而 border-width: 1px
描述的是 css像素,所以,border被放大到物理像素2px显示,在iPhone上就显得较粗。
综合以上的 rem 设计以及 1像素 的解决问题,github 已经有人提供了一套解决方案,比较实用,可在符合场景下使用