HTML - HTML網頁樣式根據手機分辨率自適應


HTML網頁樣式根據手機分辨率自適應

轉自:https://blog.csdn.net/u010071211/article/details/80474286

問題:不同手機型號屏幕尺寸大不相同,導致同樣的文字,有的顯示一行,有的顯示多行。

通過查資料和自己的嘗試解決;網頁開發習慣的px單位,手機html開發不適用

源代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!--防止手機頁面縮放-->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <title>Document</title>
</head>
<body>
<!-- 文字單位設置為rem即可,通過微信開發者工具切換手機型號查看效果。 -->
<div style='border:1px red solid;border-radius:100px;font-size:1rem;'>測試手機端文字的自適應</div>
</body>
<script>
    /*    利用js計算當前設備的DPR,動態設置在html標簽上,並動態設置html的font-size,*/
    !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 = {});

        // 設置了 viewport meta
        if (vpMeta) {
            console.warn("將根據已有的meta標簽來設置縮放比例");
            var initial = vpMeta.getAttribute("content").match(/initial\-scale=([\d\.]+)/);

            if (initial) {
                scale = parseFloat(initial[1]); // 已設置的 initialScale
                dpr = parseInt(1 / scale);      // 設備像素比 devicePixelRatio
            }

        }
        // 設置了 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 均未設置
        if (!dpr && !scale) {
            // QST
            // 這里的 第一句有什么用 ?
            // 和 Android 有毛關系 ?
            var u = (win.navigator.appVersion.match(/android/gi), win.navigator.appVersion.match(/iphone/gi)),
                _dpr = win.devicePixelRatio;

            // 所以這里似乎是將所有 Android 設備都設置為 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);
            }

            // 根節點 fontSize 根據寬度決定
            var baseSize = winWidth / 10;

            docElem.style.fontSize = baseSize + "px";
            flexible.rem = win.rem = baseSize;
        }

        // 調整窗口時重置
        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: 倒退 緩存相關
        win.addEventListener("pageshow", function (e) {
            if (e.persisted) {
                clearTimeout(timer);
                timer = setTimeout(setFontSize, 300);
            }
        }, false);

        // 設置基准字體
        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 = {}));
</script>
</html>

擴展:

viewport

翻譯為中文可以叫做"視區"。手機瀏覽器是把頁面放在一個虛擬的"窗口"(viewport)中,通常這個虛擬的"窗口"(viewport)比屏幕寬,這樣就不用把每個網頁擠到很小的窗口中(這樣會破壞沒有針對手機瀏覽器優化的網頁的布局),用戶可以通過平移和縮放來看網頁的不同部分。

物理像素(physical pixel)

物理像素又被稱為設備像素,他是顯示設備中一個最微小的物理部件。每個像素可以根據操作系統設置自己的顏色和亮度。正是這些設備像素的微小距離欺騙了我們肉眼看到的圖像效果。

設備獨立像素(density-independent pixel)

設備獨立像素也稱為密度無關像素,可以認為是計算機坐標系統中的一個點,這個點代表一個可以由程序使用的虛擬像素(比如說CSS像素),然后由相關系統轉換為物理像素。

CSS像素

CSS像素是一個抽像的單位,主要使用在瀏覽器上,用來精確度量Web頁面上的內容。一般情況之下,CSS像素稱為與設備無關的像素(device-independent pixel),簡稱DIPs。

屏幕密度

屏幕密度是指一個設備表面上存在的像素數量,它通常以每英寸有多少像素來計算(PPI)。

設備像素比(device pixel ratio)

設備像素比簡稱為dpr,其定義了物理像素和設備獨立像素的對應關系。它的值可以按下面的公式計算得到:

設備像素比 = 物理像素 / 設備獨立像素

在JavaScript中,可以通過window.devicePixelRatio獲取到當前設備的dpr。而在CSS中,可以通過-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio進行媒體查詢,對不同dpr的設備,做一些樣式適配(這里只針對webkit內核的瀏覽器和webview)。

dip或dp,(device independent pixels,設備獨立像素)與屏幕密度有關。dip可以用來輔助區分視網膜設備還是非視網膜設備。

眾所周知,iPhone6的設備寬度和高度為375pt * 667pt,可以理解為設備的獨立像素;而其dpr為2,根據上面公式,我們可以很輕松得知其物理像素為750pt * 1334pt。

如下圖所示,某元素的CSS樣式:

width: 2px;
height: 2px;

在不同的屏幕上,CSS像素所呈現的物理尺寸是一致的,而不同的是CSS像素所對應的物理像素具數是不一致的。在普通屏幕下1個CSS像素對應1個物理像素,而在Retina屏幕下,1個CSS像素對應的卻是4個物理像素。

meta標簽

<meta>標簽有很多種,而這里要着重說的是viewport的meta標簽,其主要用來告訴瀏覽器如何規范的渲染Web頁面,而你則需要告訴它視窗有多大。在開發移動端頁面,我們需要設置meta標簽如下:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

代碼以顯示網頁的屏幕寬度定義了視窗寬度。網頁的比例和最大比例被設置為100%。

CSS單位rem

rem就是相對於根元素<html>的font-size來做計算。而我們的方案中使用rem單位,是能輕易的根據<html>的font-size計算出元素的盒模型大小。而這個特色對我們來說是特別的有益處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM