利用vw+rem實現移動web適配佈局

基本概念

一、單位

Px(CSS pixels)css

  • 像素 (px) 是一種絕對單位(absolute units), 由於不管其餘相關的設置怎麼變化,像素指定的值是不會變化的
  • 實際上是相對於某個設備而言的,不一樣設備指定的值大小仍是有區別的

emhtml

  • 1em與當前元素的字體大小相同(更具體地說,一個大寫字母M的寬度)。CSS樣式被應用以前,瀏覽器給網頁設置的默認基礎字體大小是16像素,這意味着對一個元素來講1em的計算值默認爲16像素。可是要當心—em單位是會繼承父元素的字體大小,因此若是在父元素上設置了不一樣的字體大小,em的像素值就會變得複雜。如今不要過於擔憂這個問題,咱們將在後面的文章和模塊中更詳細地介紹繼承和字體大小設置。em是Web開發中最經常使用的相對單位。

ex, ch前端

  • 分別是小寫x的高度和數字0的寬度。這些並不像em那樣被廣泛使用或很好地被支持。

remvue

  • REM(root em)和em以一樣的方式工做,但它老是等於默認基礎字體大小的尺寸;繼承的字體大小將不起做用,因此這聽起來像一個比em更好的選擇,雖然在舊版本的IE上不被支持 查看關於跨瀏覽器支持 Debugging CSS.)

vw,vhhtml5

  • 分別是視口寬度的1/100和視口高度的1/100,其次,它不像rem那樣被普遍支持。 還有vmin,vmax...

百分比web

2. rem 和 vw 兼容對比

  • rem vue-cli

    rem

  • vw api

    vm

三、關於window.devicePixelRatio

mdn瀏覽器

  • 此屬性返回當前顯示設備的物理像素分辨率與CSS像素分辨率的比值。該值也能夠被解釋爲像素大小的比例:即一個CSS像素的大小相對於一個物理像素的大小的比值。

那麼什麼是設備的物理像素?bash

  • 物理像素(physical pixel):設備能控制顯示的最小單位。設備獨立像素(DIP,device-independent pixel,density-independent pixel):獨立於設備的用於邏輯上衡量像素的單位

  • 對於前端來講,能夠理解成在設備上能設置的最小值。如在dpr = 1 最小值1px; dpr = 2 最小值爲0.5px

PPI(pixel per inch)

  • 每英寸有多少個像素點(設備像素點),PPI越高,畫質越好。

公式

// w: 橫向pixel
// h: 縱向pixel
// inch: 屏幕尺寸
PPI = Math.sqrt(w * w + h * h) / inch

console.log(Math.ceil(Math.sqrt(1920 * 1920 + 1080 * 1080) / 5.5))
// 然而我並不明白怎麼要這樣算 不是應該是 w * h / inch ?????
複製代碼

retina 顯示屏

具有足夠高像素密度而使得人體肉眼沒法分辨其中單獨像素點的液晶屏

三、移動適配注意的點

  1. 屏幕尺寸不同的適配問題

    • 這個能夠藉助vw完美解決
  2. 圖片模糊問題

    • 圖片用三倍圖 能夠保證清晰,推薦用兩倍圖+webp格式 開發和顯示效果折中的結果
  3. 1px 顯示問題

    • 方法不少
  4. api不支持的兼容問題

    • vw不支持的兼容
  5. 高清顯示

    • 是否影響渲染性能??待考證
    • 縮放是否能夠是網頁更高清?

  1. 第三方組件庫兼容問題
  2. 富文本顯示問題
  3. 前端代碼遷移單位不一致問題

適配方案

一、經典的flexble.js方案

存在問題

  • 一、iframe 問題
  • 二、富文本問題
// vue指令
// 1. 先獲取dpr 2獲取每一個文檔對象的字體大小 乘以dpr
Vue.directive('richtext', (el, binding) => {
    Vue.nextTick(() => {
        let dpr = document.querySelector('html').getAttribute('data-dpr')
        let f = (dom) => {
            let fontPx = dom.style && dom.style.fontSize
            if (fontPx) {
                fontPx = fontPx.substr(0, fontPx.length - 2) * parseInt(dpr)
                dom.style.fontSize = fontPx + 'px'
            }
            if (dom.childNodes.length > 0) {
                for (let i = 0; i < dom.childNodes.length; i++) {
                    f(dom.childNodes[i])
                }
            }
        }
        f(el)
    })
})
// 使用方法 
.richtext(v-html="content" v-richtext='')
複製代碼

三、高清方案存在的誤區 dpr越高越清晰 是源自設備自己和縮放關係不大或者說當dpr爲1時清晰度已經足夠了,不須要再經過縮放來是網頁顯示更清晰(實踐總結,未找到資料支持) 四、兼容問題 juejin.im/post/5b9cb9…

二、vw方案

參考

三、rem + vw (推薦方案)

設置html根font-size的值 // 設計稿 750 * 1334

html {
  height: 100%;
  font-size: 50px; // 向下兼容 不止vw時候 寫死font-size
  font-size: 13.33333333vw; // 7.5rem === 100vw
  margin: 0 auto;
}


@media (min-width: 560px) { // pc兼容
  html,body {
    font-size: 54px;
    max-width: 540px;
  }
}

@media (max-width: 1024px) { // ipad兼容:ipad最大1024px
  html,body {
    max-width: 1024px;
  }
}
複製代碼

1px顯示問題 物理像素 dpr>=2 取2倍

.border-bottom {
  position: relative;
  &::after {
    content: '';
    position: absolute;
    z-index: 1;
    pointer-events: none;
    background-color: red;
    height: 1px;
    left: 0;
    right: 0;
    bottom: 0;
    @media only screen and (min-resolution: 2dppx) { // 非標準的
      -webkit-transform: scaleY(0.5);
      -webkit-transform-origin: 50% 0%;
    }
  }
}
// only操做符僅在媒體查詢匹配成功的狀況下被用於應用一個樣式,這對於防止讓選中的樣式在老式瀏覽器中被應用到
// -webkit-device-pixel-ratio 是一個非標準的布爾類型CSS媒體類型,是標準 
// resolution 媒體類型的一個替代方案.
複製代碼

單位要怎麼寫

方法一:postcss-px2rem(vue-cli3)

這裏不推薦 由於px2rem: 寫px時須要加上 /*no*/ 感受比較麻煩

const px2rem = require('postcss-px2rem')
const postcssPx2rem = new px2rem({
  remUnit: 50 // 基準大小
})
css: {
    loaderOptions: {
      postcss: {
        plugins: [postcssPx2rem]
      },
    }
  },
複製代碼

方法二:目前方案是直接寫 7.5rem=100vw 設計稿除以100便可

方法三:px2rem的編輯器插件如vscode的cssrem

除不盡的問題 (calc) 涉及到兼容問題

總結 vw + rem的好處

  • 實現簡單
    • 不依賴插件及第三方庫
    • 幾行css代碼 就能夠實現
  • 開發方便
    • 100vw === 設計稿 / 100 rem 方便換算
    • 不影響px使用,完美兼容第三方組件庫
    • 不存在富文本和iframe等兼容問題
相關文章
相關標籤/搜索