实战:移动端适配的最佳解决方案

本文详细探讨了移动端适配的各种方法,包括1px问题的解决方案,如媒体查询、transform+伪元素和flexible方案。通过理解设备像素比、viewport等概念,结合CSS的技巧,解决在不同设备上的显示问题。此外,还介绍了图片适配、容器宽高比处理、CSS MODULE的使用以及自动化适配配置,为前端开发者提供全面的移动端适配指南。
摘要由CSDN通过智能技术生成

开局一张图

理解这张图,需要先了解以下几个概念

  • 设备像素: 类似于密度,即每英寸的像素点数量,跟设备有关

  • 设备独立像素: 我们可以理解为css像素,跟设备无关

  • 设备像素比: 就是devicePixelRatio,简称drp,可以通过window.devicePixelRatio获取到当前设备的dpr,我们常说的x 倍屏中的x就是这个dpr

其中设备像素比 = 设备像素 / 设备独立像素

有做过移动端的同学基本是都了解过我们的设计稿一般都是750 * 1334750 * 1334就是以iPhone 6/7/8的尺寸为设计基准,就是上面说到的设备像素

一般在做移动端开发的时候,在浏览器上可以切换成移动设备模式,这个时候可以看到以下信息

这里我们可以看到 设备像素比devicePixelRatio = 设备像素 / 设备独立像素

1px问题

做过前端的开发的,应该基本都有关这样的经历设计稿上的1px渲染之后变粗了, 也都知道写样式时要根据设计稿上的值除以2,然而除以2并不能比较完美的解决问题

iPhone 6(dpr为 2)为例,这是分别设置了 border-bottom: 1px solid #f00; 和 border-bottom: 0.5px solid #f00;的渲染效果,可以看到这个1px比我们想象中的要粗一些,就是因为设备dpr的原因,才导致出现这样的效果

如何解决 1px 问题

一、媒体查询
@mixin border1px($color: #ddd, $direction: 'top') {
  @if $direction == 'all' {
    border: 1PX solid $color;
  } @else {
    border-#{$direction}: 1PX solid $color;
  }
  
  @media (-webkit-min-device-pixel-ratio: 2) {
    @if $direction == 'all' {
      border: 0.5PX solid $color;
    } @else {
      border-#{$direction}: 0.5PX solid $color;
    }
  }
  
  @media (-webkit-min-device-pixel-ratio: 3) {
    @if $direction == 'all' {
      border: 0.333333PXPX solid $color;
    } @else {
      border-#{$direction}: 0.333333PXPX solid $color;
    }
  }
}

还是刚才那两条线,还是那个iPhone 6P,使用了媒体查询之后的渲染

然而这种方式虽然比较简单,但是放在以前的那个时候并不可行,因为0.5px并不是任何设备上都支持的,比如IOS8以下、以及一些安卓系统都不支持,但是对于今天的浏览器来说,基本上是都支持的,目前我们项目中用到的也是这样方案

二、transform + 伪元素

.border-bot-1 {
    width: 100%;
    height: 100px;
    overflow: hidden;
    position: relative;
}
@media (-webkit-min-device-pixel-ratio: 2) {
    .border-bot-1::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        border-top: 1px solid red;
        transform: scaleY(0.5);
        transform-origin: left top;
    }
}
@media (-webkit-min-device-pixel-ratio: 3) {
    .border-bot-1::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        border-top: 1px solid red;
        transform: scaleY(0.333333);
        transform-origin: left top;
    }
}

这种方案可以支持圆角,但是对已经使用伪元素dom需要增加额外的层级嵌套,而且transform会把整个盒子缩放,为了不影响其他的内容,需要单独为了边框增加一层 dom

另外可以用transform来解决12px以下的字体, 一般我们开发的时候,会遇到一些字体在12px以下的情况,但是在浏览器,对字体的渲染最小是12px,当我们需要去设置一个10px的字体时,像这样font-size: 12px;transform: scale(0.8333333);就可以解决了

另外,还有background-image svg等方案,来解决1px问题

三、flexible

在讨论这种方案之前,先来了解以下基本概念:

  • viewportviewport是严格等于浏览器的窗口,在桌面浏览器中,viewport就是浏览器窗口的宽度高度,但在移动端设备上就有点复杂,移动端的viewport太窄,为了能更好为css布局,所以提供了两个viewport:

    • 虚拟的viewportvisualviewport:在不对屏幕进行缩放的前提下,相当于你的手机的可视区域

    • 布局的viewportlayoutviewport&

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值