前端架构师之路02_移动端布局方案
  ZT8lPCn7HRRr 2023年11月02日 94 0


1 移动端布局方案

1.1 百分比布局(流式布局)

百分比布局是一种等比例缩放的布局方式,也是移动Web开发中比较常见的布局方式。在CSS代码中需要使用百分比来设置盒子的宽高。

例如,把盒子的宽度设置成百分比,网页就会根据浏览器的宽度和屏幕的大小来自动调整显示效果。

而且一般的情况下,我们都会用 max-width 和 min-width 做相关的宽度限制以防止过度的拉伸。以下是子元素设置百分比的参照值:

子元素

参照值

width/height

基于子元素的直接父元素,width相对于父元素的width,height相对于父元素的height

top/bottom 和 left/right

相对于直接非static定位的父元素的height/width

padding/margin

不论是垂直方向或者是水平方向,都相对于直接父亲元素的width,与父元素的height无关。

border-radius

相对于自身的宽度

百分比布局优点

原理简单,兼容性好,且掌握好参照值之后,在一定范围内基本不会出现适配的问题

百分比布局缺点
  • 如果屏幕尺度跨度太大,相对设计稿过大或者过小的屏幕不能正常显示,在大屏手机或横竖屏切换场景下可能会导致页面元素被拉伸变形,字体大小无法随屏幕大小发生变化。
  • 设置盒模型的不同属性时,其百分比设置的参考元素不唯一,容易使布局问题变得复杂
  • 开发过程中计算量大,且参照系容易选错,当屏幕跨度超过设计稿太多时,显示相较于原来设计稿会出现比较大的变形,并且如果不注意垂直方向的适配计算的话,容易出现长宽度与设计稿不一致,另外,background-position 参照于背景图片的像素, IE怪异模式对盒模型的解析不同等也是会影响参照值;
  • 垂直方向的适配问题 !!!因为市面上的手机宽度比并不是一定的,千万别按照宽度来计算高度的百分比,而是应该按照高度来计算,其他参照参考以上表格

1.2 弹性布局

弹性盒布局是 CSS3 中的一种新布局模式,可以轻松地创建响应式网站布局。弹性盒布局为盒模块增加了灵活性,可以让我们告别浮动(float),完美地实现垂直居中。目前它得到几乎所有主流浏览器的支持。

弹性布局原理

弹性布局,用来为盒装模型提供最大的灵活性,任何一个容器都可以指定为flex布局。采用flex布局的元素,被称为容器,它的所有子元素会自动成为容器成员,称为flex项目

弹性布局优点
  • 纯粹的 CSS+HTML 解决方案,父元素 display:flex,子元素配合设置布局,排列方向,排列方式,分布方式等即可
  • html 的结构清晰。需要更少的层级
  • 特别是在移动端,良好的 align 与 justify 居中可以完美替换以前还需要:定位加 margin, margin: auto 等各种复杂的居中解决方案
弹性布局缺点

对于低端老年机,不支持 flex 属性的不太友好

1.3 Rem 适配布局

Rem 适配方案一般采取媒体查询来实现响应式布局设计。

Rem适配方案使用媒体查询可以根据不同的设备按比例设置页面的字体大小,然后在页面中使用rem单位,可以通过修改html里面的文字大小来改变页面中的元素的大小从而进行整体控制。

rem是 CSS 3 中新增的一种相对长度单位。当使用 rem 单位时,根节点 <html> 的字体大小(font-size)决定了rem的尺寸。

rem 适配布局原理

rem 是相对长度单位,rem方案中的样式设计为相对于根元素 font-size 计算值的倍数。根据 屏幕宽度 设置 html 标签的 font-size,在布局时使用 rem 单位布局,达到自适应的目的,是 弹性布局 的一种实现方式。

通过获取屏幕实际宽度动态的设置 html 的字体大小,1rem = html 的字体大小像素(font-size)。

