前言

  在移动端做自适应,我们常用的有媒体查询,rem ,em,宽度百分比这几种方案。但是都各有其缺点。

  首先拿媒体查询来说,在某一个宽度区间内只能使用一种样式,为了适应不同屏幕要,css的代码量就会增多,并且后期页面如果有改动,会变得越来越不易维护。em得根据父元素的字体大小来计算宽高,有很大局限性。用百分比来设置宽度局限性也大,首先是得计算每个元素占父元素的宽度,而且只能设置宽度的百分比,而高度则很难通过百分比来设置。所以最后的希望寄托在了rem上。

  rem与px

  在讲rem实现方案之前,我们还是按照国际惯例,讲一下rem与px之间的关系。rem是指相对于根元素的字体大小的单位。这句话怎么理解呢?请看下面的公式:

  元素的rem值 = 元素的px值 / 根节点字体大小 ,我们举栗子说明一下。

  如果我们设置了根元素的字体大小为13px,那么一个宽300px,高350px的元素对应的rem就是宽23.076923rem,高26.923076rem。

代码如下:

html{
font-size: 13px;
} div{
width: 23.076923rem; // 23.076923rem = 300px / 13px
height: 26.923076rem;// 26.923076rem = 350px / 13px
}

可以通过查看器对上面的公式进行验证,如图:

  可以看出,浏览器根据rem值自动计算得到div的宽高分别为300px,350px。由此我们可以把根节点字体大小作为自变量,元素宽高作为因变量(注意:此处的宽高指的是浏览器通过换算得到的元素px值,而不是rem值)。当我们通过JavaScript动态改变根节点字体大小时,浏览器就会重新计算元素的宽高,也就可以实现了动态缩放。但是怎么把缩放跟屏幕宽度联系起来呢?

  回答上述问题之前我们得知道,任何的缩放都必须有一个参考点,才能称为缩放,这是我们平时很容易忽略的一点。所以接下来我们以iphone6的设计稿为参考点,选择iphone6是因为现在大多数的UI出图都是iphone6的尺寸,我们写好css代码后,浏览器就可以在此基础上计算元素px值,从而达到缩放的效果。

同样通过例子来说明:UI图标注div宽300px, 高350px, 字体大小20px。

实现

index.html  

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="user-scalable=no, initial-scale=1, maximum-scale=1,
minimum-scale=1, width=device-width, height=device-height"/>
<title>Title</title>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div>
hello 大家
</div>
</body>
<script src="./src/index.js"></script>
</html>

index.css

div{
font-size: 0.533333rem; // 0.533333rem = 20px / 37.5px
width: 8rem;        // 8rem = 300px / 37.5px
height: 9.333333rem; // 9.333333rem = 350px / 37.5px
margin: 0 auto;
background-color: lightskyblue;
}

注意此处并没有设置根节的font-size为37.5px。但是计算rem时却使用了它,因为37.5px即为iphone6屏幕的十分之一,就是为了把iphone6作为参考基准,并且这样元素的宽高与屏幕的宽度之间就有了一个比例关系。当通过js通过改变font-size的值,并且保证这个值始终与屏幕宽度有一个比例关系时,浏览器根据公式重新计算元素的宽高就和屏幕宽度也就有了一个比例关系。当屏幕变宽,元素放大,当屏幕变窄元素缩小。

index.js

var htmlWidth = document.documentElement.clientWidth || document.body.clientWidth //获取屏幕宽度
var htmlDom = document.getElementsByTagName('html')[0] //获取html
htmlDom.style.fontSize = htmlWidth / 10 + 'px'; //设置html字体大小为屏幕的十分之一 //监听窗口大小改变
window.addEventListener('resize', () => {
var htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
var htmlDom = document.getElementsByTagName('html')[0]
htmlDom.style.fontSize = htmlWidth / 10 + 'px';
}) 

这样基本上就已经可以实现自适应了

但是还有一个重要的问题没解决。我们不能每一个元素的rem值都像上面那样挨个手动计算,这样效率太低。

下面介绍两种解决方案:

第一种:利用scss定义函数实现自动转换

新建index2.scss文件

@function px2rem($px){
$rem:37.5px;
@return ($px / $rem) + rem;
} div{
font-size: px2rem(20px);
width: px2rem(300px);
height: px2rem(350px);
margin: 0 auto;
background-color: lightskyblue;
}

然后看看IDE自动帮我们编译后的文件index2.css, 和index.css文件一模一样

div{
font-size: 0.533333rem;
width: 8rem;
height: 9.333333rem;
margin: 0 auto;
background-color: lightskyblue;
}

第二种:借助webpack,px2rem-loader实现

先下载各种loader

npm install style-loader css-loader px2rem-loader --save-dev

配置webpack

{  
test: /\.css$/,
   use: ExtractTextPlugin.extract({    fallback: "style-loader",    use: [{
          loader: "css-loader",
     }, {
loader: 'px2rem-loader?remUnit=37.5&remPrecision=6'
}],
})
}

 

index3.css

div{
font-size: 20px;
width: 300px;
height: 350px;
margin: 0 auto;
background-color: lightskyblue;
}

