移动WEB开发之rem
在2016开年的时候我接到了公司开发微信WEB的任务,老板说会请一个大神来担当带头人,然而并没有。我也只有硬着头皮,摸着石头过河了。
在本文开始之前先推荐一本书,来自PPK大神的《移动WEB手册》,由360齐舞团翻译。这本书没有枯燥的理论,也不是教程或者是指南类书籍。完全是PPK自身的经验,文笔轻松诙谐易于理解,特别适合我这种战五渣的小白。
好了,开始本篇博文的主题:rem
其实网上有很多关于rem的相关文章,我大致搜索看了看,很多是将他与em\px等单位做一个对比,然后粗略的讲讲它该怎么使用。然而具体怎么使用,要不是我看SUI的less源码,讲真我现在都是糊涂的。当然本文也会将它与em\px做一个对比,同时也会将它的具体使用方法列举出来。
px我们不陌生,不过在这里我们特指CSS像素(CSS像素与设备像素以后会说明),以下px和em特点引用至其他网站,因为并不是本文讨论的重点,出处未知。
em和px的主要区别:
1.IE无法调整那些使用px作为单位的字体大小;
2.国外的大部分网站能够调整的原因在于其使用了em作为字体单位;
3.Firefox能够调整px和em,但是96%以上的中国网民使用IE浏览器(或内核)。
px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
em是相对长度单位。相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸。
任意浏览器的默认字体高都是16px。所有未经调整的浏览器都符合: 1em=16px。那么12px=0.75em,10px=0.625em。为了简化font-size的换算,需要在css中的body选择器中声明 Font-size=62.5%,这就使em值变为 16px*62.5%=10px, 这样12px=1.2em, 10px=1em, 也就是说只需要将你的原来的px数值除以10,然后换上em作为单位就行了。
em有如下特点:
1.em的值并不是固定的;
2.em会继承父级元素的字体大小。
所以我们在写CSS的时候,需要注意几点:
body选择器中声明Font-size=62.5%;
将你的原来的px数值除以10,然后换上em作为单位;
重新计算那些被放大的字体的em数值。避免字体大小的重复声明。
也就是避免1.2 * 1.2= 1.44的现象。比如说你在#content中声明了字体大小为1.2em,那么在声明p的字体大小时就只能是1em,而不是1.2em, 因为此em非彼em,它因继承#content的字体高而变为了1em=12px。
但是12px汉字例外,就是由以上方法得到的12px(1.2em)大小的汉字在IE中并不等于直接用12px定义的字体大小,而是稍大一点。这个问 题 Jorux已经解决,只需在body选择器中把62.5%换成63%就能正常显示了。原因可能是IE处理汉字时,对于浮点的取值精确度有限。不知道有没有 其他的解释。
移动web开发之rem:
我之所以加上移动web开发之rem,是因为在移动WEB或是WebApp的开发上,rem这个单位真的很好用。它是CSS3新增的一个相对单位,这个单位与em有什么区别呢?
区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的只是HTML根元素。这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。目前,除了IE8及更早版本外,所有浏览器均已支持rem。对于不支持它的浏览器,应对方法也很简单,就是多写一个绝对单位的声明。这些浏览器会忽略用rem设定的字体大小。
我们先写一个固定font-size大小的Demo
CSS:
html {
font-size: 20px;
}
.div1 {
width: auto;
height: 2.2rem;
line-height: 2.2rem;
background-color: red;
text-align: center;
}
HTML+JS:
<div class="div1"> 改变宽度查看rem的变化 </div>
var $div = $('.div1');
$(window).resize(function () {
$div.html('浏览器宽度:' + $(window).width() + 'px' + ' / ' + 'DIV高度:' + $div.height() + 'px');
});
从以上代码可以看出,在html的font-size设置为20px时,内部元素的1rem=20px。
但大家可能发现这么写其实跟px没什么大的区别,更别说应用到移动端了。那我们该怎么写呢?
我们可以使用JS控制HTML中font-size的大小,这样就可以动态的改变。我们该怎么做呢?判断视口或者浏览器宽度?这是OK的,那我们引用这样一段JS代码:
(function (doc, win) {
var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth > 375 && clientWidth <= 478) {
//当CSS像素大于IP6(375px)小于478px时,根据设备宽度变换rem
docEl.style.fontSize = 20 * (clientWidth / 375) + 'px';
} else if (clientWidth > 478) {
//当CSS像素大于478px时固定
docEl.style.fontSize = '25.4545455px';
} else {
//CSS像素小于设备375px时固定
docEl.style.fontSize = '20px';
}
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
不用自己去设置html标签的font-size大小。我们可以查看这段Demo。
可以看出这段代码动态的控制了html标签的font-size大小,这正是我们所需要的。
不过既然是CSS3新增的单位,同样的思想,我们也可以使用@media来做视口宽度的判断,动态的设置html标签的font-size大小。
LESS
// // Rem // --------------------------------------------------
// Vertical screen
// 375屏幕为 20px,以此为基础计算出每一种宽度的字体大小
// 375以下不变,375以上等比放大
@baseWidth: 375px;
@baseFont: 20px;
html {
font-size: @baseFont;
//默认当做320px宽度的屏幕来处理
}
@bps: 400px, 414px, 480px;
.loop(@i: 1) when (@i <= length(@bps)) {
//注意less数组是从1开始的
@bp: extract(@bps, @i);
@font: @bp/@baseWidth*@baseFont;
@media only screen and (min-width: @bp) {
html {
font-size: @font !important;
}
}
.loop((@i + 1));
}
;
.loop;
编译后的CSS
html {
font-size: 20px;
}
@media only screen and (min-width: 400px) {
html {
font-size: 21.33333333px !important;
}
}
@media only screen and (min-width: 414px) {
html {
font-size: 22.08px !important;
}
}
@media only screen and (min-width: 480px) {
html {
font-size: 25.6px !important;
}
}
使用后效果是这样的Demo。
我个人是比较喜欢使用CSS来控制html标签font-size的大小。可能也有小伙伴发现了一个问题,就是我都是以20px做为基准,为什么不使用其他的大小。这里没有硬性的要求,只要你用着爽,你可以改成你想要的大小。那有的同学就会想,那我就使用1px=1rem,这样不就方便多了。很遗憾这样是不行的。具体原因我忘了,哈哈哈!
最后安利一个另外的方法calc:
html { font-size: calc(100vw/3.75); }
这个我没使用过,但我总觉得calc在移动设备上兼容性不是太好。
//4月6日白天增加//
在写完这篇文章的今天白天,做设计的都是我始终在思考字体大小该怎么处理才好,之前我一直都是借鉴SUI的思路,就是上面使用CSS控制html中font-size大小的那个。
但是在SUI的解决方法中,屏幕小于CSS像素小于375是不进行缩小处理的,这就让我比较尴尬了,毕竟320px/360px的占有很大部分。
我希望是大于414px的固定,小于375px的缩放。
其实我可以自己来写,但是毕竟涉及移动端未深入,不敢乱来。我就想着时不时可以看看手机腾讯网的方案。
HTML:
html{ font-size:1rem; }
这是腾讯网对html标签的设置。嗯,我当时没看懂,但是看到JS代码时理解了。
JS
(function () {
var baseFontSize = 100;
var baseWidth = 320;
var clientWidth = document.documentElement.clientWidth || window.innerWidth;
var innerWidth = Math.max(Math.min(clientWidth, 480), 320);
var rem = 100;
if (innerWidth > 362 && innerWidth <= 375) {
rem = Math.floor(innerWidth / baseWidth * baseFontSize * 0.9);
}
if (innerWidth > 375) {
rem = Math.floor(innerWidth / baseWidth * baseFontSize * 0.84);
}
window.__baseREM = rem;
document.querySelector('html').style.fontSize = rem + 'px';
}());
个人更喜欢腾讯网这种方案,也会在目前的项目使用使用!