文章目录
前言
随着前端技术的不断发展,移动端的需求不断增大,只适配pc端的界面已经无法满足用户的需求了。pc端的适配一般用CSS3 多媒体查询去适配几个阶段(如1600px,1920px)的像素就好了,这篇文章就不重点讲了,wap手机端就有点不一样了,那么要怎么去适配wap手机端的界面呢?
小提示
测试像素大小时不建议使用谷歌浏览器来测试,因为Chrome有最小字体的限制,如果字体小于12px,它会默认显示成12px,所以可以使用Firefox火狐浏览器、Edge白给不要浏览器来测试。
提示:以下是本篇文章正文内容,下面案例可供参考
一、rem是什么?
在实现页面的自适应之前我们需要搞懂一个像素单位,那就是rem。对于rem,从网上找的专业术语大都是:
rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem大家一定会想起em单位,em(font size of the element)是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。
看完之后我相信很多小伙伴依旧是没搞懂,我当初入行时也是看得一脸懵的,做过项目后才理解的。实验是验证猜想的唯一的有效方法,接下来我会做个小实验,让大家更好的去理解rem,另外em的话不重点讲,因为用不上。
1.weianl的小实验
既然rem是根据根元素换算的,换句话的意思是真实的大小是根据html元素定义的字体成倍换算出来的,即如果在html根节点设置字体为20px
,那么1rem
就应该等于1x20=20px
;2rem
就等于2x20=40px
。为了验证这句话,我们看一下下面这段代码,我们先在html设置字体为20px
,紧接着设置一个标题,大小是1rem
,接着设置了一个盒子,宽是1rem
,高是2rem
,不出意料的话标题的实际大小应该是20px
,盒子的长和宽应该是20px
、40px
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>weianl的实验室</title>
</head>
<style>
html {
font-size: 20px;
}
body {
margin: 0;
padding: 0;
}
.title {
font-size: 1rem;
}
.box {
width: 1rem;
height: 2rem;
background-color: pink;
}
</style>
<body>
<div class="title">hello rem !!!</div>
<div class="box"></div>
</body>
</html>
从下面的图中浏览器显示来看,确实验证了上面的思路。
![]() | ![]() |
到了这里,我相信各位小伙伴对rem已经有了一个直观的理解,那么有些小伙伴会问,这和适配有啥关系咧?
二、为什么做移动端要使用rem?
1.使用rem前
当html根元素的字体发生变化时,不会影响到子节点(html里面的<div>、<p>、<img>
啥的)的像素大小。
2.使用rem后
当html根元素的字体发生变化时,会影响到子节点的像素大小。
到了这里,我相信有些小伙伴已经知道适配页面的原理了,是的,只要我们动态的去更改html根节点的字体大小,是不是就可以动态的去适配不同比例的手机了呢?
三、用CSS适配
接着上面的问题,要动态的去更改html根节点的字体大小,我想做过一点pc网站的小伙伴都应该会想到,没错,就是CSS3 多媒体查询,是的然后就出现了下面这种代码:
@media screen and (min-width: 320px) {
html {font-size: 14px;}
}
@media screen and (min-width: 360px) {
html {font-size: 16px;}
}
@media screen and (min-width: 400px) {
html {font-size: 18px;}
}
@media screen and (min-width: 440px) {
html {font-size: 20px;}
}
@media screen and (min-width: 480px) {
html {font-size: 22px;}
}
@media screen and (min-width: 640px) {
html {font-size: 28px;}
}
加了这段代码后,在后续开发中全部以rem为单位确实可以达到适配的效果,但是当你拿到设计稿时,你会懵逼,要怎么1:1还原设计稿呢?于是为了解决这个问题,我就找了一下rem与px的转换,然后很多文章都会告诉你下面这段代码:
html{
font-size: 62.5%;
}
这段代码的意思是浏览器默认字体是16px,通过计算 16x62.5%=10px
;之后就有了1rem=10px
,这样就可以以1:10的方式对照设计稿了。这句话看起来没问题,但是有个问题,用rem的目的就是要做响应式,要做响应式就必须动态设置html节点的字体大写,如果通过上面的@media设置字体后,必然会把font-size: 62.5%;
覆盖掉,不科学。于是我又从其他文章看到了下面这段代码:
body{
font-size: 62.5%;
}
然而依旧并没有什么卵用,因为rem只会继承html节点的像素,在body节点设置font-size并不会影响后续子节点的像素,只有em单位才会有这种继承父节点的情况,但是这种一层一层的继承父节点计算起来是相当复杂的,这就是不用em做响应式的原因,具体看下图:
经过上边一系列的操作,我可以说是
用css来做适配了。
嗯呵,不好意思飘了。回到正题,在我接触到React框架的Demo时,我发现它没有用@media
但是它确是响应式的,最后我发现多了这么一句font-size: calc(10px + 2vmin);
,这时我才发现还可以这么玩
于是便有了下面这段代码:
html {
/* 根据自己的设计稿自行调整,7.5就是750px的设计稿,屏幕宽度为750px时1rem=100px */
font-size: calc(100vw/7.5);
}
那么这段代码是什么意思呢?以设计稿750px为例,这里100vw是指当屏幕宽度为750px时,除以7.5刚好就等于100px,此时就可以以1rem=100px的方式来对照设计稿了,具体我们看一下效果:
整个html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>weianl的实验室</title>
</head>
<style>
html {
/* 根据自己的设计稿自行调整,7.5就是750px的设计稿,屏幕宽度为750px时1rem=100px */
font-size: calc(100vw/7.5);
}
body {
margin: 0;
padding: 0;
}
.title {
font-size: 1rem;
}
.box {
width: 1rem;
height: 2rem;
background-color: pink;
}
</style>
<body>
<div class="title">hello rem !!!</div>
<div class="box"></div>
</body>
</html>
但是需要注意一下,如果你要用到项目上话,需要看一下你的项目是否合适,因为calc()函数
是CSS3的,如果你的项目要兼容什么IE6+
什么的就不要考虑了。另外,一般pc版网站是不需要做响应式的,所以在初始化项目时可以在html头部加入下面这两行代码,意思就是当页面宽度小于768px(iPad的尺寸),此时认定为wap手机端,这时用一套css样式代码,里边以rem为单位,当页面宽度大于768px时,此时认定为pc端,用另外一套代码,里边以px为单位,这样就可以动态的在手机端和电脑端来回切换样式了。
<!-- pc,以px为单位 -->
<link rel="stylesheet" type="text/css" href="./css/index.css" media="(min-width:768px)">
<!-- wap,以rem为单位 -->
<link rel="stylesheet" type="text/css" href="./css/index-wap.css" media="(max-width:768px)">
提示:其实讲了这么多,不就是为了拥抱js嘛,好了进入真正的正文
四、用JavaScript适配
首先大家要知道的一点是每个公司都有自己的规范,文章下面是以我公司的规范来编写的,我的公司编写的网站大致分成两种,分别是响应式和非响应式的网页;设计稿的话会有两套psd,一套是手机端的750px,另一套是电脑端1920px。
1.非响应式
我司的非响应式指的是pc端和手机端都有自己的html、css,当进入网站时,先进入pc版的html,接着会优先在<head>
标签里面用js判断设备是电脑的还是手机的,如果是手机的会重定向直接跳转手机端的html,相反亦然。另外,手机端会通过js动态的设定html根节点的像素大小。具体样子看下面的GIF:
代码部分:
先看下我这项目的目录结构
先在pc端的<head>
标签中加入下面就是判断是否需要重定向切换对应的html,然后自己新建一个pc端的css文件,以px为单位。
<head>
<script>
function browserRedirect() {
var sUserAgent = navigator.userAgent.toLowerCase();
var bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
var bIsMidp = sUserAgent.match(/midp/i) == "midp";
var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
var bIsAndroid = sUserAgent.match(/android/i) == "android";
var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) {
// console.log(移动端)
window.location.href = './wap/index.html'
} else {
// console.log(PC端)
}
}
browserRedirect();
</script>
<!-- 以px为单位 -->
<link rel="stylesheet" href="./css/index.css">
</head>
接着在wap端用同样的操作,先在<head>
标签中判断是否需要重定向,然后自己新建一个wap端的css文件,以rem为单位。最后就是用js根据窗口的宽度来动态的设置html根节点的像素了,具体看代码注释:
<head>
<script>
function browserRedirect() {
var sUserAgent = navigator.userAgent.toLowerCase();
var bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
var bIsMidp = sUserAgent.match(/midp/i) == "midp";
var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
var bIsAndroid = sUserAgent.match(/android/i) == "android";
var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) {
// console.log(移动端)
} else {
// console.log(PC端)
window.location.href = '../index.html'
}
}
browserRedirect();
//封装响应式像素方法,初始化单位,实现手机端1rem=100px
function responsivePX() {
//获取页面的宽度
var deviceWidth = document.documentElement.clientWidth;
// console.log(deviceWidth)
//如果页面大于750,即px端的页面,则把html的像素锁死在100px
if (deviceWidth > 750) deviceWidth = 750;
document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px';
}
// 第一次初始化像素大小
responsivePX();
window.onresize = function() {
// 监听窗口二次刷新像素大小
responsivePX();
};
</script>
<!-- 以rem为单位 -->
<link rel="stylesheet" href="../css/index-wap.css">
</head>
2.响应式
我司的响应式指的是pc端和手机端的html用的是同一个文件,只不过会根据窗口的宽度来动态的切换css样式,具体样子看下面的GIF:
代码部分:
先看下我这项目的目录结构
接着html部分的因为是共用同一个html,所以省去了pc端与wap端切换的逻辑,动态设置像素的逻辑是一样的,只不过在引入css时会用media
来切换pc端和wap端的样式,具体看代码:
<head>
<!-- pc,以px为单位 -->
<link rel="stylesheet" type="text/css" href="./css/index.css" media="(min-width:768px)">
<!-- wap,以rem为单位 -->
<link rel="stylesheet" type="text/css" href="./css/index-wap.css" media="(max-width:768px)">
<script>
//封装响应式像素方法,初始化单位,实现手机端1rem=100px
function responsivePX() {
//获取页面的宽度
var deviceWidth = document.documentElement.clientWidth;
// console.log(deviceWidth)
//如果页面大于750,即px端的页面,则把html的像素锁死在100px
if (deviceWidth > 750) deviceWidth = 750;
document.documentElement.style.fontSize = deviceWidth / 7.5 + 'px';
}
// 第一次初始化像素大小
responsivePX();
window.onresize = function() {
// 监听窗口二次刷新像素大小
responsivePX();
};
</script>
</head>
提示:不管是非响应式还是响应式,图片都是有两套的。
其他
另外如果有小伙伴想要原项目的话可以用积分下载,我就不放到百度网盘了,因为这是以前给公司做的项目,不是特别想拿出来。
前端非响应式网站模板==》传送门
前端响应式网站模板==》传送门
好吧,不装了,摊牌了,其实我是来骗积分的~~
总结
要适配wap手机端的界面的话,css需要以rem为单位,然后用css或js动态的去调整html根节点的像素大小就好了。
最后别忘了点赞哦