Skip to content

移动 Web

[TOC]

移动端适配

什么是移动端适配

移动端开发目前主要包括三类:

  • 原生 App 开发(iOS、Android、RN、uniapp、Flutter 等)
  • 小程序开发(原生小程序、uniapp、Taro 等)
  • Web 页面(移动端的 Web 页面,可以使用浏览器或者 webview 浏览)

因为目前移动端设备较多,所以我们需要对其进行一些适配。

自适应:根据不同的设备屏幕大小来自动调整尺寸、大小;

响应式:会随着屏幕的实时变动而自动调整,是一种自适应;

视口(viewport)

在一个浏览器中,我们可以看到的区域就是视口(viewport)。fixed 就是相对于视口来进行定位的

PC 端的页面中,我们是不需要对视口进行区分,因为我们的布局视口和视觉视口是同一个

但在移动端,不太一样,你布局的视口和你可见的视口是不太一样的。这是因为移动端的网页窗口往往比较小,我们可能会希望一个大的网页在移动端可以完整的显示,所以在默认情况下,移动端的布局视口是大于视觉视口的

分类:

  • 布局视口(layout viewport)
  • 视觉视口(visual viewport)
  • 理想视口(ideal viewport)

1、布局视口(layout viewport)

默认情况下,PC 端的网页在移动端会按照宽度为 980px来布局一个页面的盒子和内容。同时为了可以完整的显示在页面中,会对整个页面进行缩小

我们将相对于 980px 布局的这个视口,称之为布局视口布局视口的默认宽度是 980px

image-20230111211853862

2、视觉视口(visual viewport)

显示在可见区域的这个视口,就是视觉视口

image-20230111212013381

3、理想视口(ideal viewport)

当布局视口和视觉视口宽度相等时,就是理想视口

默认情况下的布局视口并不适合我们进行布局,我们可以对布局视口进行宽度和缩放的设置,以满足正常在一个移动端窗口的布局

image-20230111212359760

image-20230111212747025

设置:

html
<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
/>

移动端适配方案

移动端的屏幕尺寸通常是非常繁多的,很多时候我们希望在不同的屏幕尺寸上显示不同的大小

比如我们设置一个 100x100 的盒子

  • 在 375px 的屏幕上显示是 100x100;

  • 在 320px 的屏幕上显示是 90+x90+;

  • 在 414px 的屏幕上显示是 100+x100+

其他尺寸也是类似,如 padding、margin、border、left,甚至是 font-size 等

适配方案:

  • 方案一:百分比
  • 方案二:rem + 动态 html 的 font-size
  • 方案三:vm
  • 方案四:flex 弹性布局

方案-百分比

因为不同属性的百分比值,相对的可能是不同参照物,所以百分比往往很难统一,所以百分比在移动端适配中使用是非常少的,不推荐

方案-rem

思路: rem 单位是相对于 html 元素的 font-size 来设置的,那么如果我们需要在不同的屏幕下有不同的尺寸,可以动态的修改 html 的 font-size 尺寸

一个宽度为 1rem 的盒子在不同屏幕上 html 的 font-size 也不同

image-20230111213406319

在开发中我们需要考虑 2 个问题:

  • 针对不同的屏幕,设置 html 不同的 font-size
  • 将原来要设置的尺寸,转化成 rem 单位

1、rem 的 font-size 尺寸设置

  • 方案一:媒体查询

    通过媒体查询来设置不同尺寸范围内的屏幕 html 的 font-size 尺寸

    css
    /* 媒体查询设置 rem */
    @media screen and (min-width: 320px) {
      + html {
        font-size: 32px;
      }
    }
    @media screen and (min-width: 375px) {
      + html {
        font-size: 37.5px;
      }
    }
    @media screen and (min-width: 414px) {
      + html {
        font-size: 41.4px;
      }
    }

    缺点:

    • 需要针对不同的屏幕编写大量的媒体查询
  • 如果动态改变尺寸,不会实时的进行更新

  • 方案二:JS 监听

    如果希望实时改变屏幕尺寸时,可以通过 js 代码实时更改 font-size

    思路:

    • 根据 html 的宽度计算出 font-size 的大小,并且设置到 html 上
    • 监听页面的实时改变,并且重新设置 font-size 的大小到 html 上
    html
    <div class="box"></div>
    <div>这是一个DIV</div>
    <p>这是一个段落</p>
    
    <script>
      // 设置html的font-size
      const htmlEl = document.documentElement
      function setRemUnit() {
        const htmlWidth = htmlEl.clientWidth
        console.log(htmlWidth)
        htmlEl.style.fontSize = htmlWidth / 10 + 'px'
      }
      setRemUnit()
      window.addEventListener('resize', setRemUnit)
      // 解决历史跳转时的缓存问题导致的不能重新设置font-size的问题
      window.addEventListener('pageshow', function (e) {
        if (e.persisted) setRemUnit()
      })
    
      // 重置body的font-size,解决后代元素rem字体过大的BUG
      document.body.style.fontSize = '16px'
    </script>
  • 方案三:lib-flexible 库

    安装

    sh
    npm i amfe-flexible

    引入

    html
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <script src="./node_modules/amfe-flexible/index.js"></script>