rem 计算方案
(function (doc, win) {
    let docEl = doc.documentElement, // 获取html
        resizeEvt = "orientationchange" in window ? "orientationchange" : "resize",
        width = 750, // 设计稿宽,用时只需要修改这一处
        recalc = function () {
            const clientWidth = docEl.clientWidth; // 获取设备尺寸
            if (!clientWidth) return; // 如果没有值,回去
            if (clientWidth > width) {
                // 如果超过设计稿宽度,就给一个固定值
                docEl.style.fontSize = "100px";
                docEl.style.width = width + "px";
                docEl.style.margin = "0 auto";
            } else {
                docEl.style.fontSize = 100 * (clientWidth / width) + "px";
                docEl.style.width = "";
                docEl.style.margin = "";
            }
        };
    if (!doc.addEventListener) return; // 如果没有这个方法,中断函数
    win.addEventListener(resizeEvt, recalc, false); // 改变大小时调整一下
    doc.addEventListener("DOMContentLoaded", recalc, false); // 加载完成时调整
})(document, window);
// 使用时:1rem = 设计稿的宽度 / 100
<script>
    (function (doc, win) {
      let docEl = doc.documentElement, // 获取html
        resizeEvt = "orientationchange" in window ? "orientationchange" : "resize",
        width = 750, // 设计稿宽,用时只需要修改这一处
        recalc = function () {
          const clientWidth = docEl.clientWidth; // 获取设备尺寸
          if (!clientWidth) return; // 如果没有值,回去
          if (clientWidth > width) {
            // 如果超过设计稿宽度,就给一个固定值
            docEl.style.fontSize = "100px";
          } else {
            docEl.style.fontSize = 100 * (clientWidth / width) + "px";
          }
        };
      if (!doc.addEventListener) return; // 如果没有这个方法,回去
      win.addEventListener(resizeEvt, recalc, false); // 改变大小时调整一下
      doc.addEventListener("DOMContentLoaded", recalc, false); // 加载完成时调整
    })(document, window);
    // 使用时:1rem = 设计稿的宽度 / 100
  </script>
rem 适配布局优点
  • 兼容性好
  • ios: 6.1 系统以上都支持
  • android: 2.1 系统以上都支持
  • 大部分主流浏览器都支持
  • 相较于之前的静态布局和百分比方案,页面不会因为伸缩发生变形,自适应效果更佳。
  • 开发计算量小,参照系单一
rem 适配布局缺点
  • 不是纯 CSS 移动适配方案,需要引入js脚本,在头部内嵌一段 js脚本,监听分辨率的变化来动态改变根元素的字体大小,css样式和 js 代码有一定 耦合性,并且必须将改变 font-size 的代码放在 css 样式之前。
  • 小数像素问题,浏览器渲染最小的单位是像素,元素根据屏幕宽度自适应,通过 rem 计算后可能会出现小数像素,浏览器会对这部分小数四舍五入,按照整数渲染。
    浏览器在渲染时所做的舍入处理只是应用在元素的尺寸渲染上,其真实占据的空间依旧是原始大小。
    也就是说如果一个元素尺寸是 0.625px,那么其渲染尺寸应该是 1px,空出的 0.375px 空间由其临近的元素填充;同样道理,如果一个元素尺寸是 0.375px,其渲染尺寸就应该是0,但是其会占据临近元素 0.375px 的空间。会导致:缩放到低于1px的元素时隐时现(解决办法:指定最小转换像素,对于比较小的像素,不转换为 rem 或 vw)
    两个同样宽度的元素因为各自周围的元素宽度不同,导致两元素相差1px。
    宽高相同的正方形,长宽不等了。
    border-radius: 50% 画的圆不圆。
  • Android 浏览器下 line-height 垂直居中偏离的问题。常用的垂直居中方式就是使用line-height,这种方法在Android设备下并不能完全居中。最佳推荐:利用弹性盒布局的居中方案可以完美解决该问题。
rem 淘宝适配方案
<script>!function(e,t){var n=t.documentElement,d=e.devicePixelRatio||1;function i(){var e=n.clientWidth/3.75;n.style.fontSize=e+"px"}if(function e(){t.body?t.body.style.fontSize="16px":t.addEventListener("DOMContentLoaded",e)}(),i(),e.addEventListener("resize",i),e.addEventListener("pageshow",function(e){e.persisted&&i()}),2<=d){var o=t.createElement("body"),a=t.createElement("div");a.style.border=".5px solid transparent",o.appendChild(a),n.appendChild(o),1===a.offsetHeight&&n.classList.add("hairlines"),n.removeChild(o)}}(window,document)</script>

1.4 vh/vw 布局

vh/vw 布局原理

