06移动webapp适配方案--rem

Posted TigerChain

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了06移动webapp适配方案--rem相关的知识,希望对你有一定的参考价值。

1
教程简介
  • 1、阅读对象
    本篇教程适合新手阅读,老手直接略过

  • 2、教程难度
    初级,本人水平有限,文章内容难免会出现问题,如果有问题欢迎指出,谢谢

2
教程大纲

一、media query「媒体查询」

  • 媒体查询的作用

  • 媒体查询的语法以及 Demo 实现适配

二、rem

  • 什么是 rem 以及 Demo 编写

  • 动态修改 html 的根 fontsize 以及 Demo

三、参考文献

3
正文

一、media query「媒体查询」

在聊 rem 之前,我们先看看什么是 media query?

为了适配多种屏幕大到电脑,小到手机等, css3 中有了多媒体查询这个功能「是继承 css2 多媒体类型的思想」,通过 media query 就可以做响应式的开发

1、media query 的作用

  • 可以检测 viewport(视窗) 的宽度与高度

  • 可以检测设备的宽度与高度

  • 可以检测设备的分辨率

2、media query 的语法

@media not|only mediatype and (expressions) {
    CSS 代码...;
}

我们可以看到 media query 由四部分组成

  • 1、关键字:@media

  • 2、操作符:not|only|all 「默认不写就是 all」

  • 3、媒体类型:mediatype

  • 4、表达式:expressions

这里的媒体类型有以下几种:

描述
all 用于所有多媒体类型设备
print 用于打印机
screen 用于电脑屏幕,平板,智能手机等。
speech 用于屏幕阅读器

一般情况下我们使用 screen 的媒体类型是最多的

举个栗子

我们想让在屏幕尺寸大于 375px 的设备上让 class 为 div1 的背景显示成红色,media query 哪下定义

@media screen and (min-device-width : 375px){
.div1 {
    background-color:red;
   }

}

我们可以针对不同的设备宽度来设置不同的样式 ,这样就达到了响应式布局的效果,现在我们来一个例子说明吧

3、demo 验证 media query

效果如下


从上面的效果图我们可以看到,我们针对不同屏幕宽度就会显示不同的效果,这就是响应式布局,下面我们使用 media query 来实现这一效果

撸码实现上述效果

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>media-query</title>
 <!-- 重置默认的 css 样式 ,类似于 reset.css -->
 <link rel="stylesheet" href="../css/normalize.css">
 <!-- https://necolas.github.io/normalize.css/7.0.0/normalize.css -->

 <style>
   .box {
     width:100% ;
     height:80px;
     background-color: red;
   }


   /* 屏幕小于 375 px 则是下面的样式 */
   @media screen and (max-device-width : 375px){
     .div1 {
       width:25%;
       background-color: green;
       height:80px;
     }

   }

   /* 屏幕大于 376 小于 414 px 则使用下面的样式 */
   @media screen and (min-device-width : 376px) and (max-device-width:414px){
     .div1 {
       width:50%;
       background-color: blue;
       height:80px;
     }

   }

   /* 小于等于 375px 使用以下样式  */
   @media screen and (max-device-width: 375px) {
     .menuitem1 {
       height: 100px;
       width: 100%;
       background-color: yellow;
     }

     .menuitem2 {
       height: 100px;
       width: 100%;
       background-color: blue;
     }

     .menuitem3 {
       height: 100px;
       width: 100%;
       background-color: #cceedd;
     }


     .menuitem4 {
       height: 100px;
       width: 100%;
       background-color: black;
     }

   }

   /* 大于等于 376px 使用以下样式 */
   @media screen and (min-device-width: 376px) {
     .menu {
       display: flex;
     }

     .menuitem1 {
       height: 100px;
       width: 100%;
       background-color: yellow;
     }

     .menuitem2 {
       height: 100px;
       width: 100%;
       background-color: blue;
     }

     .menuitem3 {
       height: 100px;
       width: 100%;
       background-color: #cceedd;
     }

     .menuitem4 {
       height: 100px;
       width: 100%;
       background-color: black;
     }

   }
 
</style>
</head>
<body>

 <div id="contnainer">
   <div></div>
 </div>
 <!-- mediaquery 实现响应式布局 -->
 <div>
   <div></div>
   <div></div>
   <div></div>
   <div></div>
 </div>

</body>
</html>

以上代码就实现了上述效果图,代码注释清楚,这里也不多说了

二、rem「font size of the root element」

1、什么是 rem

rem 就是根据网页根元素「html」来设置字体大小,这有什么用呢?这是移动 webapp 的最佳的适配方案「目前来说」,既然说是最佳的适配方案,那肯定还有别的适配方案,先看看都有那些适配方案吧

  • 1、viewport缩放「被废弃了」

  • 2、宽度固定两边留白「体验很差」

  • 3、响应式布局「工作量太大,针对不同的分辨率写一套 android 下估计开发者就疯了」