2、rem 的单位换算

  • 方案一:手动换算

    less
    /**
     在375px的标准屏幕上,换算100px的盒子的宽和高为rem单位
     html的font-size: 37.5px
    */
    .box {
      width: 100 / 37.5rem // 2.66667rem
    ;
    }
  • 方案二:less/scss 函数

    以 375px 的设计稿为标准

    css
      @htmlFontSize: 37.5;
    +  .pxToRem(@px) {
    +    result: (@px / @htmlFontSize) * 1rem;
      }
      .box {
    +    width: .pxToRem(100)[result]; // 6.25rem
    +    height: .pxToRem(50)[result]; // 3.125rem
        background-color: orange;
      }
  • 方案三:postcss-pxtorem(后续学习)

    在前端的工程化开发中,我们可以借助于 webpack 的工具来完成自动的转化

  • 方案四:VSCode 插件

    插件:px to rem & rpx & vw(cssrem)

    设置:以 750px 的设计稿为标准

    image-20230112103416268

方案-vw

使用 vw 设置 html 的 font-size

image-20230112100228608

1、vw 和 rem 的对比

在开发中我们只要考虑 1 个问题:

  • image-20230112102026194

2、vw 的单位换算

  • 方案一:手动换算

  • 方案二:less / scss 函数

    image-20230112103248557
  • 方案三:postcss-px-to-viewport-8-plugin(后续学习)

  • 方案四:VSCode 插件

    插件:px to rem & rpx & vw(cssrem)

    设置:以 375px 的设计稿为标准

    image-20230112103450505

image-20230111155117125

image-20230111155128185

image-20230111155135537

image-20230111155142756

方案-flex 弹性布局

认识 Flex 布局

Flex 布局是一种按行或列布局元素的一维布局方法

解决的痛点

  • 垂直居中
  • 等分宽高
  • 多列不等高想占等高的位置

API

  • 容器 container

  • display: flex | inline-flex。弹性盒子

  • flex-direction: row | row-reverse | column | column-reverse | unset。调整主轴方向

  • flex-wrap: wrap | nowrap | wrap-reverse。控制是否换行

  • flex-flow: 简写:flex-direction + flex-wrap

  • justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly。调整主轴对齐

  • align-items: flex-start | flex-end | center | baseline | normal | stretch。调整交叉轴对齐

  • align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch。堆栈(由 flex-wrap 产生的独立行)多行垂直对齐方式

  • 子元素 items

  • flex-grow: <非负数>,默认 0。设置 flex 项主轴尺寸的 flex 增长系数

  • flex-shrink: <非负数>,默认 1。指定了 flex 元素的收缩规则

  • flex-basis: auto | <宽度 px>。指定了 flex 元素在主轴方向上的初始大小

  • flex: 缩写:flex-grow | flex-shrink | flex-basis | none | auto

  • order: number。控制子项目的排列顺序,正序方式排序,从小到大

  • align-self: flex-start | flex-end | center | baseline | stretch | auto 。对齐当前元素,并覆盖已有的 align-items 的值

Flex 布局的模型

image-20221107223208141

概念:

  • main start / main end: 主轴开始 / 结束
  • cross start / cross end: 交叉轴开始 / 结束
  • main size/ cross size: 主轴 / 交叉轴尺寸
  • flex container: flex 容器
  • flex item: flex 元素

item 最终 size 的决定因素

优先级:从高到低

  • 1、max-width / max-height / min-width / min-height
  • 2、flex-basis
  • 3、width / height
  • 4、内容本身的 size

Flex 布局常见问题

问题: Flex 布局中设置 justify-content 后最后一行不对齐,如图:

image-20221107224806555

解决: 在 items 最后加上最少 列数 - 2 个 span,span 设置如下

image-20221107225226027

grid 布局

image-20230112104228923

image-20230112105226251

image-20230112105405912

学习网址:

image-20230112105527331

项目:考拉海购

image-20230112110411373

index 页

head 设置

image-20230112110859554

reset.less 重置

image-20230112111334282

image-20230112111400177

目录结构

image-20230112113451292

导航(tabbar)

image-20230112115033743

首页(home)

1、下载 app(.download)

image-20230112115353039

border-bottom: 要被右边的盒子盖上

border-bottom: 1px solid #e3e3e3

image-20230112123442999

2、硬核补贴(.subsidy)

image-20230112141601131

3、分类(.category)

image-20230112141714193

4、商品列表(.product)

5、商品列表(.item)

分类(category)

购物车(cart)

我的考拉(profile)

image-20230111155108851