06移动webapp适配方案--rem
Posted TigerChain
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了06移动webapp适配方案--rem相关的知识,希望对你有一定的参考价值。
1、阅读对象
本篇教程适合新手阅读,老手直接略过2、教程难度
初级,本人水平有限,文章内容难免会出现问题,如果有问题欢迎指出,谢谢
一、media query「媒体查询」
媒体查询的作用
媒体查询的语法以及 Demo 实现适配
二、rem
什么是 rem 以及 Demo 编写
动态修改 html 的根 fontsize 以及 Demo
三、参考文献
一、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 | 用于所有多媒体类型设备 |
用于打印机 | |
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、运行查看结果
从图中我们可以看到,不管我们是什么分辨率的机型下,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 调试工具中可以看到
html 默认的 font-size 大小就 = 1rem , 从上面代码我们可以看到 box 的宽高都为 10rem 即 160px ,我们来验证一下,运行看结果
果然是 160px「肯定在别的分辨率上也是 160px」,这有个毛用呀,不就是把 100px 转化成 160px 了吗?还不是没有适配呀「大家是不是有这个疑问」,别急马上揭晓答案
我们可以想一下,rem 和 font-size 有关,那么如果我们能动态的修改 font-size 的大小,那么以 rem 为单位的宽高等不就自动适配了吗。我们来一下修改 font-size 的效果
看到了吧,我们手动修改 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、查看是否安装成功
如果看到这个,就证明 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、运行一下看结果
没有什么毛病,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的主要内容,如果未能解决你的问题,请参考以下文章