vh,vw 主要是 CSS3 中新出的为了进行移动适配的长度单位:主要是相对于视口viewport的百分比。

视口是浏览器中用于呈现网页的区域,移动端的视口通常指的是布局视口。

  • vw : 1vw 等于视口宽度的 1%
  • vh : 1vh 等于视口高度的 1%
  • vmin : 选取 vw 和 vh 中最小的那个
  • vmax : 选取 vw 和 vh 中最大的那个

计算方式实际上与百分基本一致,不过多了一个优势,就是参照系没有百分比那么复杂

vh/vw 布局优点
  • 纯 CSS 移动端适配方案,不存在脚本依赖问题
  • 相对于 rem 以根元素字体大小的倍数定义元素大小,逻辑清晰简单,视口单位依赖于视口的尺寸 “1vw = 1/100 viewport width”,根据 视口尺寸的百分比来定义元素宽度
vh/vw 布局缺点
  • 存在一些兼容性问题,Android 4.4 以下不支持
  • px 转换成 vw 不一定能完全整除,因此有一定的像素差
vh/vw 布局计算

100vw = 750px(设计图的像素)

0.13333333333333333333vw = 1px

/* 设计图中一个 48px*35px 大小的元素 */
box1{
    width:48px;
    height:35px;
}
/* 用 vh/vw 布局 */
box1{
    width:6.4vw;
    height:4.667vw;
}

1.5 rem+vw/vh 布局

rem+vw/vh 布局原理
  • vw/vh 方案能够实现宽度和高度的自适应,并且逻辑清晰,由于其被支持得较晚,所以存在一定的兼容性问题。将 vw/vh 方案与 rem 方案相结合,给根元素设置随视口变化的vw单位。
  • 对于 1080px 宽的设计稿,设置默认根字号的大小为 100px,那么设计稿中 1px 对应的是 100vw/1080 = 0.0925926vw,并且 1rem = 100px,也就可以得到 1rem = 9.256926vw
  • 可以使用媒体查询限制根元素的最大最小值,实现对页面的最大最小宽度限制,对用户的视觉体验更好。
rem+vw/vh 布局实用性
  • rem 弹性布局方式作为移动端 web 页面适配方法,后期从 rem 过渡到 vw ,只需要通过 改变根元素大小的计算方式 不需要其他处理。
  • vw 将会成为一种更好的适配方式,目前由于兼容性的原因得不到广泛应用。rem+vw/vh 不存在 vw/vh 的兼容性问题,可以成为由 rem 向 vw/vh 转变的一种过渡方案。
rem+vw/vh 布局适配
  • 1 rem= 1 html的字体大小
  • 网页中字体大小最小是 12px,不能设置比 12 像素还小的字体,如果设置了一个小于 12px 的字体,则字体自动设置为 12
rem+vw/vh 布局换算
  • 设置 font-size:0.13333vw; 然后 1rem = 1px(设计图)(不推荐)
  • 设置 font-size:5.3333vw; 然后 1rem = 40px(设计图)
  • 设置 font-size:13.333vw; 然后 1rem = 100px(设计图)
html{
    font-size:5.3333vw
}
.box1{
    width:1.2rem;
    height:0.875rem;
}
html{
    font-size:13.333vw
}
.box1{
    width:0.48rem;
    height:0.35rem;
}
  • vw 适配如何换算元素大小呢?使用公式:(元素大小 / 设计稿大小)* 100vw 将元素大小转换为 vw 单位的大小。以常用的 750px 设计稿尺寸为例,假设设计稿的某个字体大小是 40px,换算成 vw 单位大小应该为 (40 / 750)* 100vw = 5.33333vw。

1.6 rem+媒体查询布局

rem+媒体查询布局原理
  • 主要实现是通过媒体查询,通过给不同分辨率的设备编写不同的样式实现响应式布局,用于解决不同设备不同分辨率之间兼容问题,一般是指PC、平板、手机设备之间较大的分辨率差异。
  • 实现上不局限于具体的方案,通常结合了 流式布局 + 弹性布局 方案。比如给小屏幕手机设置 @2x 图,为大屏手机设置 @3x 图。
苏宁适配方案(rem+媒体查询)
html {
    font-size: 50px
}

body {
    font-size: 24px
}

@media screen and (min-width:320px) {
    html {
        font-size: 21.33px
    }
    body {
        font-size: 12px
    }
}

