REM or EM

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuexueenen/article/details/53544640

2010年,Ethan Marcotte提出了"自适应网页设计"(Responsive Web Design)这个名词,指可以自动识别屏幕宽度、并做出相应调整的网页设计。


在小编这次做的移动端Web App中,也遇到了需要兼容不同设备的自适应布局的问题,尽管这是一个老生常谈的问题,小编这次也希望能够重拾一下基础,和大家说说这次开发中在这个领域的一些整理


我们看下传统的页面的自适应布局都会用到哪些方式:

1.viewport

现在的只能手机(IOS,Android)的浏览器都是基于webkit内核的,所以自然会有一些针对webkit的特殊的meta标签,这在开发移动端上尤为重要,如下:

<meta name="viewport" content="width=320,maximum-scale=1.2,user-scalable=no">

这里以320宽度为基准,进行缩放,最大缩放为320 * 1.2 = 384,这个方法简单粗暴,又高效


2.Flex布局

这里通过定义3个css属性即可做到

1)定义box-sizing
2)弹性布局display:flex
3)定义行内块级display:inline-block


3.固定宽度

比如把页面的宽度强制设置为320的宽度,超出的部分留白,视觉再也不用担心被流失布局限制自己的灵感了,前端也不用再搞坑爹的流式布局了,但是大屏手机下,页面会显得比较小,并且两边也是留白的,这对挑剔的用户来说,也是极大的影响他们的体验。


4.响应式做法

如中小型的门户或者博客类站点采用,从web page到web app一步到位,但是这样会导致工作量大,可维护性低,但是这样反而能够节约成本,不用再专门为自己的网站做一个web app的版本。


5.rem或者em

这也是目前一种主流的web app的适配解决方案,这也是接下来我打算重点说一说的内容。


首先我们先了解下生涩的理论定义,到底什么是rem,什么是em

rem:(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。

em:W3C对其定义为一个CSS单位,1em等于当前的字体尺寸。


所以我们看得出来,这两个单位都是灵活,可扩展的单位,由浏览器转换为像素值,他们的实际大小取决于设计中的字体大小设置。如果你使用1em或者1rem,在浏览器默认的字体大小下,也就是16px,他可以被浏览器翻译成从16px到160px或其他任意值。


这里我们可以看下一个简单的em的例子:


在这里,浏览器将其翻译为320px



em 和 rem 单位提供的这种灵活性和工作方式都很相似,所以最大的问题是,我们何时应使用 em 值,何时应使用 rem 值呢?


这里我们需要先明确一个概念,页面元素的默认字体大小是什么

默认情况下浏览器的字体大小通常为16px,但这可以被用户更改为从9px到72px之间的任何值


html的根元素将会继承浏览器中设置的字体大小,除非显示的去设置固定值去覆盖


那么我们看下,他们的主要区别在哪里

em单位是如何转换为像素值的

当使用em单位时,像素值将是em值乘以使用em单位的元素的字体大小,如下:

这里,一个div的宽度为20em,其中设置的字体大小为30px,那么,实际上浏览器渲染的div宽度将为20 * 30 = 600px



渲染的效果:



那,这里有个比较普遍的误解,很多人认为em单位是相对于父元素的字体大小,事实上,根据W3C的标准,他们是相遇使用em单位的元素的字体大小。

父元素的字体大小可以影响em值,纯粹是因为继承的关系,使用em单位时,每个元素将自动继承其度元素的字体大小,继承的效果只能被明确的字体单位覆盖,如:px,因此,以em为单位的元素字体大小可能收到其任何父元素的字体大小影响。



那么,这里并不是说em不好,em单位的主要目的是允许保持在一个特定的设计元素范围内,做一些可伸缩的渲染,如,我们已使用em值设置导航菜单项的padding

这里我们分别看下以20px和25px为字体大小的菜单项的样子(这里小编做的简单点,大家明白意思就好)




所以,一般来说,你需要使用em代为的唯一原因是缩放没有默认字体大小的元素,比如按钮,菜单或者标题可能会有自己明确的字体大小,当你修改字体大小的时候,你希望整个组件都适当缩放,这将适用于非默认字体大小的元素上的padding,width,height或者line-height。


rem单位是如何转换为像素值的

当使用 rem 单位,他们转化的像素大小取决于页面根元素的字体大小,即 html 元素的字体大小。根元素字体大小乘以你 rem 值。

如:根元素的字体大小为16px,10rem将等同于160px,即10 * 16 = 160

但是,不同设备的分辨率是不同的,那我们如何做到不管在任何分辨率下,页面的排版都能够按照等比例切换,并且保证布局不乱呢,这里是需要一段JS去根据浏览器的分辨率去改变font-size的,总而影响到rem的实际渲染大小的,这里,我们来看一组表格,我这里是根据640的标准尺寸去等比例转换不同size的


所以,这里都是使用10rem的,是不是很爽!

以下为小编系统中的用于动态计算跟元素的font-size的JS代码,这里做了增强处理

function Fjjrem(){
	this.Fjjwidth = 320;
	this.Fjjheiht = 480;
	this.count = 0;
	this.type = 'all';
	this.Go = function (){
		this.s();
	}
	var $this = this;
	this.s = function() {
		var count = 0;
		
		function setHtmlFontSize(callback) {
			var baseWidth = $this.Fjjwidth,
				baseHeiht = $this.Fjjheiht,
				baseFontSize = 100,
				newSize = 1,
				sacle = 1;

			var sacle = '';
			switch ($this.type){
				case 'width':
					sacle = window.innerWidth / baseWidth;
					break;
				case 'heiht':
					sacle = window.innerHeight / baseHeiht;
					break;
				case 'min':
					sacle = Math.min(window.innerWidth / baseWidth, window.innerHeight / baseHeiht);
					break;
				case 'max':
					sacle = Math.max(window.innerWidth / baseWidth, window.innerHeight / baseHeiht)
					break;
			}
			var	newSize = parseInt(sacle * 10000 * baseFontSize) / 10000;
			setTimeout(function() {
				if (callback) {
					callback();
				}
				if(newSize > 100){
					newSize = 100;
				}
				document.documentElement.style.fontSize = newSize + "px";
			}, 0);
		}
		setHtmlFontSize();
	}
	window.onresize = this.s;
}

不过,创建布局的时候,往往以像素为单位更为方便,但部署时,应该使用rem单位,当然,我们可以使用预处理比如Stylus / Sass / Less,来自动转换单位或PostCSS之类的插件。


总的来看,使用rem或者em去做页面的适配各有所长,但是如何最好地利用他们在我们的设计中,还需要不断接触不同的设计和页面,具体案例,具体分析了。


以上内容,大神们不免会有嫌弃,毕竟仅仅是浅谈笔者目前项目中开发用到的一点点技术和笔者自己一点点的积累,有啥问题也请大神们指点指点,毕竟笔者也还是个孩子,孩子的邮箱还是那个邮箱:

[email protected]


最后坦白来说,想写的东西有很多,想研究的东西有很多,想说的废话也有很多,嘿嘿,不过毕竟细水长流嘛,笔者也会继续默默的学习,默默的更新博客,尽管路不好走,但还得走啊!


猜你喜欢

转载自blog.csdn.net/xuexueenen/article/details/53544640