文章目录
- 怎么做移动端的样式适配?
- 1、方案选择
- 2. iPhoneX 适配方案
怎么做移动端的样式适配?
在移动端虽然整体来说大部分浏览器内核都是 webkit,而且大部分都支持 css3 的所有语法。但手机屏幕尺寸不一样,分辨率不一样,或者有时需要考虑横竖屏的问题,或者考虑到各式各样的移动端兼容性问题。
1、方案选择
1、使用 css 的媒体查询 @media
基于 css 的媒体查询属性 @media 分别为不同屏幕尺寸的移动设备编写不同尺寸的 css 属性,示例如下所示。虽然此方法能在一定程度上解决移动设备适配的问题,但我们也可以看出其存在以下问题,所以其已几乎被历史潮流淘汰。
页面上所有的元素都得在不同的 @media 中定义一遍不同的尺寸,这个代价有点高;
如果再多一种屏幕尺寸,就得多写一个 @media 查询块;
@media only screen and (min-width: 375px) {
.logo {
width : 62.5px;
}
}
@media only screen and (min-width: 360px) {
.logo {
width : 60px;
}
}
@media only screen and (min-width: 320px) {
.logo {
width : 53.3333px;
}
}
2、使用 rem 单位
rem(font size of the root element)是指相对于根元素的字体大小的单位,如果我们设置 html 的 font-size 为 16px,则如果需要设置元素字体大小为 16px,则写为 1rem。但是其还是必须得借助 @media 属性来为不同大小的设备设置不同的 font-size,相对上一种方案,可以减少重复编写相同属性的代价,简单示例如下所示。
我们也能看到该方案存在以下问题:
不同的尺寸需要写多个 @media;
所有涉及到使用 rem 的地方,全部都需要调用方法 calc() ,这个也挺麻烦的;
@media only screen and (min-width: 375px) {
html {
font-size : 375px;
}
}
@media only screen and (min-width: 360px) {
html {
font-size : 360px;
}
}
@media only screen and (min-width: 320px) {
html {
font-size : 320px;
}
}
//定义方法:calc
@function calc($val){
@return $val / 1080;
}
.logo{
width : calc(180rem);
}
3、flexible 适配方案
1、 使用 rem 模拟 vw 特性适配多种屏幕尺寸
它的核心代码如下所示
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit();
.2、控制 viewport 的 width 和 scale 值适配高倍屏显示
设置 viewport 的 width 为 device-width,改变浏览器 viewport(布局视口和视觉视口)的默认宽度为理想视口宽度,从而使得用户可以在理想视口内看到完整的布局视口的内容。
等比设置 viewport 的 initial-scale、maximum-scale、minimum-scale 的值,从而实现 1 物理像素=1 css像素,以适配高倍屏的显示效果
var metaEL= doc.querySelector('meta[name="viewport"]');
var dpr = window.devicePixelRatio;
var scale = 1 / dpr
metaEl.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
4、viewport 适配方案
vw 作为布局单位,从底层根本上解决了不同尺寸屏幕的适配问题,因为每个屏幕的百分比是固定的、可预测、可控制的。 viewport 相关概念如下:
- vw:是 viewport’s width 的简写,1vw 等于 window.innerWidth 的 1%;
- vh:和 vw 类似,是 viewport’s height 的简写,1vh 等于 window.innerHeihgt 的 1%;
- vmin:vmin 的值是当前 vw 和 vh 中较小的值;
- vmax:vmax 的值是当前 vw 和 vh 中较大的值;
若视觉稿宽度为 750px,视觉稿中某个字体大小为 75px,则我们的 css 属性只要如下这么写,不需要额外的去用 js 进行设置,也不需要去缩放屏幕等;
.logo {
font-size: 10vw; // 1vw = 750px * 1% = 7.5px
}
1、设置 meta 标签
在 html 头部设置 mata 标签如下所示,让当前 viewport 的宽度等于设备的宽度,同时不允许用户手动缩放。
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
2、px 自动转换为 vw
设计师一般给宽度大小为 375px 或 750px 的视觉稿,若采用 vw 方案的话,需要将对应的元素大小单位 px 转换为 vw 单位(需要手动计算将 px 转换为 vw)且不利于后续代码维护
安装 postcss-px-to-viewport 插件,来将 px 自动转换为 vw
npm install postcss-px-to-viewport --save-dev
2. iPhoneX 适配方案
安全区域指的是一个可视窗口范围,处于安全区域的内容不受圆角(corners)、齐刘海(sensor housing)、小黑条(Home Indicator)影响,如下图蓝色区域:
适配步骤
-
设置网页在可视窗口的布局方式
新增 viweport-fit 属性,使得页面内容完全覆盖整个窗口,只有设置了 viewport-fit=cover,才能使用 env()
<meta name="viewport" content="width=device-width, viewport-fit=cover">
-
fixed 完全吸底元素场景的适配
-
可以通过加内边距 padding 扩展高度:
{
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
或者通过计算函数 calc 覆盖原来高度:
{
height: calc(60px(假设值) + constant(safe-area-inset-bottom));
height: calc(60px(假设值) + env(safe-area-inset-bottom));
}
- fixed 非完全吸底元素场景的适配
像这种只是位置需要对应向上调整,可以仅通过下外边距 margin-bottom 来处理
{
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
}
或者,你也可以通过计算函数 calc 覆盖原来 bottom 值:
{
bottom: calc(50px(假设值) + constant(safe-area-inset-bottom));
bottom: calc(50px(假设值) + env(safe-area-inset-bottom));
}