原文:http://www.w3cplus.com/preprocessor/sass-px-to-rem-with-mixin-and-function.html

remCSS3中新增加的一个单位值,他和em单位一样,都是一个相对单位。不同的是em是相对于元素的父元素的font-size进行计算;rem是相对于根元素htmlfont-size进行计算。这样一来rem就绕开了复杂的层级关系,实现了类似于em单位的功能。

Rem的使用

前面说了em是相对于其父元素来设置字体大小的,这样就会存在一个问题,进行任何元素设置,都有可能需要知道他父元素的大小,在我们多次使用时,就会带来无法预知的错误风险。而rem是相对于根元素<html>,这样就意味着,我们只需要在根元素确定一个参考值,这个参考值设置为多少,完全可以根据您自己的需求来定。

 

假设就使用浏览器默认的字号16px,来看一些px单位与rem之间的转换关系:

|  px  |     rem       |
------------------------
| 12 | 12/16 = .75 |
| 14 | 14/16 = .875 |
| 16 | 16/16 = 1 |
| 18 | 18/16 = 1.125 |
| 20 | 20/16 = 1.25 |
| 24 | 24/16 = 1.5 |
| 30 | 30/16 = 1.875 |
| 36 | 36/16 = 2.25 |
| 42 | 42/16 = 2.625 |
| 48 | 48/16 = 3 |
-------------------------

如果你要设置一个不同的值,那么需要在根元素<html>中定义,为了方便计算,时常将在<html>元素中设置font-size值为62.5%:

html {
font-size: 62.5%; /* 10 ÷ 16 × 100% = 62.5% */
}

相当于在<html>中设置font-size10px,此时,上面示例中所示的值将会改变:

|  px  |     rem        |
-------------------------
| 12 | 12/10 = 1.2 |
| 14 | 14/10 = 1.4 |
| 16 | 16/10 = 1.6 |
| 18 | 18/10 = 1.8 |
| 20 | 20/10 = 2.0 |
| 24 | 24/10 = 2.4 |
| 30 | 30/10 = 3.0 |
| 36 | 36/10 = 3.6 |
| 42 | 42/10 = 4.2 |
| 48 | 48/10 = 4.8 |
-------------------------

由于rem是CSS3中的一个属性,很多人首先关注的就是浏览器对他的支持度,我截了一张caniuserem属性的兼容表:

从上图可以清楚的知道,rem在众多浏览器中都已得到很好的支持,如果您的项目不用考虑IE低版本的话,你就可以放心的使用了,如果您的项目在IE低版本中还占有不少的比例,那么你还在担心使用rem不能兼容,而不敢使用。其实是没有必要的,可以针对低版本的IE浏览器做一定的处理:

html { font-size: 62.5%; }
body { font-size: 14px; font-size: 1.4rem; } /* =14px */
h1 { font-size: 24px; font-size: 2.4rem; } /* =24px */

这样一来解决了IE低版本的不能兼容的问题,但生出另一个不足地方,就是增加了代码量。必竟鱼和熊掌很多时候不能兼得嘛。

如果你想更深入的了解rem如何使用,建议您阅读:

为什么要使用rem

em单位一样,在Responsive设计中使用rem单位非常有用。虽然他们都是相对单位,但使用rem单位可以避开很多层级的关系。因为em是相对于他的父元素的font-size,而rem是相对于根元素<html>。比如说h1设置了font-size1rem之后,只要不重置htmlfont-size大小,无论他的父元素设置多大,对h1都不会有任何的影响。

Sass中rem的使用

在CSS中,实现pxrem转换非常简单,但每次使用都需进行计算。虽然在html中设置font-size:62.5%;会给大家带来便利,但终究有些烦人,也不是长远之计。既然我们学习了Sass,就应该思考如何让Sass来帮助我们做这些计算的工作。接下来介绍如何使用Sass实现pxrem之间的计算。

rem@function中的使用

Sass中也可以像使用em一样,实现px转换为rem。这个过程也同样是通过Sass的@function方法来实现。

根据rem的使用原理,可以知道pxrem需要在html根元素设置一个font-size值,因为rem是相对于html根元素。在Sass中定义一个pxrem的函数,先要设置一个默认变量:

$browser-default-font-size: 16px !default;//变量的值可以根据自己需求定义

