我们知道移动开发上面有个设备像素比: window.devicePixelRatio
,现在在开发页面的时候,一定会在 head
中添加个 viewport
的 meta
类似下面的代码:
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
但是随着手机屏幕越来越大,于是页面会遇见下面的问题:
介绍下REM
rem是以 document.documentElement
(即 <html>
标签)的 font-size
为基准的,举例说明:
- html的font-size:10px
- 那么1rem = 10px
手百Rem切图方案
为了切图方便,我们手百使用了Rem切图,首先类似淘宝的flexible方案,会在页面head中引入一个 flexible.js
。
为了计算方便,我们将 documentElement
的font-size设置为页面宽度的10%,代码如下:
var docEl = document.documentElement; var width = docEl.getBoundingClientRect().width; var rem = width / 10; docEl.style.fontSize = rem + 'px';
同时配合js获取dpr动态设置的viewport。切图布局的时候,需要计算rem,为了方便我们使用sass写了一个 rem
函数和mixin:
$rem-baseline: 75px !default; @function rem-convert($to, $values...) { $result: (); $separator: rem-separator($values); @each $value in $values { @if type-of($value) == "number" and unit($value) == ""{ $value: $value * 1px; } @if type-of($value) == "number" and unit($value) == "rem" and $to == "px" { $result: append($result, $value / 1rem * $rem-baseline, $separator); } @else if type-of($value) == "number" and unit($value) == "px" and $to == "rem" { $result: append($result, $value / ($rem-baseline / 1rem), $separator); } @else if type-of($value) == "list" { $result: append($result, rem-convert($to, $value...), $separator); } @else { $result: append($result, $value, $separator); } } @return $result; } @function rem($values...) { @if $rem-px-only { @return rem-convert(px, $values...); } @else { @return rem-convert(rem, $values...); } } @mixin rem($properties, $values...) { @if type-of($properties) == "map" { @each $property in map-keys($properties) { @include rem($property, map-get($properties, $property)); } } @else { @each $property in $properties { @if $rem-fallback or $rem-px-only { #{$property}: rem-convert(px, $values...); } @if not $rem-px-only { #{$property}: rem-convert(rem, $values...); } } } } // .demo{ height: rem(300px); @include rem(padding, 10px 20px); }
sass变量 $rem-baseline
是基准值,以设计图宽度/10为准,这样设计后,就可以直接用视觉稿的尺寸大小切图了。
举个例子
720px的视觉稿中有个360x360的div。
普通切图
使用普通方法切页面,设置:
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
这样采用iPhone5为基准手机切图,需要计算: 需要切图的图层width/(视觉稿width/基准手机设备宽度)
即: 360/(720/320)=160px
Rem切图
- 设置
$rem-baseline
为720/10,即72px - 使用rem进行计算:
width: rem(360px)
算一算
- html字体:1rem=640px/10=64px
- viewport:scale = 1/dpr = 0.5
- css的宽:360px/72px = 5rem
- 5rem 64px 0.5 = 160px
字体问题
字体的大小是根据 <body>
标签的 font-size
,为了计算方便, $font-baseline
设置为 12px
,所以需要根据不同的设备像素比设置不同的 font-size
,然后配合sass的mixin fontsize
设置字体大小
[data-dpr="1"] body{ font-size: $font-baseline; } [data-dpr="2"] body{ font-size: $font-baseline * 2; } [data-dpr="2.5"] body{ font-size: $font-baseline * 2.5; } [data-dpr="2.75"] body{ font-size: $font-baseline * 2.75; } [data-dpr="3"] body{ font-size: $font-baseline * 3; } .demo{ @include fontsize(24px); }
总结
关于设备上面的切图就说到这里,想了解更多,看下我之前的分析:移动适配切图方案