摘要:所有權(quán)保留,請勿用于商業(yè)目的。年月日補充寫過這篇博客之后,又陸續(xù)讀過幾篇關(guān)于布局的文章。移動開發(fā)在必要情況的下,可以適當(dāng)使用來調(diào)整字體大小,但做成完全自適應(yīng)則是一種存在問題的做法。
【資源一】基礎(chǔ)知識恕不回顧本文作者: 文藺
本文地址: http://www.wemlion.com/2015/a...
本文由 @文藺 創(chuàng)作,轉(zhuǎn)載請保留此聲明。 所有權(quán)保留,請勿用于商業(yè)目的。
基礎(chǔ)知識參考以下兩篇博客:
http://isux.tencent.com/web-a...
http://www.w3cplus.com/css3/d...
【資源二】淘寶m站首頁的動態(tài)實現(xiàn)學(xué)習(xí)http://m.taobao.com 首頁的實現(xiàn)。
最近讀到@大漠的新文章《使用Flexible實現(xiàn)手淘H5頁面的終端適配》,和本部分有點關(guān)系。暫且加上來以供參考。(updated 2015-11-24)
源碼進(jìn)行美化、解讀之后,基本布局部分的代碼已經(jīng)被我還原出來了:(2016-01-13補充:后來才發(fā)現(xiàn),早就開源在github上了)
!function(win, lib) { var timer, doc = win.document, docElem = doc.documentElement, vpMeta = doc.querySelector("meta[name="viewport"]"), flexMeta = doc.querySelector("meta[name="flexible"]"), dpr = 0, scale = 0, flexible = lib.flexible || (lib.flexible = {}); // 設(shè)置了 viewport meta if (vpMeta) { console.warn("將根據(jù)已有的meta標(biāo)簽來設(shè)置縮放比例"); var initial = vpMeta.getAttribute("content").match(/initial-scale=([d.]+)/); if (initial) { scale = parseFloat(initial[1]); // 已設(shè)置的 initialScale dpr = parseInt(1 / scale); // 設(shè)備像素比 devicePixelRatio } } // 設(shè)置了 flexible Meta else if (flexMeta) { var flexMetaContent = flexMeta.getAttribute("content"); if (flexMetaContent) { var initial = flexMetaContent.match(/initial-dpr=([d.]+)/), maximum = flexMetaContent.match(/maximum-dpr=([d.]+)/); if (initial) { dpr = parseFloat(initial[1]); scale = parseFloat((1 / dpr).toFixed(2)); } if (maximum) { dpr = parseFloat(maximum[1]); scale = parseFloat((1 / dpr).toFixed(2)); } } } // viewport 或 flexible // meta 均未設(shè)置 if (!dpr && !scale) { // QST // 這里的 第一句有什么用 ? // 和 Android 有毛關(guān)系 ? var u = (win.navigator.appVersion.match(/android/gi), win.navigator.appVersion.match(/iphone/gi)), _dpr = win.devicePixelRatio; // 所以這里似乎是將所有 Android 設(shè)備都設(shè)置為 1 了 dpr = u ? ( (_dpr >= 3 && (!dpr || dpr >= 3)) ? 3 : (_dpr >= 2 && (!dpr || dpr >= 2)) ? 2 : 1 ) : 1; scale = 1 / dpr; } docElem.setAttribute("data-dpr", dpr); // 插入 viewport meta if (!vpMeta) { vpMeta = doc.createElement("meta"); vpMeta.setAttribute("name", "viewport"); vpMeta.setAttribute("content", "initial-scale=" + scale + ", maximum-scale=" + scale + ", minimum-scale=" + scale + ", user-scalable=no"); if (docElem.firstElementChild) { docElem.firstElementChild.appendChild(vpMeta) } else { var div = doc.createElement("div"); div.appendChild(vpMeta); doc.write(div.innerHTML); } } function setFontSize() { var winWidth = docElem.getBoundingClientRect().width; if (winWidth / dpr > 540) { (winWidth = 540 * dpr); } // 根節(jié)點 fontSize 根據(jù)寬度決定 var baseSize = winWidth / 10; docElem.style.fontSize = baseSize + "px"; flexible.rem = win.rem = baseSize; } // 調(diào)整窗口時重置 win.addEventListener("resize", function() { clearTimeout(timer); timer = setTimeout(setFontSize, 300); }, false); // 這一段是我自己加的 // orientationchange 時也需要重算下吧 win.addEventListener("orientationchange", function() { clearTimeout(timer); timer = setTimeout(setFontSize, 300); }, false); // pageshow // keyword: 倒退 緩存相關(guān) win.addEventListener("pageshow", function(e) { if (e.persisted) { clearTimeout(timer); timer = setTimeout(setFontSize, 300); } }, false); // 設(shè)置基準(zhǔn)字體 if ("complete" === doc.readyState) { doc.body.style.fontSize = 12 * dpr + "px"; } else { doc.addEventListener("DOMContentLoaded", function() { doc.body.style.fontSize = 12 * dpr + "px"; }, false); } setFontSize(); flexible.dpr = win.dpr = dpr; flexible.refreshRem = setFontSize; flexible.rem2px = function(d) { var c = parseFloat(d) * this.rem; if ("string" == typeof d && d.match(/rem$/)) { c += "px"; } return c; }; flexible.px2rem = function(d) { var c = parseFloat(d) / this.rem; if ("string" == typeof d && d.match(/px$/)) { c += "rem"; } return c; } }(window, window.lib || (window.lib = {}));
注意:
淘寶首頁在iPhone4上設(shè)置的initial-scale是0.5(其他尺寸類似)。
因此,這句在iPhone4上得出的結(jié)果是640:
var winWidth = docElem.getBoundingClientRect().width;
正是因為淘寶這種獨特的設(shè)置,使得 ios 上 1px邊框的問題完美解決(1px變2px, 又被 initial-scale=0.5 縮小了一半)。
【資源三】常規(guī)情況下js根據(jù)屏幕寬度動態(tài)計算使用js動態(tài)計算:
!(function(doc, win) { var docEle = doc.documentElement, evt = "onorientationchange" in window ? "orientationchange" : "resize", fn = function() { var width = docEle.clientWidth; width && (docEle.style.fontSize = 20 * (width / 320) + "px"); }; win.addEventListener(evt, fn, false); doc.addEventListener("DOMContentLoaded", fn, false); }(document, window));【資源四】媒體查詢較密集的斷點
使用css3 media query 實現(xiàn)
@media screen and (min-width: 320px) { html {font-size: 14px;} } @media screen and (min-width: 360px) { html {font-size: 16px;} } @media screen and (min-width: 400px) { html {font-size: 18px;} } @media screen and (min-width: 440px) { html {font-size: 20px;} } @media screen and (min-width: 480px) { html {font-size: 22px;} } @media screen and (min-width: 640px) { html {font-size: 28px;} }【資源五】強大的單位——vw
使用單位 vw 實現(xiàn)動態(tài)計算。
html { font-size: 31.25vw; /* 表達(dá)式:100*100vw/320 */ }
不過考慮到國內(nèi)兼容性的問題,還是結(jié)合媒體查詢來使用比較好。(媒體查詢的斷點暫時是借用上面的例子)
@media screen and (min-width: 320px) { html { font-size: 100px; } } @media screen and (min-width: 360px) { html { font-size: 112.5px; } } @media screen and (min-width: 400px) { html { font-size: 125px; } } @media screen and (min-width: 440px) { html { font-size: 137.5px; } } @media screen and (min-width: 480px) { html { font-size: 150px; } } @media screen and (min-width: 640px) { html { font-size: 200px; } } html { font-size: 31.25vw; }【總結(jié)】
對以上種種方法的綜合:
1、meta:viewport, 還是initial-scale為 1;
2、320px屏幕下,把頁面根元素html的字體大小設(shè)置為50px;
3、鑒于我們拿到的設(shè)計圖目前是640px寬的基準(zhǔn),這樣我們就不用每次自己除以2了,直接在PS中量就好;
4、寬度什么的最好還是用百分比處理;涉及到高度、字體大小之類的則用rem。
eg:
設(shè)計稿上,div高度為40px;那么css就是 div {height: 0.4rem;}
結(jié)果就只剩下一步轉(zhuǎn)換:設(shè)計稿上量的長度轉(zhuǎn)化為小數(shù)。 50% => 0.5 這種計算,不要太簡單。。。
【方法一】純粹css,支持calc函數(shù)的動態(tài)計算;不支持的用css媒體查詢斷點,優(yōu)雅降級。
@media screen and (min-width: 320px) { html { font-size: 50px; } } @media screen and (min-width: 360px) { html { font-size: 56px; } } @media screen and (min-width: 400px) { html { font-size: 63px; } } @media screen and (min-width: 440px) { html { font-size: 69px; } } @media screen and (min-width: 480px) { html { font-size: 75px; } } /** * 2016-01-13 訂正 * 做適當(dāng)限制 * 大于640的屏幕 固定為100px * 同時需要對body或者最外層wrapper做max-width: 640px的限制 */ /* @media screen and (min-width: 640px) { html { font-size: 100px; } } html { font-size: 15.625vw; } */ html { font-size: 15.625vw; } @media screen and (min-width: 640px) { html { font-size: 100px; } }
【方法二】腳本動態(tài)計算
大前提:
1、initial-scale 為 1;
2、在項目css中(注意不要被公共的base、common之類的影響了,資源加載順序也是蠻重要的),先把html的fontSize設(shè)置為 50px(或者加上媒體查詢代碼), 避免加載未完成時候樣式錯亂;
/* css */ html {font-size: 50px;}
/* javascript */ !(function(win, doc){ function setFontSize() { // 獲取window 寬度 // zepto實現(xiàn) $(window).width()就是這么干的 var winWidth = window.innerWidth; // doc.documentElement.style.fontSize = (winWidth / 640) * 100 + "px" ; // 2016-01-13 訂正 // 640寬度以上進(jìn)行限制 需要css進(jìn)行配合 var size = (winWidth / 640) * 100; doc.documentElement.style.fontSize = (size < 100 ? size : 100) + "px" ; } var evt = "onorientationchange" in win ? "orientationchange" : "resize"; var timer = null; win.addEventListener(evt, function () { clearTimeout(timer); timer = setTimeout(setFontSize, 300); }, false); win.addEventListener("pageshow", function(e) { if (e.persisted) { clearTimeout(timer); timer = setTimeout(setFontSize, 300); } }, false); // 初始化 setFontSize(); }(window, document));
嗯。。。
就這么愉快地結(jié)束了。。。
不知道解讀了某寶首頁的一點點代碼,然后發(fā)在這里,會不會有什么后果。。。
==================================================
2016年1月13日補充寫過這篇博客之后,又陸續(xù)讀過幾篇關(guān)于布局的文章。
具體已經(jīng)忘了,大約是大漠的文章,還有一篇應(yīng)該是搜車前端的博文,另外應(yīng)該還有關(guān)于手淘首頁的分析的文章。
另外,自己也用rem布局實踐過幾個項目。
不得不說,個人覺得rem布局現(xiàn)在已經(jīng)可以放棄了。flex布局已經(jīng)很好用了,早已有之的百分比布局等稍用點心思也并不難。
這篇博客一直想改。但懶惰總是占據(jù)著我的身體。
最后再說下,字體大小自適應(yīng)是錯誤的,字體大小自適應(yīng)是錯誤的,字體大小自適應(yīng)是錯誤的。
rem 布局,可以告別了。
迎接 flex 布局吧。
=========================================
寫在最后這篇博客寫于半年前,那時候還是個剛畢業(yè)的菜鳥。
偶爾有點想法,看了一些大牛的文章,有了這篇博客。
這也是半年來唯一一篇產(chǎn)出。
5k的瀏覽量,95收藏,13推薦,已經(jīng)讓我很驚訝了。
謝謝各路大神們的關(guān)注。
半年來感受到的前端大環(huán)境變化還是很大。雖然在公司沒有太多變化,但眼睛總得看著世界吧。
接下來,還得繼續(xù)學(xué)習(xí)。
由于手上沒什么項目,一直想探索出一套自己的自動化流程,但到現(xiàn)在也只是積累了許多版的草稿。
nodejs方面也得有所探索,nodejs 再加上 shelljs 和 yargs 用起來是真的很爽。(鳴謝阮大神的文章)
算是年終總結(jié)了。在前端的路上繼續(xù)走吧。
=========================================
一點想法:評論區(qū)的回復(fù)媒體查詢和js動態(tài)計算是兩種方式。
首先,支持 CSS3 calc方法 和 rem、vw單位的瀏覽器下,只需要html {font-size: 15.625vw;}這樣一句就好,另外加個媒體查詢限制下。
之前的一大堆密集的斷點只是為了hack不支持calc或者calc的情況。其次,js動態(tài)設(shè)置html的font-size,只要瀏覽器支持rem單位即可。
為什么會考慮到密集的mq斷點呢,因為當(dāng)時還在考慮文字大小的自適應(yīng)問題。
實踐證明,字體大小自適應(yīng)是一種錯誤的想法。
移動開發(fā)在必要情況的下,可以適當(dāng)使用mq來調(diào)整字體大小,但做成完全自適應(yīng)則是一種存在問題的做法。
因此,這里提到的 calc和vh rem配合的做法,最好只用來做布局的工作。js動態(tài)計算也是類似,更適合做布局。
更新Articles on responsive font:
https://madebymike.com.au/wri...
https://medium.com/@jakobud/c...
http://www.w3cplus.com/css/cs...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85955.html
摘要:另一種就是不縮放,對等問題單獨引入處理方案。彩蛋部分相信大多數(shù)同學(xué)也是有想法在實際開發(fā)中把融入到現(xiàn)有的移動端適配方案中的。 前言 2018年最后的法定假期都已經(jīng)結(jié)束了,我相信大部分正在進(jìn)行或曾經(jīng)進(jìn)行過移動端頁面開發(fā)的同學(xué)都或多或少的了解過使用rem進(jìn)行移動端頁面適配的方案以及使用vw的方案,(沒了解過的同學(xué)可以參見大漠老師的這兩篇文章 使用Flexible實現(xiàn)手淘H5頁面的終端適配和再...
摘要:另一種就是不縮放,對等問題單獨引入處理方案。彩蛋部分相信大多數(shù)同學(xué)也是有想法在實際開發(fā)中把融入到現(xiàn)有的移動端適配方案中的。 前言 2018年最后的法定假期都已經(jīng)結(jié)束了,我相信大部分正在進(jìn)行或曾經(jīng)進(jìn)行過移動端頁面開發(fā)的同學(xué)都或多或少的了解過使用rem進(jìn)行移動端頁面適配的方案以及使用vw的方案,(沒了解過的同學(xué)可以參見大漠老師的這兩篇文章 使用Flexible實現(xiàn)手淘H5頁面的終端適配和再...
摘要:方案的簡單介紹基于前提頁面元素的布局尺寸全都以設(shè)計稿為基準(zhǔn)等比例設(shè)置。給根節(jié)點設(shè)置一個基礎(chǔ)值,然后頁面的所有元素布局均相對于該值采用單位設(shè)定。 1、困擾多時的問題 在這之前做web app開發(fā)的的時候,在自適應(yīng)方面一般都是寬度通過百分比,高度以iPhone6跟iPhone5之間的一個平衡值寫死,我們的設(shè)計稿都是iPhone5的640 * 1136標(biāo)準(zhǔn),所以高度一般取個大概值,各種圖標(biāo)的...
摘要:方案的簡單介紹基于前提頁面元素的布局尺寸全都以設(shè)計稿為基準(zhǔn)等比例設(shè)置。給根節(jié)點設(shè)置一個基礎(chǔ)值,然后頁面的所有元素布局均相對于該值采用單位設(shè)定。 1、困擾多時的問題 在這之前做web app開發(fā)的的時候,在自適應(yīng)方面一般都是寬度通過百分比,高度以iPhone6跟iPhone5之間的一個平衡值寫死,我們的設(shè)計稿都是iPhone5的640 * 1136標(biāo)準(zhǔn),所以高度一般取個大概值,各種圖標(biāo)的...
摘要:這種使用簡單,但是兼容性不太好。這種顏色有陰影,估計過不了設(shè)計大佬的那關(guān)。最后會把對應(yīng)的編譯出來,這種兼容性好,就是依賴于插件。這種兼容好,但是會和偽類沖突,也是我司采用的方式。 前言 工作以后,大部分的業(yè)務(wù)工作都是基于移動端H5的,開發(fā)過程中學(xué)習(xí)了很多東西,遇到過許多問題,諸如rememcss pxdevice px等,本文純屬個人的歸納總結(jié),如有問題,請指出親噴~ PC端 本文主要...
閱讀 3968·2021-11-11 10:58
閱讀 3341·2021-09-26 09:46
閱讀 1921·2019-08-30 15:55
閱讀 987·2019-08-30 13:52
閱讀 1955·2019-08-29 13:11
閱讀 3036·2019-08-29 11:27
閱讀 1526·2019-08-26 18:18
閱讀 2648·2019-08-23 14:17