通过webpack编译过后的index.css3文件还是和index.css文件一样。这样就直接可以按照ui图来写代码,不用任何计算。提高了效率

从原理到方案,一步步讲解web移动端实现自适应等比缩放的更多相关文章

  1. web移动端适配方案

    web移动端常用解决方案: 一.通过js+rem,这里有一个解决方案(http://imochen.github.io/hotcss/) 1.1.rem兼容性(https://caniuse.com) ...

  2. 空间变换网络(STN)原理+2D图像空间变换+齐次坐标系讲解

    空间变换网络(STN)原理+2D图像空间变换+齐次坐标系讲解 2018年11月14日 17:05:41 Rosemary_tu 阅读数 1295更多 分类专栏: 计算机视觉   版权声明:本文为博主原 ...

  3. 关于如何提高Web服务端并发效率的异步编程技术

    最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...

  4. web移动端性能调优及16ms优化

    本文只是一个索引,收集了网络上大部分关于调试及优化方面的文章,从中挑选了一些比较好的文章分享给大家. 移动端性能不及桌面浏览器性能的10分之1,特别是在android设备良莠不齐的情况下,性能显得尤为 ...

  5. 如何提高Web服务端并发效率的异步编程技术

    作为一名web工程师都希望自己做的web应用能被越来越多的人使用,如果我们所做的web应用随着用户的增多而宕机了,那么越来越多的人就会变得越来越少了,为了让我们的web应用能有更多人使用,我们就得提升 ...

  6. 【转载】Web移动端Fixed布局的解决方案

    特别声明:本文转载于EFE的<Web移动端Fixed布局的解决方案>.如需转载,烦请注明原文出处:http://efe.baidu.com/blog/mobile-fixed-layout ...

  7. iOS 【终极方案】精准获取webView内容高度,自适应高度

    前言:是这样的,刚写完上一篇文章还没缓过神来,上一篇文章我还提到了,想和大家聊聊原生+H5如何无缝连接的故事.结果我朋友就给我发了两篇他的作品.他的做法也都有独到之处.好的文章都是这样,让你每次看都能 ...

  8. IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践

    说到ios的应用开发,我们不能不提到web server服务端,如果没有服务端的支持,ios应用开发就没有多大意义了,因为从事过手机开发的朋友都知道(Android也一样),大量复杂业务的处理和数据库 ...

  9. web服务端的架构演变

    此文已由作者肖凡授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 最近Lofter项目碰到很多性能上的问题,特别是数据库相关的,每次推送后,告警就会第一时间到来.这些问题随着产 ...

随机推荐

  1. 【新人赛】阿里云恶意程序检测 -- 实践记录11.3 - n-gram模型调参

    主要工作 本周主要是跑了下n-gram模型,并调了下参数.大概看了几篇论文,有几个处理方法不错,准备下周代码实现一下. xgboost参数设置为: param = {'max_depth': 6, ' ...

  2. php ftp 使用 以及 php_connect_nonb() failed: Operation now in progress (115)

    设置 ftp_pasv($conn,true);  会出现下面错误   不设置 调用ftp 连接没问题  ftp_nlist  ftp_put ftp_get 等函数都不成功 ftp_nb_fput( ...

  3. VMware Workstation Pro工具

    安装包 链接:https://pan.baidu.com/s/1n-URb83lHtric3Ds8UbF9Q 提取码:c9z5 密钥 FF31K-AHZD1-H8ETZ-8WWEZ-WUUVA CV7 ...

  4. IO流学习之字符流(三)

    IO流之字符流缓冲区: 概念: 流中的缓冲区:是先把程序需要操作的数据保存在内存中,然后我们的程序读写数据的时候,不直接和持久设备之间交互,而改成和内存中的数据进行交互. 缓冲区:它就是临时存储数据, ...

  5. Scala之Option: Some None

    Option类型本身没有实现,而是依赖两个子类型提供具体实习那:Some和None.Some是iyge类型参数化的单元素集合,None是一个空集合. ----<scala学习手册>P119

  6. 1级搭建类101-Oracle 11g 单实例 FS LVM(11.2.0.4+RHEL 5)公开

    项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前 ...

  7. 自己的系统重装之后,怎么去重新的装官方的office办公软件,详细教程

    1  访问官网地址--微软,并通过自己的微软账号进行登录,转到下面的界面 2   点击上图的菜单栏的offce菜单项,跳转到下图 3  点击  菜单栏的产品  之后选择  查看office的全部的历史 ...

  8. 关闭Apache的目录浏览功能

    一.默认情况 默认情况下,Apache的配置文件C:\web\apache2.4\conf/httpd.conf中有如下参数: 引用 <Directory "/var/www/html ...

  9. 洛谷P1551 亲戚 (并查集模板题)

    链接 https://www.luogu.org/problemnew/show/P1551 代码 #include<bits/stdc++.h> using namespace std; ...

  10. 模块简介与matplotlib基础

    模块简介与matplotlib基础 1.基本概念 1.1数据分析 对已知的数据进行分析,提取出一些有价值的信息. 1.2数据挖掘 对大量的数据进行分析与挖掘,得到一些未知的,有价值的信息. 1.3数据 ...