<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【CSS】 淺析rem布局方案

          共 3082字,需瀏覽 7分鐘

           ·

          2021-02-26 12:19


          一些像素概念

          • 物理像素:即實(shí)際的每一個(gè)物理像素,也就是移動(dòng)設(shè)備上每一個(gè)物理顯示單元(點(diǎn))
          • 設(shè)備邏輯像素(css中的px):可以理解為一個(gè)虛擬的相對(duì)的顯示塊,與物理像素有著一定的比例關(guān)系,也就是下面的設(shè)備像素比
          • 設(shè)備像素比(dpr):= 物理像素 / 設(shè)備獨(dú)立像素(px)

          如果dpr1的話(huà),那么1px = 1物理像素xy軸加起來(lái)就是1

          如果dpr2的話(huà),那么1px = 2物理像素,xy軸加起來(lái)就是4

          以此類(lèi)推

          在js中可以通過(guò)window.devicePixelRatio獲取當(dāng)前設(shè)備的dpr

          這里說(shuō)明一下,無(wú)論dpr多大,1px的大小通常來(lái)說(shuō)是一致的,這也就意味著,隨著dpr的增大,物理像素點(diǎn)會(huì)越來(lái)越小,這樣才能容納更多的物理像素,才能更高清,更retina

          說(shuō)完基本概念,來(lái)說(shuō)一下幾個(gè)問(wèn)題:

          retina屏圖片模糊

          首先普及一下位圖像素:一個(gè)位圖像素是圖片的最小數(shù)據(jù)單元,每一個(gè)單元都包含具體的顯示信息(色彩,透明度,位置等等)

          那為什么在dpr高的retina屏上反而會(huì)模糊呢?看圖~

          1dpr的屏幕上,位圖像素和物理像素一一對(duì)應(yīng)沒(méi)什么問(wèn)題,但是在retina屏上,由于一個(gè)px4個(gè)甚至更多的物理像素組成,并且單個(gè)位圖像素不能進(jìn)一步分割,所以會(huì)出現(xiàn)就近取色的情況,如果取色不均,那么就會(huì)導(dǎo)致圖片模糊。

          對(duì)于這種情況,只能采用@2x@3x這樣的倍圖來(lái)適配高清展示,這樣側(cè)向說(shuō)明了為什么照著iphone6做的ui稿不是375,而是750的問(wèn)題。

          雖然這樣在dpr1的屏幕上會(huì)導(dǎo)致1個(gè)物理像素上有4個(gè)位圖像素,但是這種情況的取色算法更優(yōu),影響不大,不做討論。

          1px的粗細(xì)問(wèn)題

          由于1px的實(shí)際大小是一樣的,只是里面的物理像素?cái)?shù)量不同,所以如果直接寫(xiě)1px是沒(méi)問(wèn)題的,不會(huì)出現(xiàn)粗細(xì)不同的情況,但是這樣一來(lái)retina的優(yōu)勢(shì)也rem的作用也就沒(méi)了,其實(shí)還是dpr的問(wèn)題,dpr1,那么1px就是一個(gè)物理像素,但是在retina中。1px實(shí)際可能有49個(gè)物理像素,ui想要的其實(shí)是1個(gè)物理像素,而不是1px,不過(guò)由于不是素所有的手機(jī)都能適配0.x,所以曲線救國(guó),采用scale縮放或者設(shè)置meta都可以

          viewport

          三個(gè)概念

          • layout viewport
          • visual viewport
          • ideal viewport

          layout viewport

          最開(kāi)始,pc上的頁(yè)面是無(wú)法再移動(dòng)端正常顯示的,因?yàn)槠聊惶。瑫?huì)擠作一團(tuán),所以就有了viewport的概念,又稱(chēng)布局視口(虛擬視口),這個(gè)視口大小接近于pc,大部分都是980px

          visual viewport

          有了布局視口,還缺一個(gè)承載它的真是視口,也就是移動(dòng)設(shè)備的可視區(qū)域-視覺(jué)視口(物理視口),這個(gè)尺寸隨著設(shè)備的不同也有不同。這樣在視覺(jué)視口中創(chuàng)建了一個(gè)布局視口,類(lèi)似overscroll:scroll;這樣,可以通過(guò)滾動(dòng)拖拽、縮放擴(kuò)大進(jìn)行較好的訪問(wèn)體驗(yàn)

          ideal viewport

          像上面的體驗(yàn)在早些年可能比較多,但是近幾年幾乎很少了,還是歸咎于用戶(hù)體驗(yàn),所以,我們還需要一個(gè)視口-理想視口(同樣是虛擬視口),不過(guò)這個(gè)理想視口的大小是等于布局視口的,這樣用戶(hù)就能得到更好的瀏覽體驗(yàn)。

          一個(gè)特性

          viewport有六種可以設(shè)置的常用屬性:

          • width:定義layout viewport的寬度,如果不設(shè)置,大部分情況下默認(rèn)是980
          • height:非常用
          • initial-scale:可以以某個(gè)比例將頁(yè)面縮放\放大,你也可以用它來(lái)設(shè)置ideal viewport
            <meta name='viewport' content='initial-scale=1' />
          • maximum-scale:限制最大放大比例
          • minimum-scale:限制最小縮小比例
          • user-scalable:是否允許用戶(hù)放大\縮小頁(yè)面,默認(rèn)為yes

          rem適配方案

          先說(shuō)原理,通過(guò)meta修正1px對(duì)應(yīng)的物理像素?cái)?shù)量,在根據(jù)統(tǒng)一的設(shè)計(jì)稿來(lái)生成html上的動(dòng)態(tài)font-size,根據(jù)dpr構(gòu)造字體等誤差較大的樣式的mixin

          // 第一版:
          function initRem({
            const meta = document.querySelector('meta[name="viewport"]');;
            const html = document.documentElement;
            const cliW = html.clientWidth;
            const dpr = window.devicePixelRatio || 1;
            meta.setAttribute('name''viewport');
            meta.setAttribute(
                'content',
                `width=${cliW * dpr}, initial-scale=${1 /
                    dpr} ,maximum-scale=${1 /
           dpr}
          , minimum-scale=${1 /
                    dpr},user-scalable=no`
            );
            html.setAttribute('data-dpr', dpr);
            /
          / 這樣計(jì)算的好處是,你可以直接用ui的px/100得到的就是rem大小,方便快捷,無(wú)需mixin
            html.style.fontSize = 10 / 75 * cliW * dpr + 'px';
          }
          initRem();
          window.onresize = window.onorientationchange = initRem();

          對(duì)于引入的第三方ui組件,需要使用px2rem轉(zhuǎn)換工具去做整體轉(zhuǎn)換,比如postcss-pxtorem:https://github.com/cuth/postcss-pxtorem



          最后


          • 歡迎加我微信(winty230),拉你進(jìn)技術(shù)群,長(zhǎng)期交流學(xué)習(xí)...

          • 歡迎關(guān)注「前端Q」,認(rèn)真學(xué)前端,做個(gè)專(zhuān)業(yè)的技術(shù)人...

          點(diǎn)個(gè)在看支持我吧
          瀏覽 62
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲精品乱码久久久久久蜜桃不卡 | 久久人热视频综合网 | 亚洲四虎在线观看 | 激情操逼影音 | 国产性爱一区二区三区 |