移动端为什么要适配,怎么适配?

本文将从以下两个方面去讲解:

1,移动端为什么会有适配的问题

2,怎么解决的

移动端为什么会有适配的问题

不同型号的手机可能它的宽度、高度是不相同的,我们先来看懂这个表格,其中和前端相关的dp和px比较有意义,其他了解就行。

拿iPhone 13 Pro来说,它的对角线是6.1英寸(15.494厘米),横向有1170个栅格(物理像素px),纵向有2532个栅格(一个栅格表示1px),斜对角线上每英寸包含的栅格数是460PPI

它的宽度是2.82英寸,横向每英寸包含的栅格数是1170/2.82=414.89,横向屏幕密度 dpi = 414.89/160=2.59约等于3.0

它的高度是5.4英寸,纵向每英寸包含的栅格数是2532/5.4=468.9,纵向屏幕密度dpi = 468.9/160=2.93约等于3.0

Tips:栅格=物理像素(physical pixel),单位px,不等于css的px

Tips:手机屏幕最小单位是物理硬件栅格,每个手机的栅格大小不一定相同。 一般一个栅格显示一种颜色,比如1170*2532横向可以显示1170个颜色,如果你手动调节降低屏幕分辨率为600*800,系统就会分配给你600*800个有效像素个数,剩余栅格就由系统自作主张,通过一系列运算给你一个模拟色彩块,填充成正好1170*2532个色彩,这样看上去好像就模糊了。

iphone13pro横向有1170个栅格,是不是表示横向屏幕css宽度100%=1170px呢?当然不是。

这里的css像素和物理像素之间还有一个桥梁 ”设备像素比dpr“,它表示1px css像素对应物理上多少个栅格(物理像素)。这个还拿iphone13pro举例,它的dpr是3,所以在UI方面它的css逻辑像素横向宽度=390dp

这个dp就是和我们前端相关的单位!

一般UI设计师给我们的设计稿,宽度都是375px,比如有这样一个设计稿:

如果 你在iphone13pro上写死左右两个div宽度=187.5px,那么右边会多出15px的空白区域,这个就不是顶格适配了,这个就是移动端由于屏幕宽度不同,需要进行适配的原因。

怎么解决的

有两种方案:rem布局和viewport(vw)布局

rem布局

简单讲就是,每个手机屏幕宽度不一样,那我就拿手机屏幕宽度/设计稿宽度,得出来这个比例,然后把设计稿的每个px都乘上这个倍率。

但是你总不能每写一个样式就乘一下倍率,所以想到rem,在根html直接设置font-size=倍率px,然后其他的样式用rem为单位

let pixelRatio= document.documentElement.clientWidth/375(设计稿宽度);

// css文件
html{
   font-size: ${pixelRatio}px
}
div{
  padding: 16rem;
}

这样有个问题,假如pixelRatio是个小数比如1.23,那么就是无效的,因为px最小单位是1。所以我们可以做一个调整:

let pixelRatio= document.documentElement.clientWidth/375(设计稿宽度);

// css文件
html{
   font-size: ${pixelRatio*100}px
}
div{
  padding: (16/100)rem;
}

这样问题就来了,难道我们每次写样式都要做一个除100的计算吗,这样太麻烦了。

这个时候我们就可以借助less的function做一个处理:

$ue-width: 375; /* ue图的宽度 */

@function px2rem($px) {
  @return #{$px/$ue-width*100}rem;
}

p {
  width: px2rem(187);
}

到此为止其实已经解决了问题,但是其实这个别人也想到了,并且已经做成了npm包,我们只要安装npm并且配置一下就可以了:postcss-px2rem   postcss-px2rem-exclude

// postcss.config.js文件
const path = require('path');
module.exports = {
    plugins: [
        require("autoprefixer")(),
        require('postcss-px2rem')({
            remUnit: 75
        }),
        require('cssnano')()
    ]
};

然后项目中元素的宽度直接按照设计稿的宽度来就直接是一致的啦。

vw布局

vw原理就更简单了,100vw=屏幕宽度,直接省略js获取屏幕宽度的步骤了;比如iphone13pro宽度是460px,下面是rem和vw的对比

// rem原理
html{
  font-size: 123px; // (460/375*100)
}

div{
  width: 1.87rem; //  (187/100)
}

// vw原理
div{
  width: 49.87vw; //(187/375*100)
}

但是这么计算也很麻烦,不合适~🙈,所以我们可以继续用别人写好的npm库:postcss-px-to-viewport

具体配置文件,其中的viewportWidth:375是视觉稿的宽度。

'use strict';

module.exports = {
  plugins: [
    require('autoprefixer')(),
    // https://github.com/evrone/postcss-px-to-viewport
      require('postcss-px-to-viewport')({
        viewportWidth: 375, // 视口宽度(数字)
        viewportHeight: 1334, // 视口高度(数字)
        unitPrecision: 3, // 设置的保留小数位数(数字)
        viewportUnit: 'vw', // 设置要转换的单位(字符串)
        fontViewportUnit: 'vw', // 设置字体转换的单位(字符串)
        selectorBlackList: ['.ignore', '.hairlines'], // 不需要进行转换的类名(数组)
        minPixelValue: 1, // 设置要替换的最小像素值(数字)
        mediaQuery: false // 允许在媒体查询中转换px(true/false)
      })
  ]
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值