虽然我们课程明确的区分各种移动端适配方案,但依然有很多同学搞不清楚移动端等比适配和响应式,这里对移动端主流适配方案给大家做一个分析。
移动端适配是指同一个页面可以在不同的移动端设备上都有合理的布局。主流的实现方案有两种:
- 响应式布局,通过@media实现一套html配合多套css实现适配;
- 通过rem或者vw,vh等实现不同的设备俺照相同的比例适配;
例子
这里给大家列举几个例子:
- 小米移动端商城,很明显是采用了rem等比适配的方案。
2. 不凡官网,采用了@media媒体监听实现适配。
3. 王者荣耀,同时采用了媒体监听和rem等比适配。
4. vh,vm 暂时没找到。
实现原理
首先需要了解一个概念:viewport
视口(mdn)。如果要实现浏览器适配移动端,首先我们要统一标准视口。在html的head中添加以下代码:
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no">
第一种:rem实现原理
rem是一个倍数单位,它是基于html的font-size的倍数。只要我们在不同的设备上设置一个合适的初始值,当设备发生变化font-size就会自动等比适配大小,从而在不同的设备上表现统一。
比如说:移动端设计稿一般会以750px进行交付,而手机实际像素可能是375px。那么一般我们会以设备宽度的1/10作为初试html的font-size大小,当然这个值是动态的,在不同设备上得到的值不同。
比如有的设备宽度是375px,那么html初始font-size就是37.5px,如果设备宽度是300px,那么font-size就是30px。 因为内容都是rem基于font-size的倍数,所以不同宽度的设备上都是等比显示的。
注意:这个font-size基数到底是不是设备的1/10是没有统一论调的,你可以用1/n任意定义。关键是理解rem适配的原理是元素等比缩放
。
参照具体代码:
<!DOCTYPE html>
<!-- 0. 注意:font-size是动态设置,宽度为屏幕1/10 -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 1. 标准视口,禁止缩放,初始缩放为1 -->
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no">
<title>移动视口</title>
<style>
*{
margin: 0;
padding: 0;
}
.box{
/* 4. 如果原稿宽度是750px,而且在750宽度的设备上开发。则375px应该还是375px。
基础font-size为75px,则这里换算成rem应该是5rem */
/*
想必你不一定能理解。试想如果在375宽度的设备上开发。这里的5rem是不是应该为37.5的5倍?
37.5*5=187.5刚好为375的1/2呢?
*/
width: 5rem;
height: 5rem;
background-color: green;
}
</style>
</head>
<body>
<!-- 2. 假设一个750px宽度的设计稿,给了一个375px的元素块。 -->
<!-- 我们的实现应该是一个盒子在不同宽度的设备上都应该表现一致(占比屏幕宽度的1/2)。
因为屏幕宽度不一定,通过px显然无法实现,那么我们就需要使用rem来做等比缩放。 -->
<!-- 一个简单的例子: -->
<div class="box"></div>
<script>
// 3. 这里通过js监听屏幕尺寸 设置html的font-size
function setView(){
document.documentElement.style.fontSize = screen.width/10 + 'px';
}
setView();
// 这里是为什么?你自己想一想
window.onresize = setView;
</script>
</body>
</html>
至于px如何转换为rem,在vscode中可以搜索相关插件。
第二种: 媒体监听
媒体监听通过@media实现。注意:媒体监听不是等比缩放!!!是同一块内容在不同设备上有合理的表现。
比如在PC端一行能同时展示4个元素块,而在移动端只能一行展示1个或者2个元素块(要不看不清)。
那么就可以通过监听媒体宽度,给元素设置不同的宽度,从而有合理的表现。
代码参考:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 1. 标准视口,禁止缩放,初始缩放为1 -->
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, user-scalable=no">
<title>媒体监听适配</title>
<style>
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
.header{
width: 100%;
height: 100px;
background-color: pink;
}
.header .header-c{
width: 1200px;
height: 100px;
background-color: green;
margin: 0 auto;
}
.header .nav{
/* width: xx */
height: 100%;
}
.header .nav .nav-item{
float: left;
width: 100px;
height: 100%;
line-height: 100px;
text-align: center;
cursor: pointer;
}
/* 3. 针对适配的设备重新写一套样式 */
@media screen and (max-width: 750px){
.header{
position: relative;
height: 40px;
}
.header .header-c{
width: 100%;
}
.header .nav{
position: absolute;
width: 100%;
left: 0;
top: 40px;
}
.header .nav .nav-item{
float: none;
width: 100%;
height: 40px;
background-color: pink;
border-bottom: 1px solid gray;
line-height: 40px;
}
}
</style>
</head>
<body>
<!-- 2. 要明确媒体监听实现的不是等比缩放!!!而是同一个内容在不同设备上都有合理的表现。 -->
<!-- 比如一个导航 -->
<div class="header">
<div class="header-c">
<ul class="nav">
<li class="nav-item">首页</li>
<li class="nav-item">分类</li>
<li class="nav-item">发现</li>
<li class="nav-item">我的</li>
</ul>
</div>
</div>
</body>
</html>
第三种: vw/vh方案
vw 是相对单位,1vw 表示屏幕宽度的 1%。需要缩放的元素采用vw,不需要的采用px。
具体实现方法与rem类似,至于转换问题也可以参考rem的插件形式。
各种方案对比
rem方案:
- 原理不好理解^_^
- 从px到rem的转换需要使用工具
- 灵活可控,几乎完美复刻设计稿
- 可能大量出现小数点,由于换算有些许误差(极小)
- 适合具有完全移动端设计稿的项目
media媒体监听方案:
- 没有学习成本
- 如何适配需要重新定义,可能设计稿都不会体现
- 复杂的组件很难有完美的呈现
- 适合只有PC端设计稿,又需要兼容移动端的需求
综合方案:
- 可以同时使用media和rem
- 实现更大的自由度和更完美的呈现
- 实现复杂,颗粒度不好把控
这里总结了两种常用的移动端适配方案。其实后来的微信小程序css单位rpx,换算方法为1px=2rpx,应该和rem的适配方案原理大致相同。
附件
代码仓库: https://gitee.com/bufanxy/learnjs-troublemaker
声明:不凡君原创不易,转载请说明出处。