从原理到方案,一步步讲解web移动端实现自适应等比缩放
前言
在移动端做自适应,我们常用的有媒体查询,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移动端实现自适应等比缩放的更多相关文章
- web移动端适配方案
web移动端常用解决方案: 一.通过js+rem,这里有一个解决方案(http://imochen.github.io/hotcss/) 1.1.rem兼容性(https://caniuse.com) ...
- 空间变换网络(STN)原理+2D图像空间变换+齐次坐标系讲解
空间变换网络(STN)原理+2D图像空间变换+齐次坐标系讲解 2018年11月14日 17:05:41 Rosemary_tu 阅读数 1295更多 分类专栏: 计算机视觉 版权声明:本文为博主原 ...
- 关于如何提高Web服务端并发效率的异步编程技术
最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...
- web移动端性能调优及16ms优化
本文只是一个索引,收集了网络上大部分关于调试及优化方面的文章,从中挑选了一些比较好的文章分享给大家. 移动端性能不及桌面浏览器性能的10分之1,特别是在android设备良莠不齐的情况下,性能显得尤为 ...
- 如何提高Web服务端并发效率的异步编程技术
作为一名web工程师都希望自己做的web应用能被越来越多的人使用,如果我们所做的web应用随着用户的增多而宕机了,那么越来越多的人就会变得越来越少了,为了让我们的web应用能有更多人使用,我们就得提升 ...
- 【转载】Web移动端Fixed布局的解决方案
特别声明:本文转载于EFE的<Web移动端Fixed布局的解决方案>.如需转载,烦请注明原文出处:http://efe.baidu.com/blog/mobile-fixed-layout ...
- iOS 【终极方案】精准获取webView内容高度,自适应高度
前言:是这样的,刚写完上一篇文章还没缓过神来,上一篇文章我还提到了,想和大家聊聊原生+H5如何无缝连接的故事.结果我朋友就给我发了两篇他的作品.他的做法也都有独到之处.好的文章都是这样,让你每次看都能 ...
- IOS开发系列之阿堂教程:玩转IPhone客户端和Web服务端交互(客户端)实践
说到ios的应用开发,我们不能不提到web server服务端,如果没有服务端的支持,ios应用开发就没有多大意义了,因为从事过手机开发的朋友都知道(Android也一样),大量复杂业务的处理和数据库 ...
- web服务端的架构演变
此文已由作者肖凡授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 最近Lofter项目碰到很多性能上的问题,特别是数据库相关的,每次推送后,告警就会第一时间到来.这些问题随着产 ...
随机推荐
- selenium实现网易邮箱的登录注册
#实现163网站的注册 from selenium import webdriver import time driver = webdriver.Chrome() url = 'https://ma ...
- java控制台模式控制光标及字符颜色
System.out.println("\033[47;31mhello world\033[5m"); 47是字背景颜色, 31是字体的颜色, hello world是字符串. ...
- 关于 DP 的一些内容
0.关于 动态规划是编程解题的一种重要手段.1951 年美国数学家 R.Bellman 等人,根据一类多阶段问题的特点,把多阶段决策问题变换为一系列互相联系的单阶段问题,然后逐个加以解 ...
- 【sklearn朴素贝叶斯算法】高斯分布/多项式/伯努利贝叶斯算法以及代码实例
朴素贝叶斯 朴素贝叶斯方法是一组基于贝叶斯定理的监督学习算法,其"朴素"假设是:给定类别变量的每一对特征之间条件独立.贝叶斯定理描述了如下关系: 给定类别变量\(y\)以及属性值向 ...
- BLOB-数据库中用来存储二进制文件的字段类型
BLOB (binary large object)----二进制大对象,是一个可以存储二进制文件的容器. 在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型. BLOB是一个大文件,典型 ...
- Vue图片验证码-自定义组件高级版
最近项目中要用到图片验证码,网上一查有很多,基本都是千篇一律的4位纯数字验证码.首先得感谢那位一代目兄台提供的模板,由于不能满足需求,所以对其进行了改造升级. 经改造的图片验证码能满足一下情形使用:① ...
- 安装 browsercookie 模块详细步骤
在安装browsercookie时遇到了不少问题,现在终于解决了,把方法分享下,希望能帮大家节约点时间 到此网址上下载压缩包: https://pypi.org/project/browsercook ...
- PHP版常用算法
PHP版常用算法最近准备面试的资料,顺便整理一下以前的基本算法,写个DEMO记录一下 //冒泡//逐行对比,满足条件则交换function bubbleSort($arrData,$sort = 'd ...
- Redis初级安装及使用
env:ubuntu 19.04 redis官网: redis.io 安装步骤: 1.wget http://download.redis.io/releases/redis-5.0.7.tar.gz ...
- java回文代码
import java.util.*; import java.math.BigInteger; import java.util.Scanner; public class Test{ static ...