移动端布局和适配解决方案全解

610 阅读1分钟

常用布局

  • 固定宽度布局( PC端常用)
  • 流体布局(百分比布局% )
  • rem和vw布局
  • 响应式布局
  • Flex弹性布局(工具)
  • Grid网格布局(工具)

Flex弹性布局

Grid布局

响应式布局

流体布局

  • 主要使用%单位布局
  • 不是只能使用%单位布局,也可以使用其它单位,比如px
  • 图片一般只设置宽度或高度之一, 这样可以等比例缩放,不失真

案例

rem布局方案

rem 相对的是根元素的字体大小

rem适配的原理:编写样式时统一使用rem为单位,在不同设备上动态调整根字体大小

viewWidth / 750px = ? / 10px

? = viewWidth * 10px / 750px

viewWidth是视口宽度 750px是设计稿宽度 ?是html标签字体大小

  1. 通过js设置根字体大小 = *( 当前设备横向独立像素值 100) / 设计稿宽度
  2. 编写样式时,直接以rem为单位,值为:设计值 / 100
  3. 增加 JS 代码进行实时适配

image-20210706001420875

image-20211230174106603

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>rem 布局方案</title>
    <style>
      img {
        width: 100%;
      }
      .tabbar-layout {
        position: fixed;
        bottom: 0;
        left: 0;
        box-shadow: 0 -4px 4px rgba(0, 0, 0, 0.15);

        /* width: 100%;
        height: 48px; */

        /* width: 750px;
        height: 96px; */

        /* width: 750rem;
        height: 96rem; */

        width: 75rem;
        height: 9.6rem;
      }
    </style>
    <style>
      html {
        /* 不用担心字体过大或过小,这里只是用来计算,不用来显示 */
        /* font-size: 10px; */
      }
    </style>
    <script>
      // 1.原理
      // 750px / 96px

      // 宽高比不变
      //  75rem / 9.6rem
      // 宽和高可以随着屏幕大小的变化而变化
      //   当屏幕变化的时候修改 html 的字体大小

      // 1rem = html 字体大小
      // 设 1rem = 10px
		
      // viewWidth / 750px = ? / 10px
      // ? = viewWidth * 10px / 750px = viewWidth / 75

      // 2.实现
      {
        const docEl = document.documentElement;

        const setHtmlFontSize = () => {
          const viewWidth = docEl.clientWidth;

          docEl.style.fontSize = `${viewWidth / 75}px`;
        };

        setHtmlFontSize();
        window.addEventListener("resize", setHtmlFontSize, false);
      }

      // 安装 px2rem 插件,修改配置后需重启编辑器生效

      // 3.扩展 flexible
      // https://github.com/amfe/lib-flexible
      // 解决了 1px 边框问题
    </script>
  </head>
  <body>
    <div class="tabbar-layout">
      <img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f6bc3056b99c4955893ddac8fbb1cd54~tplv-k3u1fbpfcp-zoom-1.image" alt="标签栏" />
    </div>
  </body>
</html>

tabbar

vw布局方案

vw和vh是两个相对单位

  • 1vw = 等于布局视口宽度的1%
  • 1vh = 等于布局视口高度的1%

不过vw和vh有一定的兼容性问题:详见:这里

image-20211230175310420

测量px / 750px = ?vw / 100vw

?vw =测量px * 100vw / 750px

750px是设计稿宽度 测量px是从设计稿上测量的值 ?vw是html标签字体大小

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vw 布局方案</title>
    <style>
      img {
        width: 100%;
      }
      .tabbar-layout {
        position: fixed;
        bottom: 0;
        left: 0;
        box-shadow: 0 -4px 4px rgba(0, 0, 0, 0.15);

        /* width: 100%;
        height: 48px; */

        /* width: 750px;
        height: 96px; */

        /* width: 100vw;
        height: 12.8vw; */

        width: 100vw;
        /* width: 100%; */
        height: 12.8vw;
      }
    </style>
  </head>
  <body>
    <div class="tabbar-layout"><img src="./tabbar.png" alt="标签栏" /></div>
  </body>

  <script>
    // 1.原理
    // 计算出测量的值对应的 vw 单位的值

    // 测量 px / 750px = ?vw / 100vw
    // ?vw = 100vw * 测量px / 750px

    // 1rem = 10px
    // 75rem 9.6rem

    // px2vw 插件

    // 优先使用 vw 布局方案,如果条件不允许(比如浏览器不兼容 vw),再选择 rem 方案
    // 修改历史项目的时候,如果该项目使用的是 rem 布局,可以使用 vw + rem 方案修改
  </script>
</html>

vw + rem 布局方案

viewWidth / 750px = ?px / 10px

100vw / 750px = ?vw / 10px

?vw = 10px * 100vw / 750px

viewWidth是视口宽度等于100vw 750px是设计稿宽度 ?vw是html标签字体大小

  • html的字体大小使用vw单位

image-20211230174619336

  • 需要等比例缩放的使用rem单位

image-20211230174639371

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>vw + rem 布局方案</title>
    <style>
      img {
        width: 100%;
      }
      .tabbar-layout {
        position: fixed;
        bottom: 0;
        left: 0;
        box-shadow: 0 -4px 4px rgba(0, 0, 0, 0.15);

        /* width: 750px;
          height: 96px; */

        width: 75rem;
        height: 9.6rem;
      }
    </style>
    <style>
      /* 1.原理 */
      /* viewWidth / 750px = ?px / 10px */
      /* 100vw / 750px = ?vw / 10px */
      /* ?vw = 10px * 100vw / 750px */
		 /* ?vw = 1000vw / 750 */
      /* 2.实现 */
      html {
        /* font-size: 10px; */
        /* font-size: 10vw; */

        /* 10px * 100vw / 750px */
        font-size: 1.333333vw;
      }
    </style>
    <script>
      // {
      //   const docEl = document.documentElement;

      //   const setHtmlFontSize = () => {
      //     const viewWidth = docEl.clientWidth;
 
      //     docEl.style.fontSize = `${viewWidth / 75}px`;
      //   };

      //   setHtmlFontSize();
      //   window.addEventListener('resize', setHtmlFontSize, false);
      // }
    </script>
  </head>
  <body>
    <div class="tabbar-layout">
      <img src="./tabbar.png" alt="标签栏" />
    </div>
  </body>
</html>

rem 和 vw 布局实战