2、如何适配

我们先来看一个简单的例子吧,然后就能得到一些启发和感悟

  • 1、新建一个 rem.html 然后输入以下内容

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <!-- 重置默认的 css 样式 ,类似于 reset.css -->
 <link rel="stylesheet" href="../css/normalize.css">
 <title>rem demo</title>

 <style>
   .box {
     width: 100px;
     height: 100px;
     background-color: red;
     text-align: center;
   }

   .test {
     font-size: 16px;
     line-height: 100px;
   }

 
</style>
</head>
<body>

 <div>
   <span>测试</span>
 </div>

</body>
</html>

很简单就是一个宽高为 100px 的 div 并且里面有一个居中的文字大小为 16px

  • 2、运行查看结果


06、移动webapp适配方案--rem


从图中我们可以看到,不管我们是什么分辨率的机型下,div 宽高都为 100px,这是不合理的,根本就没有适配「就是写死的呀」

  • 3、由于 2 中的效果是写死的,我们来看看 rem 是如何适配的,稍微把代码改一下

我们知道 rem 和 html 下的 font-size 有关,我们来改代码吧

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <!-- 重置默认的 css 样式 ,类似于 reset.css -->
  <link rel="stylesheet" href="../css/normalize.css">
  <title>rem demo</title>

  <style>
     html {
       font-size: 16px;
     }
    .box {
      width: 10rem;
      height: 10rem;
      background-color: red;
      text-align: center;
    }
    .test {
      font-size: 1rem;
      line-height: 10rem;
    }
  </style>
</head>
<body>

  <div>
    <span>测试</span>
  </div>

</body>
</html>

ps: 这里说明几点

为什么这里 font-size 要写成 16px ,因为大部分浏览的默认字体都是显示 16px,我们从 chrome 调试工具中可以看到

06、移动webapp适配方案--rem


html 默认的 font-size 大小就 = 1rem , 从上面代码我们可以看到 box 的宽高都为 10rem 即 160px ,我们来验证一下,运行看结果

06、移动webapp适配方案--rem


果然是 160px「肯定在别的分辨率上也是 160px」,这有个毛用呀,不就是把 100px 转化成 160px 了吗?还不是没有适配呀「大家是不是有这个疑问」,别急马上揭晓答案

我们可以想一下,rem 和 font-size 有关,那么如果我们能动态的修改 font-size 的大小,那么以 rem 为单位的宽高等不就自动适配了吗。我们来一下修改 font-size 的效果

06、移动webapp适配方案--rem


看到了吧,我们手动修改 font-size 的值 div 的宽高就会动态改变「如果在不同分辨率的手机上设置不同和 font-size 那不就达到适配的效果了」

三、适配手段

我们知道只要动态的修改 font-size 使用 rem 就可以适配多种手机了

  • 1、通过 media query 来设置 font-size,比如:

html {
   font-size : 20px;
}

@media only screen and (min-width: 401px){
   html {
       font-size: 25px !important;
   }

}
@media only screen and (min-width: 450px){
   html {
       font-size: 26.75px !important;
   }

}
@media only screen and (min-width: 481px){
   html {
       font-size: 30px !important;
   }

}
  • 2、通过 js 来设置

估计上面的方法能把人写疯,特别对于 android 这个多样机型来说「一般只适配常用的分辨率」,那就有了下面的方法,使用 js 来动态设置 font-size

再说 js 动态修改 font-size 之前,先推导下 px 转化成 rem 的公式:

比如:1rem = 16px「rem 的基准值」 ; 48px = 48/16 = 3rem,

所以得出:

rem = 需要转化的px/rem基准值

rem 基准值「和 html 的 font-size 有关」如何算,这里给出一个比较常见的做法,就是用设计稿的屏幕宽度/10 ,原则上除以多少都可以,除以 10 是为了好除「业界基本上也是这样做的」,比如以 iPhone 6p「414*736」 为例子,那么 rem 的基准值就是 414/10 = 41.4px,然后我们就是要不停的改变这个页面基准值的值即可,我们只要记住一点,rem 的基准值是根据设计稿来决定的

我们也知道了,如果把一个 px 转化成 rem 那么就是使用 px/rem基准值,这样界面中的 css 中有太多的 px ,如果一个个除下来人头发都白了「也不一定能除完,当然网上也有在线转换网站,就是这样也累呀」,我们可以使用 sass「css 扩展语言」 来解决这个问题

sass 的安装

  • 2、安装 sass 和 compass

gem install sass
gem install compass

以上安装速度如果慢的话,可以切换成淘宝的 gem「安装基于ruby的软件」源

  • 3、查看是否安装成功


06、移动webapp适配方案--rem


如果看到这个,就证明 sass 安装成功了

  • 4、具体的安装过程请看:https://www.sass.hk/install/

