CSS 动态REM

说明:动态REM是移动端专用的自适应方案,需要注意的是,它并不属于响应式布局,不支持在PC上使用该方案。

一、em和rem分别是什么


em和rem都是众多长度单位的中的一种,MDN给出的定义分别是

em是一个相对长度单位,这个单位表示元素的font-size的计算值。如果用在font-size属性本身,它会继承父元素的font-size。

1em == 自己的font-size的像素值

rem代表根元素的font-size大小(例如<html>元素的font-size)。当用在根元素的font-size上面时 ,它代表了它的初始值。

1rem == html的font-size的像素值

其他的长度单位还有px(像素)、vw(100vw == 视口宽度)、vh(100vh == 视口高度)等等。

注意:

  • chrome默认font-size大小为16px
  • chrome默认最小字号为12px(可在设置中更改),这意味着即使设置font-size<12px,打开控制台查看计算出来的font-size依旧是12px

二、移动端的特点


打开开发者工具切换到手机端,我们发现所有手机显示的界面都大同小异,不同的仅仅只是屏幕的大小(宽高)

机型 大小
iPhone 4 320 x 480
iPhone 5/SE 320 x 568
iPhone 6/7/8 375 x 667
iPhone 6/7/8 Plus 414 x 736
iPhone X 375 x 812

三、移动端适配方案


方案一:媒体查询

从上面可以看出,光是iPhone这一类手机就有如此多不同的宽高,更别说要适配所有手机了,显然这时候如果使用媒体查询来做适配不可取(那得写n多套样式)

方案二:百分比布局

思路:不用定宽/定高,而是将宽高都设置为百分比,这样不管屏幕大小如何变化,总是保持最初的比例不变

宽度自适应,高度无法确定

我们可以发现,元素宽度随屏幕宽度变化而变化。但问题是,元素高度没办法与屏幕宽度相关联,比如这里我们想让高度为宽度的一半就无法做到,这样就无法保持原始的比例,如果是图片的话会发生明显的形变。

解决方法:去掉高度,使用padding将元素撑起来

width: 40%; /* 屏幕宽度的40% */
height 0;
padding-bottom: 20%; /* 屏幕宽度的20% */

这样就用百分比布局做到了实现宽高都自适应的效果

用百分比做宽高自适应

代码:http://js.jirengu.com/peziq/3/edit?html,css,output

当然,为了引入我们的主题,这里还介绍另外一种方法动态REM

四、动态rem(JS动态地调整rem)


从上面对百分比布局的分析中,我们不难发现,只需要把元素的宽高与屏幕宽度关联起来,就可以实现根据屏幕宽度来进行缩放。

换个思路,我们不使用百分比布局,而是改为固定宽高,让元素宽高两者都有的长度单位和手机屏幕宽度进行关联。

但是无论是px、em还是rem都与手机屏幕的宽度无关(vw与屏幕宽度有关,但这个属性的兼容性太差,这里我们不使用它)

将rem与手机屏幕宽度进行关联

虽然除vw之外的长度单位都与屏幕宽度无关,但是1rem == html的font-size啊,这样我们只需要让font-size == 屏幕宽度(用JS做),即1rem == html的font-size == 屏幕宽度,这样就把长度单位rem与手机屏幕宽度关联起来了。

1 rem == html font-size == viewport width

我们用JS来实现font-size == 屏幕宽度

var pageWidth = window.innerWidth
document.write('<style>html{font-size:'+pageWidth+'px;}</style>')

效果如下:

动态rem

每次运行JS都会改变rem的值,即JS动态地调整rem,这就是动态rem

五、对rem进行微调


  1. 别忘了移动端得加一个meta viewport,加了之后才能正常显示出动态rem的效果
  1. 不一定非得让rem和屏幕宽度保持1:1

比如,上例中我们可以让1 rem == html font-size == viewport width/10
1 rem == 0.1 width

document.write('<style>html{font-size:'+pageWidth/10+'px;}</style>')

这样我们在写宽高的时候就不用总是写小数了,便于我们取整数

效果不变

不过需要注意的是,不要把比例设置得太小,否则会出bug。
比如你设置1 rem == 0.01width,因为在chrome中,默认最小字号为12px,当屏幕宽度为375px时,此时html的font-size为3.75<12,字体大小变化是不会生效的,浏览器依然按照最小的12px来计算。

  1. REM 可以与其他单位同时存在
    当计算出来的rem值特别小时就别用rem值了,比如上例中,如果此时
    我要为元素添加border,通过计算1px/640 == 0.0015 == 0.015 rem,
    这样计算出来的rem值太小时,border就会显示不精确。

    因此,当rem值太小时,可以不使用rem,rem可以与其他长度单位混用。

六、让px自动变为rem


每次都要计算rem值比较麻烦,我们可以通过SCSS将px直接翻译为正确的rem值。

使用步骤如下:

  1. npm config set registry https://registry.npm.taobao.org/
  2. touch ~/.bashrc
  3. echo 'export SASS_BINARY_SITE="https://npm.taobao.org/mirrors/node-sass"' >> ~/.bashrc
  4. source ~/.bashrc
  5. npm i -g node-sass
  6. mkdir ~/Desktop/scss-demo
  7. cd ~/Desktop/scss-demo
  8. mkdir scss css
  9. touch scss/style.scss
    在scss文件中添加以下内容
$ cat scss/style.scss @function px($px) {
  @return $px/$designWidth*10 + rem;
}

$designWidth: 400px; // 400px是设计稿的宽度,你要根据设计稿的宽度填写

.child {
  width: px(160px);
  height: px(80px);
  margin: px(20px) px(20px);
  border: 1px solid red;
  float: left;
  font-size: 16px;
}
  1. node-sass -wr scss -o css
运行结果

代码:http://js.jirengu.com/zokat/2/edit?html,css,output

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342