而且需要在html根元素中显示的声明font-size

html {
font-size: $browser-default-font-size;
}

然后通过@function来实现px转为rem计算:

@function pxTorem($px){//$px为需要转换的字号
@return $px / $browser-default-font-size * 1rem;
}

定义好@function之后,实际使用中就简单多了:

//SCSS
html {
font-size: $browser-default-font-size;
}
.header {
font-size: pxTorem(12px);
} //CSS
html {
font-size: 16px; } .header {
font-size: 0.75rem; }

不过定义的这个函数pxTorem()虽然实现了px转换成rem的计算,但不能同时服务于多个属性值的计算:

.header {
font-size: pxTorem(12px);
margin: pxTorem(5px 10px);//同时计算多个值将报错
}

如果这样使用,编译的时候将会报错:

>>> Change detected to: /Users/airen/Sites/testSass/style.scss
error style.scss (Line 4: Undefined operation: "5px 10px/16px times 1rem".)

这也就是说,如果样式同时需要设置多个属性值的时候,pxTorem()变得就局限性太大,换句话说,这个函数仅适合运用在具有单个属性值的属性上,例如font-size。如果要强行使用,只能同时使用多个pxTorem()

//SCSS
.header {
font-size: pxTorem(12px);
margin: pxTorem(5px) pxTorem(10px) pxTorem(15px);
border: pxTorem(1px) solid #f36;
} //CSS
.header {
font-size: 0.75rem;
margin: 0.3125rem 0.625rem 0.9375rem;
border: 0.0625rem solid #ff3366; }

Sass中mixin实现rem

除了使用@function实现px转换成rem之外,还可以使用Sass中的mixin实现pxrem功能。

font-size是样式中常见的属性之一,我们先来看一个简单mixin,用来实现font-sizepxrem

@mixin font-size($target){
font-size: $target;
font-size: ($target / $browser-default-font-size) * 1rem;
}

在实际使用中,可以通过@include调用定义好的@mixin font-size:

//SCSS
.footer {
@include font-size(12px);
} //CSS
.footer {
font-size: 12px;
font-size: 0.75rem; }

可实际中,这个mixin太弱小了,根本无法实现我们需要的效果,因为我们很多样式属性中他可不只一个属性。为了实现多个属性能设置多值,就需要对mixin做出功能扩展:

@mixin remCalc($property, $values...) {
$max: length($values);//返回$values列表的长度值
$pxValues: '';
$remValues: ''; @for $i from 1 through $max {
$value: strip-units(nth($values, $i));//返回$values列表中的第$i个值,并将单位值去掉
$browser-default-font-size: strip-units($browser-default-font-size);
$pxValues: #{$pxValues + $value * $browser-default-font-size}px; @if $i < $max {
$pxValues: #{$pxValues + " "};
}
} @for $i from 1 through $max {
$value: strip-units(nth($values, $i));
$remValues: #{$remValues + $value}rem; @if $i < $max {
$remValues: #{$remValues + " "};
}
} #{$property}: $pxValues;
#{$property}: $remValues;
}

在这个remCalc()中定义了两个参数$property$values...。其中$property表示的是样式属性,而$values...表示一个或者多个属性值。

注:在上面定义的remCalc中使用了下自定义的函数strip-units,主要用来去除单位,详细的请参阅Sass基础——PX to EM Mixin和@function一文中的strip-units函数定义方法。

pxremmixin定义完成后,就可以通过@include来引用:

//SCSS
.wrapper {
@include remCalc(width,45);
@include remCalc(margin,1,.5,2,3);
} //CSS
.wrapper {
width: 720px;
width: 45rem;
margin: 16px 8px 32px 48px;
margin: 1rem 0.5rem 2rem 3rem; }

在实际使用中取值有一点非常重要remCalc()取的$values值为rem