@media screen and (min-width:360px) {
    html {
        font-size: 24px
    }
    body {
        font-size: 12px
    }
}

@media screen and (min-width:375px) {
    html {
        font-size: 25px
    }
    body {
        font-size: 12px
    }
}

@media screen and (min-width:384px) {
    html {
        font-size: 25.6px
    }
    body {
        font-size: 14px
    }
}

@media screen and (min-width:400px) {
    html {
        font-size: 26.67px
    }
    body {
        font-size: 14px
    }
}

@media screen and (min-width:414px) {
    html {
        font-size: 27.6px
    }
    body {
        font-size: 14px
    }
}

@media screen and (min-width:424px) {
    html {
        font-size: 28.27px
    }
    body {
        font-size: 14px
    }
}

@media screen and (min-width:480px) {
    html {
        font-size: 32px
    }
    body {
        font-size: 15.36px
    }
}

@media screen and (min-width:540px) {
    html {
        font-size: 36px
    }
    body {
        font-size: 17.28px
    }
}

@media screen and (min-width:720px) {
    html {
        font-size: 48px
    }
    body {
        font-size: 23.04px
    }
}

@media screen and (min-width:750px) {
    html {
        font-size: 50px
    }
    body {
        font-size: 24px
    }
}
rem+媒体查询布局优点
  • 不同屏幕与设备精确适配达到最好的用户友好度
  • 对一些布局紧凑的页面和活动页的适配是最友好的方式,没有之一
  • PC,移动只需要一套代码
rem+媒体查询布局缺点
  • 要匹配足够多的设备与屏幕,一个web页面需要多个设计方案,工作量比较大
  • 通过媒体查询技术需要设置一定量的断点,到达某个断点前后的页面发生显著变化,用户体验不太友好
  • 页面中上存在一定的“冗余”代码
  • 最致命的还是由于PC和移动的交互方式和用户行为存在差距,不仅仅需要 CSS 适配,连一下交互方式也可能需要俩套 JS 来适配。

1.7 移动端布局方案总结

  • 首先需要明确一点的是:并不存在某一个方案完美适用于移动端的所有场景,也并不是每一个方案到现在已经毫无用处
  • 首推的布局方案为:弹性盒布局(如果实在不嫌麻烦大的分块布局使用 vw,vh 也可以,甚至使用 rem 也行)
  • 对于上述的各种移动端web页面自适应方案来说,都存在着一些优势和不足
  • 国内的一些互联网站,通过查看网页源代码发现,它可能不是某一种方案的单独使用,而是几种方案的结合
  • 一个页面上,元素的宽度设置上有百分比,也有 rem,字体的样式中有 rem,有 em,也有固定大小的 px;在屏幕宽度过大时不再缩放,也会用到媒体查询,并且响应式设计更多地可能是针对不同设备间的自适应
  • 对于移动端web页面的自适应方案来说,现在用的比较多的是rem,逐渐向 vw/vh 发展,而 rem+vw/vh 则是作为 vw/vh 向后兼容的一种过渡
  • 响应式针对的是不同分辨率设备而进行的适配式设计,以利用 @media 规则为主要手段,而自适应则忽略@media 以比例布局为主,目的是适应不同的浏览器窗口大小
移动端图片处理
  • 指定图像宽度时使用相对单位,防止意外溢出视口,如 width: 50%,将图片宽度设置为包含元素宽度的 50%
  • 因为 CSS 允许内容溢出容器, 需要使用 max-width: 100% 来保证图像及其他内容不会溢出
  • 维护自适应页面中图片宽高比固定比较常用的方法是使用 padding 设置
rem、vw/vh、百分比以及弹性盒做整体的布局
  • 当内容密集时考虑利用 媒介查询 来针对密集区域的内容来实现不同宽度的类似 icon、字体、margin、padding 小边距的设置(px)
    这样就不会因为适配而使得间距变小甚至挤到一起这种不太好的体验,实际上现在淘宝、京东这些都是这套解决方案
  • 当内容不密集时就可以使用 rem、vw、vh 来设置 px 来设置即可

2 练习作业

  • 实现苏宁易购移动端首页


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  E929ZvlRxyUs   2023年12月23日   38   0   0 前端url前端URL
ZT8lPCn7HRRr