写个 demo 感受一下

  • 1、新建一个 usesass.html

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <link rel="stylesheet" href="../css/normalize.css">
 <link rel="stylesheet" href="../css/usesass.css">
 <title>使用 sass </title>
</head>
<body>

 <div>
   <div><span>1</span></div>
 </div>

</body>
</html>

细心的朋友会发现,我们这里引入了一个 usesass.css 样式文件,哪来的?目前这个文件是不存在的,完后我们使用 sass 直接转换成普通的 css 文件即可

  • 2、在 css 目录下新建 usesass.scss 文件

scss 和 sass 文件区别,前者对格式没有严格要求,后者对格式有严格的要求「没有大括号等,这里我们使用 scss」

.box{
 background-color: red;
 width: 100px;
 height: 100px;
 display: flex;
 justify-content: center;
 align-items: center;
}
.item {
 background-color: yellow;
 width:50px;
 height:50px;
}
  • 3、scss 肯定是直接不能使用的,我们要转化一下,使用 sass 命令

我们进入到 css 目录下使用如下命令

sass usesass.scss usesass.css

这样就会在 css 目录下创建一个 usesass.css 文件并且把 sass 转化成 css 了,我们看看这个 css 文件

.box {
 background-color: red;
 width: 100px;
 height: 100px;
 display: flex;
 justify-content: center;
 align-items: center; }


.item {
 background-color: yellow;
 width: 50px;
 height: 50px; }

看起来和上面的 sass 文件是一毛一样的「原因是我们没有使用 sass 的扩展语法,sass 是兼容所有的版本的 css 的」

  • 4、运行一下看结果


06、移动webapp适配方案--rem


没有什么毛病,sass 成功转化成 css 并且显示出结果了

使用 sass 来转化 px—rem ,并且使用 js 动态设置 font-size

  • 1、提供 px2rem() 函数

在 sass 中我们可以使用函数,我们定义一个函数用来转化 px 到 rem,这里以视觉稿为 iphone 6p「414*736」 为例子,那么 rem 的基准值就是 41.4px ,我们在 usesass.sass 中添加如下代码,并且修改 box 的宽高 px 为 rem「调用 px2rem()方法」

@function px2rem($px){
  // rem基准值
    $rem : 41.4px;
    @return ($px/$rem) + rem;
}

.box{
  background-color: red;
  width: px2rem(100px);
  height: px2rem(100px);
  display: flex;
  justify-content: center;
  align-items: center;
}
.item {
  background-color: yellow;
  width:px2rem(50px);
  height:px2rem(50px);
}
  • 2、使用 js 动态的修改 font-size 的值

在 usesass.html 添加以下动态修改 font-size 的代码

<script>
  // 取得屏幕宽度
  var devicewidth = document.documentElement.clientWidth || document.body.clientWidth
  //动态设置 html font-size 值
  document.getElementsByTagName('html')[0].style.fontSize = devicewidth / 10 + 'px';
</script>
  • 3、记得一定要把 sass 转化成 css

sass usesass.scss usesass.css

我们再看看 usesass.css 文件

.box {
 background-color: red;
 width: 2.4154589372rem;
 height: 2.4154589372rem;
 display: flex;
 justify-content: center;
 align-items: center; }


.item {
 background-color: yellow;
 width: 1.2077294686rem;
 height: 1.2077294686rem; }

我们看 px 成功的转化成 rem 了,这样我们就可以动态的修改 rem 了

  • 4、看看效果吧

先看效果之前,我们为了方便测试,来给动态修改 rem 添加一个事件吧,否则每次修改分辨率都要重新刷新一下浏览器「这里是为了演示添加的代码」

// 窗口大小改变时的回调
window.onresize = function(){
 // 取得屏幕宽度
 var devicewidth = document.documentElement.clientWidth || document.body.clientWidth
 //动态设置 html font-size 值
 document.getElementsByTagName('html')[0].style.fontSize = devicewidth / 10 + 'px';
}


依据前面我们知道,我们是以设计稿为 iphone 6p 基准来设置的「在此手机上宽高就是 100 px」,从上图可以看到确实在不同的分辨率手机下 box 的宽高等比缩放,这就达到了适配的目的,基本上 rem 适配手机 webapp 方法就说完了

三、参考资料

腾讯全端AlloyTeam团队—移动web适配利器—rem:http://www.alloyteam.com/2016/03/mobile-web-adaptation-tool-rem

点赞是一种美德,转发富五代

更多文章等着你,欢迎关注我的公号

长按下图识别图中二维码或是扫描添加即可关注


以上是关于06移动webapp适配方案--rem的主要内容,如果未能解决你的问题,请参考以下文章

rem移动端适配方案

移动端适配

为什么说移动端该放弃rem适配方案了?

为什么说移动端该放弃rem适配方案了?

移动端适配-px转成rem

rem, vw, 还是...? 各凭本事的移动端适配方案