Rem与Px的转换[转载]的更多相关文章

  1. rem与px的转换

    rem与px的转换 引用自http://caibaojian.com/rem-and-px.html A-A+ 前端博客•前端开发教程•rem•3702View0 rem是相对于根元素<html ...

  2. Sass基础——Rem与Px的转换

    rem是CSS3中新增加的一个单位值,他和em单位一样,都是一个相对单位.不同的是em是相对于元素的父元素的font-size进行计算:rem是相对于根元素html的font-size进行计算.这样一 ...

  3. 转: rem与px的转换

    rem是相对于根元素<html>,这样就意味着,我们只需要在根元素确定一个参考值,这个参考值设置为多少,完全可以根据您自己的需求来定.· 我们知道,浏览器默认的字号16px,来看一些px单 ...

  4. 移动端适配方案以及rem和px之间的转换

    背景 开发移动端H5页面 面对不同分辨率的手机 面对不同屏幕尺寸的手机 视觉稿 在前端开发之前,视觉MM会给我们一个psd文件,称之为视觉稿. 对于移动端开发而言,为了做到页面高清的效果,视觉稿的规范 ...

  5. 自动把网页px单位转换成rem

    自动把网页px单位转换成rem 首先在你的项目开发环境中安装2个插件 然后在vue.config.js文件引入并重新启动服务器 这样就配置成功了,一起看看效果

  6. vue换算单位px自动转换rem

    cnpm i postcss-px2rem --save cnpm install px2rem-loader --save 2.配置px2rem build目录下vue-loader.conf.js ...

  7. EM vs REM vs PX,为什么你不应该”只用px“”

    Actually this artical is from other person's opnion ,i just put it into chinese,and this means a ver ...

  8. 使用em和rem替代px

    rem是指根元素的字体大小,默认情况下html的字体大小为:16px=1rem.而em是相对单位,是基于它的祖先元素计算的. 如果我们不指定html和body的字体大小,要得到12px的rem需要这样 ...

  9. android 手机屏幕有关的几个工具(屏幕宽高,dp和px互相转换)

    平时适配页面时经常会需要根据屏幕的宽高来设置控件的大小,很多时候在代码中还会需要dp和px互相转换. 今天把最常用的几个记录一下,经测试包括2.3 ~ 5.0之间的版本都可用,其他版本未测,不过应该也 ...

随机推荐

  1. Qt全局宏和变量

    1.  Qt 全局宏定义 Qt版本号: QT_VERSION :  (major << 16) + (minor << 8) + patch 检测版本号: QT_VERSION ...

  2. UI自动化测试简介及Selenium工具的介绍和环境搭建

    自动化测试简介 1.1何为自动化测试? 是把以人为驱动的测试转化为机器执行的一种过程,它是一种以程序测试程序的过程.换言之,就是以程序实现的方式来代替手工测试. 1.2自动化测试分类 分为功能自动化测 ...

  3. Happy 2006 poj2773

    Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9049   Accepted: 3031 Descri ...

  4. hdu3507 Print Article(斜率DP优化)

    Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it ...

  5. Python系列之lambda、函数、序列化

    lambda 在python中使用lambda来创建匿名函数,而用def创建的方法是有名称的,除了从表面上的方法名不一样外,python lambda还有哪些和def不一样呢? 1 python la ...

  6. java web jsp学习笔记--概述-常用语法,指令,动作元素,隐式对象,域对象

     JSP学习笔记 1.什么是jsp JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP/Servlet规范.JS ...

  7. SQL Server2008安装教程

    SQL Server2008安装教程   第一步,打开文件,点击开始安装: 第二步,打开后点击左边项的安装,选择右边第一项: 第三步,点击确定: 第四步,选择接受服务条款,点击下一步: 第五步,按着一 ...

  8. iOS之浅谈纯代码控制UIViewController视图控制器跳转界面的几种方法

    .最普通的视图控制器UIViewContoller 一个普通的视图控制器一般只有模态跳转的功能(ipad我不了解除外,这里只说iPhone),这个方法是所有视图控制器对象都可以用的,而实现这种功能,有 ...

  9. canvas图表详解系列(3):动态饼状图(原生Js仿echarts饼状图)

    本章建议学习时间4小时 学习方式:详细阅读,并手动实现相关代码(如果没有canvas基础,需要先学习前面的canvas基础笔记) 学习目标:此教程将教会大家如何使用canvas绘制各种图表,详细分解步 ...

  10. Spring4.0.1+Quartz2.2.1实现定时任务调度[亲测可用]

    Spring4.0.1+Quartz2.2.1实现定时任务调度[亲测可用] tip:只需要配置xml文件即可 1.第三方依赖包的引入 <properties> <project.bu ...