美文网首页
多屏适配方案

多屏适配方案

作者: jsAllen | 来源:发表于2018-11-12 18:18 被阅读50次

    本文提供几种常用的多屏适配方案,由于不同公司和产品,适配需求不同,这里没法一一概况完全,仅供参考。

    流行多屏适配种类

    1. PC 和移动端各自为一套独立的页面

      PC 固定宽度(设置最小宽度),移动端自适应(flexible)
      参考示例:https://www.ifanr.com

    2. PC 和移动端共用一套

      响应式和自适应结合
      参考示例:https://www.ifanr.com/api/ifanr-special/vivo-nex

    3. 移动端为主,PC 放置介绍页或者二维码

      参考示例:https://www.ifanr.com/api/ifanr-special/apple-2018-autumn

    多屏适配方案五花八门,不同公司有不同的适配要求,对于开发者而言,需要在开发前明确产品需求,再选择相应的适配方案。

    移动端自适应方案

    前面提到了几种多屏适配的方案,这里重点讲讲移动端自适应的方案

    1. init-scale 方案

    scale = 1 / dpr;
    metaEl.setAttribute('content',  'initial-scale=' + scale + ', maximum-scale=' +  scale + ', minimum-scale=' + scale + ', user-scalable=no');
    

    自动拉伸,好处是简单,只需要根据设计稿的尺寸开发即可,不需要考虑单位转换,坏处是完全放弃 px 单位,没法再进行细粒度的调整,在大屏幕上,仅仅是进行放大操作,而不是展示更多内容,丧失大屏幕的优势。

    在 ipad pro 下等比放大 在 ipad pro 下展示更多内容

    2. rem 方案

    关于 rem 这里就不多介绍了,不过要理解 rem 的定义,即 1rem 等于根字体的大小。这也是后面说把设计稿的基准字体大小设为 100 方便计算的原因。
    使用 rem 做自适应的原理,即根据设计稿尺寸和实际的屏幕尺寸,等比例地缩放设计稿上的元素的尺寸。

    两个公式:

    /*
     * 等比公式
     * clientWidth 为通过 documentElement.clientWidth 获取的当前屏幕宽度
     * designWidth 为设计稿宽度(通常为 750)
     * designFontSize 为自定义的设计稿的基准字体大小,为方便计算,设为 100
     * 通过该公式求出 clientFontSize,即动态设置的根字体大小
     */
    clientWidth / designWidth = clientFontSize / designFontSize
    
    /*
     * px 转 rem 公式
     * pxValue 为设计稿中元素的尺寸
     * designFontSize 在前面已定义的 100 (可设为任何数,不过两边要保持一致) 
     * remValue 即为我们实际设置的 rem 大小
     * 该转换一般是在 sass 等 css 编译语言中进行
     */
    remValue = pxValue / designFontSize
    

    示例代码如下:

    javascript:

    const designWidth = 750
    const designFontSize = 100
    
    function getFontSize() {
       const clientWidth = document.documentElement.clientWidth
       const fontSize = clientWidth * designFontSize / baseClientWidth
       return fontSize
    }
    
    function adjustFontSize() {
       const htmlEle = document.getElementsByTagName('html')[0]
       let fontSize = this.getFontSize()
       htmlEle.style.fontSize = fontSize + 'px'
    
       window.onresize = () => {
          fontSize = this.getFontSize()
          htmlEle.style.fontSize = fontSize + 'px'
       }
    }
    

    sass:

    $designFontSize = 100
    @function r ($size) {
       @return $size / $designFontSize + rem;
    }
    

    补充:rem + init-scale 解决 1px 问题

    左边为高清屏下的 1px ,右边为缩小了一倍的 1px

    在 2dpr 屏上,css border 的 1px 实际上是 2px,如果设计师要求 border 的宽度为普通屏幕上的 1px,则此时需要将 border 设置为 0.5 px,然而大部分浏览器不允许 css 的值为小数点,因此我们可以通过 init-scale 的缩小功能,将 1px border 缩小为 0.5 px,从而解决 1px 问题

    scale = 1 / dpr;
    metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
    fontSize = clientWidth * 100 * dpr / baseClientWidth;
    

    其它解决 1px 问题的方案:before after 伪类 + transform 的 scale 属性

    3. vw 方案

    rem 其实是 vw 的 hack 实现,因为在 rem 方案诞生时,vw 的兼容性还不够理想。
    使用 vw 边不再需要 js 动态设置根字体的大小了,直接使用 sass 等语言,将 px 转为 vw 即可:

    @function vw($px) {
      @return ($px / 375) * 100vw;
    }
    

    补充:提供最大和最小宽度限制需求
    使用上面的 rem 或则 vw 做自适应,在移动端的适配效果还是很不错的,但是如果用户在 PC 上打开了链接,而你又没有专门的 PC 页面的话,那么,适配效果就会很糟糕,示例效果如下:

    移动端下适配很好的页面,在 PC 上的适配效果

    虽然元素仍然是等比放大,但是在 PC 上放大有点吓人了,因此我们有时有必要限制一个最大的宽度,大于这个宽度,页面边不再放大了。如下为限制了最大宽度的 h5,在 PC 上的效果:

    在 PC 上限制最大宽度

    给出 rem 和 vw 宽度限制的代码示例:

    1. rem
    const designFontSize = 100
    const clientWidth = document.documentElement.clientWidth
    
    if (clientWidth > 540) {
       fontSize = (540 * designFontSize) / designDocsWidth
    }
    
    if (clientWidth < 320) {
       fontSize = (minWidth * designFontSize) / designDocsWidth
    }
    
    1. vw
    html {
      font-size: 16px;
    }
    
    @media screen and (min-width: 320px) {
      html {
        font-size: calc(16px + 4 * (100vw - 320px) / 220);
      }
    }
    
    @media screen and (min-width: 540px) {
      html {
        font-size: 20px;
      }
    }
    
    @function r($size){
      @return ($size / 16) + rem; // 16px for 375.
    }
    

    计算公式:

    font-size: calc([minimum size] + ([maximum size] - [minimum size]) * ((100vw - [minimum viewport width]) / ([maximum viewport width] - [minimum viewport width])));
    

    在整理这篇文章之前,我一直对多屏适配心生畏惧,即使已经做了一年多的前端工程师,完成了几个产品和 H5 页面的开发,但一说起多屏适配,还是很头疼,没法很清晰地解答如何做好多屏适配。在我完成这篇文章后,我觉得我的思路清晰了很多,这并不是我已经找到了银弹 —— 我觉得根本没有一套解决所有适配需求的银弹,而是我认识到,多屏适配的方案是在太多了,我并没有必要全部去了解,全部去实验,我觉得我只要掌握了原理,掌握几套常用的解决方案即可,剩下的再根据产品需求,去完善,找出最佳的解决方案。这样一想,适配问题不再那么可怕了。

    参考资料

    使用Flexible實現手淘H5頁面的終端適配

    再聊移動端頁面的適配

    Fluid Typography

    rem, vw, 還是...? 各憑本事的移動端適配方案

    相关文章

      网友评论

          本文标题:多屏适配方案

          本文链接:https://www.haomeiwen.com/subject/vjucfqtx.html