整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          如何進行自適應網頁設計?

          .背景介紹

          如今人們經過手機閱讀網頁占了大多數,隨著閱讀方式的改動,網頁完成多終端自適應,無論關于防止工程師無謂的反復勞動或者是項目管理的便利性上來說重要性都是非常巨大的。

          2.知識剖析

          由于挪動設備越來越多的被人們運用,手機成為訪問互聯網的最常見終端,而我們設計的網頁確是為了呈如今PC端。

          手機的屏幕比擬小,寬度通常在600像素以下,而PC的屏幕寬度,普通都在1000像素以上(目前主流寬度是1366×768),有的還到達了2000像素。同樣的內容,要在大小懸殊的屏幕上,都呈現出稱心的效果,并不是一件容易的事。

          很多網站的處理辦法,是為不同的設備提供不同的網頁,比方特地提供一個mobile版本,或者iPhone / iPad版本。這樣做固然保證了效果,但是比擬費事,同時要維護好幾個版本,而且假如一個網站有多個portal(入口),會大大增加架構設計的復雜度。

          自適應是為了解決如何在不同大小的設備上呈現同樣的網頁。

          3.常見問題

          如何進行自適應網頁設計

          4.解決方案

          1. 在HTML頭部增加viewport標簽。

          通俗的講,移動設備上的viewport就是設備的屏幕上能用來顯示我們的網頁的那一塊區域,在具體一點,就是瀏覽器上(也可能是一個app中的webview)用來顯示網頁的那部分區域,但viewport又不局限于瀏覽器可視區域的大小,它可能比瀏覽器的可視區域要大,也可能比瀏覽器的可視區域要小。在默認情況下,一般來講,移動設備上的viewport都是要大于瀏覽器可視區域的,這是因為考慮到移動設備的分辨率相對于桌面電腦來說都比較小,所以為了能在移動設備上正常顯示那些傳統的為桌面瀏覽器設計的網站移動設備上的瀏覽器都會把自己默認的viewport設為980px或1024px(也可能是其它值,這個是由設備自己決定的),但帶來的后果就是瀏覽器會出現橫向滾動條,因為瀏覽器可視區域的寬度是比這個默認的viewport的寬度要小的。

          該meta標簽的作用是讓當前viewport的寬度等于設備的寬度,同時不允許用戶手動縮放。也許允不允許用戶縮放不同的網站有不同的要求,但讓viewport的寬度等于設備的寬度,這個應該是大家都想要的效果,如果你不這樣的設定的話,那就會使用那個比屏幕寬的默認viewport,也就是說會出現橫向滾動條。

          meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
          

          把移動設備上的viewport分為layout viewport 、 visual viewport 和 ideal viewport 三類,其中的ideal viewport是最適合移動設備的viewport,ideal viewport的寬度等于移動設備的屏幕寬度,只要在css中把某一元素的寬度設為ideal viewport的寬度(單位用px),那么這個元素的寬度就是設備屏幕的寬度了,也就是寬度為100%的效果。ideal viewport 的意義在于,無論在何種分辨率的屏幕下,那些針對ideal viewport 而設計的網站,不需要用戶手動縮放,也不需要出現橫向滾動條,都可以完美的呈現給用戶。

          要得到ideal viewport就必須把默認的layout viewport的寬度設為移動設備的屏幕寬度。因為meta viewport中的width能控制layout viewport的寬度,所以我們只需要把width設為width-device這個特殊的值就行了。

          • 2、不使用絕對寬度

          在css中我們一般使用px作為單位,在桌面瀏覽器中css的1個像素往往都是對應著電腦屏幕的1個物理像素,這可能會造成我們的一個錯覺,那就是css中的像素就是設備的物理像素。但實際情況卻并非如此,css中的像素只是一個抽象的單位,在不同的設備或不同的環境中,css中的1px所代表的設備物理像素是不同的。在為桌面瀏覽器設計的網頁中,我們無需對這個津津計較,但在移動設備上,必須弄明白這點。在早先的移動設備中,屏幕像素密度都比較低,如iphone3,它的分辨率為320x480,在iphone3上,一個css像素確實是等于一個屏幕物理像素的。后來隨著技術的發展,移動設備的屏幕像素密度越來越高,從iphone4開始,蘋果公司便推出了所謂的Retina屏,分辨率提高了一倍,變成640x960,但屏幕尺寸卻沒變化,這就意味著同樣大小的屏幕上,像素卻多了一倍,這時,一個css像素是等于兩個物理像素的。

          • 3、流動布局

          流動布局(fluid grid) "流動布局"的含義是,各個區塊的位置都是浮動的,不是固定不變的。

          .main {float: right;width: 70%; }

          .leftBar {float: left;width: 25%;}

          float的好處是,如果寬度太小,放不下兩個元素,后面的元素會自動滾動到前面元素的下方,不會在水平方向overflow(溢出),避免了水平滾動條的出現。

          • 4、MediaQuery模塊

          "自適應網頁設計"的核心,就是CSS3引入的MediaQuery模塊。 它的意思就是,自動探測屏幕寬度,然后加載相應的CSS文件。

          link rel="stylesheet" type="text/css"media="screen and (max-device-width:400px)"href="a.css"

          上面的代碼意思是,如果屏幕寬度小于400像素(max-device-width: 400px),就加載a.css文件。

          link rel="stylesheet" type="text/css"media="screen and (min-width: 400px)and (max-device-width: 600px)"href="b.css"

          如果屏幕寬度在400像素到600像素之間,則加載b.css文件。

          5.擴展思考

          自適應與響應式的區別

          自適應是為了解決如何才能在不同大小的設備上呈現同樣的網頁,讓同一張網頁自動適應不同大小的屏幕,根據屏幕寬度,自動調整網頁內容大小。但是無論怎樣,他們主體的內容和布局是沒有變的。

          自適應還是暴露出一個問題,如果屏幕太小,即使網頁能夠根據屏幕大小進行適配,但是會感覺在小屏幕上查看,內容過于擁擠,響應式正是為了解決這個問題而衍生出來的概念。它可以自動識別屏幕寬度、并做出相應調整的網頁設計,布局和展示的內容可能會有所變動。

          響應式布局被大家熟知的一個重要原因就是 twitter 開源了 bootstrap。

          相比自適應網站,響應式網站省去了很多的控件,同時也省去了不少建立和維護的功夫。響應式布局就是一種流體,在按百分比縮放時也能相當的流暢。

          使用響應式設計,你要記住所以的布局。這當然可能會使過程混亂,并且使設計更加復雜。這就意味著你應該專注于中等分辨率的視圖,然后再用media querie調整為更低或更高的分辨率。 所以通常的做法是,在一個新的項目中使用響應式設計,在后期的改造中使用自適應設計。

          自適應可用于改造現有的網站使其更好地適應移動端。這使你的設計可控制和開發多個特定的視圖。你開發視圖的數量完全取決于你,你的公司和全面的預算。然而,它也提供了一定量的控件(例如在內容和布局上),如此你便無須使用響應式設計。但當你設計多種分辨率時你會發現,在改變窗口大小的時候將會“跳出”布局。

          自適應網站可以用于設計和開發一個擁有多個自適應視圖的網站。所以這種設計通常用于改造網站。

          代 CSS 顏色規范

          新的 CSS Color Module 規范引入了多種新的顏色表示法. 可以支持多種色彩空間和顏色模型. 這解鎖了很多的玩法. 比如: 基于一個顏色生成更深或更淺的顏色; 根據背景自適應文本色; 使用廣色域顏色等等.

          CSS Color Module Level 4 規范

          引入了新的顏色表示法, 同時引入了多種色彩空間, 不再僅限于sRGB, 這些方法現代瀏覽器均已支持:

          • 基于 sRGB 色彩空間的方法: hsl(), hwb(), rgb();
          • 基于 CIELAB 色彩空間的方法: lab(), lch();
          • 基于 Oklab 色彩空間的方法: oklab(), oklch();
          • 其它色彩空間的方法: color()

          再補充一點, 這些新方法中:

          • 帶 h 的是使用極坐標的顏色空間: hsl, hwb, lch, oklch
          • color()使用任意 color-gamut CSS 媒介功能支持的顏色空間
          • 其它使用的是直角坐標系的顏色空間: rgb, lab, oklab

          CSS Color Module Level 5 規范

          • 引入工具方法: color-mix(), 現代瀏覽器均已支持.
          • 擴展CSS Color Module Level 4 引入的新方法, 是它們支持相對顏色表示法. 相對顏色表示法絕大多數現代瀏覽器已支持.

          CSS Color Module Level 6 規范

          • 引入工具方法: color-contrast(), 目前還沒有瀏覽器支持, 但使用Level 4和Level 5中的工具和方法就可以實現.

          在詳細介紹這些現代新方法之前有必要對一些術語進行解釋:

          名詞解釋:

          • 顏色模型(color model)

          顏色模型是指顏色與坐標系之間的映射和編碼方式, 它定義維度分量與色彩空間的關系. 一個顏色模型就會有一個對應的色彩空間.

          • 色彩空間(color space)

          色彩空間是某一顏色模型所涵蓋的顏色的定義和命名. 每個顏色空間都由數學模型和關聯的規則集定義. 色彩空間是表示顏色的三維網格, 色彩空間中的每個顏色都由三個通道分量(維度)來表示. 每個顏色空間都有一個定義的色域。

          • 色域(color gamut)

          色域指的是它可以表示的特定顏色的范圍, 通常指設備可以顯示的顏色范圍. 如 sRGB, P3, Rec2020 等

          可以看出三者有一些共性的東西, 通常來說, 當上下文中使用顏色空間時強調的是它的顏色模型和算法. 當使用色域時強調的是能不能顯示某些顏色

          所有色彩空間

          CSS Color Module Level 4 新引入的顏色方法統一了帶和不帶alpha通道的表示法

          比如, 以前用的最多的rgb方法, 帶和不帶alpha通道是不同的方法: 不帶alpha通道的是: rgb(r, g, b), 而帶alpha通道的是: rgba(r, g, b, a)

          現在可以統一使用: rgb(R G B [/ A]), alpha通道值是可選的. 注意為了區分舊方法, 新方法不使用逗號分隔分量, 而是用空格替代.

          上面只是拿rgb方法舉了個例子, 其實Level 4 中的所有新方法都支持這種表示法. 如: oklch(L C H [/A])

          CSS Color Module Level 5 相對顏色表示法

          語法: rgb(from <color> R G B[ / A]), hsl(from <color> H S L [/A]), oklch(from <color> L C H [/A]), ...

          相對顏色是指從一個指定顏色的色彩空間轉換到目標色彩空間, 通過對目標色彩空間中的維度變量進行微調后的結果作為輸出.

          這聽起來比較繞, 簡單點說就是可以根據原色, 對維度變量進行微調后輸出. 主要特性:

          1. 可以從任意色彩空間轉換到目標色彩空間, 甚至是CSS自定義屬性.
          2. 轉換后可以使用目標色彩模型中的維度變量
          3. 維度分量可以使用calc()等CSS函數計算

          這3個特性解鎖了一些原本只能通過js才能實現的一些功能.

          例子1: 鼠標覆蓋按鈕時加深背景色:

          方法1: 使用Level 5 規范中的相對顏色表示法:

          .btn {
            --btn-bg: blue;
            background-color: var(--btn-bg);
          }
          .btn:hover {
            background-color: oklch(from var(--btn-bg) calc(l - 0.1) c h);
          }

          這個例子中--btn-bg自定義屬性可以更改為任意顏色, 本例中使用了oklch作為目標色彩空間, 因為oklch可以做到調整亮度而不會影響色相.

          從這個例子中可以看出, CSS自定義屬性與相對顏色的結合使用, 可以創造出很多的新玩法.

          方法2: 使用Level 5 規范中的color-mix()方法

          .btn {
            --btn-bg: blue;
            background-color: var(--btn-bg);
          }
          .btn:hover {
            background-color: color-mix(in oklch, var(--btn-bg), black 10%);
          }

          color-mix()方法的意思是將顏色1和顏色2先轉換到in關鍵字指定的目標色彩空間, 然后按百分比混合它們后輸出.由于black只有L分量, 因此混合只影響了L分量, 因此就得到了不改變色相的情況下加深了顏色.

          例子2: 根據不同背景色自適應高對比度的文本色

          這個場景需要一種方式確定高對比度的算法模型. 通用的是WCAG 2.1, 但它不太準確, 還有一種是APCA, 它相對準確性更高, 參考性更大. 在APCA算法下, 采用oklch顏色模型下L分量在72%左右是一個比較好的對比度分界線. 72%以上采用黑色文本, 72%以下采用白色文本.

          好了, 有了這個基礎, 現在可以使用純CSS實現自適應高對比度的文本色:

          .btn {
            --btn-bg: blue;
            background-color: var(--btn-bg);
            color: oklch(from var(--btn-bg) clamp(0, calc((0.72 - l) * 10000), 1) 0 0);
          }

          這個例子中--bg自定義屬性可以更改為任意顏色, 按鈕文本都可以自適應的高對比度顏色. 本例中使用了oklch作為目標色彩空間, 因為oklch可以做到亮度是可預測性.

          這里稍微解釋這句:clamp(0, calc((0.72 - l)* 10000), 1), 意思是背景色的l維度分量 > 0.72說明背景是淺色的, 那么文本色的L分量就取0即黑色, 否則就說明背景是深色的,L分量就取1即白色. 如果不想純白或純黑, 適當調整各分量以及L的上下界即可.

          這個例子還可以使用CSS Color Module Level 6中的color-contrast()實現相同的效果, 但目前還沒有瀏覽器支持, 留著將來備用:

          .btn {
            --btn-bg: blue;
            background-color: var(--btn-bg);
            color: color-contrast(var(--btn-bg) vs white,black);
          }

          color-contrast()的意思是選擇vs關鍵字之后與第一個參數指定的顏色對比度最高的顏色作為輸出.

          這么多CSS顏色新方法, 我應該使用哪個?

          現代網頁中推薦使用oklch顏色模型, 使用 OKLCH 的好處:

          • OKLCH 各分量是獨立的,互不影響的, 對一個分量的修改不會影響其它分量. 而 hsl()不是.
          • OKLCH 使設計師無需手動選擇每種顏色。他們可以定義一個公式,選擇幾種顏色,并自動生成整個設計系統調色板。
          • OKLCH 可用于任意色域, 標準色域 sRGB, 廣色域 P3, Rec2020 等。例如,新設備(如 Apple 的設備)可以顯示比舊 sRGB 顯示器更多的顏色,我們可以使用 OKLCH 來指定這些新顏色。而且超出色域瀏覽器會呈現最接近的顏色
          • 與 hsl() 不同,OKLCH 更適合顏色修改和調色板生成。因為它使用的是感知亮度, 因此不會再出現意想不到的結果,比如在 Sass 中使用 darken() 產生的意外結果。
          • 憑借其可預測的亮度 L, OKLCH 提供了更好的 a11y。
          • 隨著 CSS 相對顏色函數的瀏覽器普及, 可以很方便的微調顏色(比如根據基色生成強調色, 只需修改 L 分量), 也將不再需要js偵測背景色的高對比度文本色. 根據 APAC 對比度算法,在感知亮度 L >=72% 時所有色相下黑色文本都不會產生對比度的可訪問性問題.
          • 與 rgb() 或十六進制(#ca0000)不同,OKLCH 是人類可讀和可預測的。您只需查看數字即可快速輕松地知道 OKLCH 值代表哪種顏色。OKLCH 的工作方式類似于 HSL,但它對亮度的編碼比 HSL 更好。

          OKLCH 顏色由亮度(明度)、色度(飽和度或純度)、色相三個維度組成, 這也是人類認知里的顏色的三個基本屬性.

          • 亮度(lightness) 是感知亮度,取值: 0-1 或 0-100%,0為黑色,1或100%為白色,"感知"意味著它對我們的眼睛具有一致的亮度,并且是可預測的, 這與 hsl()中的 L 是不同的。
          • 色度(chroma) 從灰色到最飽和的顏色, 對于 P3 和 sRGB 顏色空間應低于 0.37, Rec2020 顏色空間應低于 0.4
          • 色相(hue) 在色環中的角度, 色環: 紅、橙、黃、綠、青、藍、紫。紅為20度左右, 每個顏色間隔50度左右.

          詳細分析請看這篇文章: OKLCH in CSS: why we moved from RGB and HSL—Martian Chronicles, Evil Martians’ team blog

          為了兼容性考慮或想在js中使用CSS相同的顏色功能怎么辦?

          使用這個 colorjs.io npm包即可. 它完全支持CSS Color Module Level 4 和 Level 5 的規范

          新的CSS Color Module規范產生的影響:

          1. 瀏覽器原生的顏色選取器元素需要更新以支持新的顏色模型, 目前還沒有瀏覽器實現.
          2. 現有第三方的顏色選取器組件都是基于sRGB的, 不能選取新的色彩空間中的顏色. 這些組件需要重構.

          我們的正式開源輕量級的基于Tailwindcss的React 組件庫中的顏色選取組件正在重構中

          家好,很高興又見面了,我是"高級前端?進階?",由我帶著大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點贊、收藏、轉發,您的支持是我不斷創作的動力。

          1.為什么開始談論關鍵路徑 CSS

          關鍵路徑 CSS 很重要

          構建頁面的渲染樹需要 CSS,而 JavaScript 在頁面的初始構建過程中通常會阻塞 CSS。 因此,開發者應該確保任何非必要的 CSS 都被標記為非關鍵(例如:打印和其他媒體查詢),并且關鍵 CSS 體積應該足夠小,同時加載時間要盡可能短。

          借助于關鍵 CSS,用戶可以盡快獲得基本樣式;因為它就在文檔的<head>中的<style>元素中,所以沒有額外的請求到服務器獲取樣式表&等待請求的樣式加載和渲染。


          然后在后臺加載下面的折疊或非關鍵樣式,以避免渲染阻塞。

          關鍵路徑 CSS 應該內聯

          為了獲得最佳性能,開發者可能需要考慮將關鍵 CSS 直接內聯到 HTML 文檔中。

          內聯 CSS 消除了關鍵路徑中的額外往返,如果正確設置,可用于提供“單次往返”關鍵路徑長度,其中只有 HTML 是阻塞資源。

          2.critical.js 基礎用法

          critical.js 用于從 HTML 中提取關鍵內容并內聯關鍵路徑 CSS,比如首屏。critical.js 在 Github上開源,有超過10k的star,同時使用也非常簡單:

          import { generate } from 'critical';

          同時支持以下配置選項:

          generate({
            // Inline the generated critical-path CSS
            // - true generates HTML
            // - false generates CSS
            inline: true,
            // Your base directory
            base: 'dist/',
            // HTML source
            html: '<html>...</html>',
            // HTML source file
            src: 'index.html',
            // Your CSS Files (optional)
            css: ['dist/styles/main.css'],
            // Viewport width
            width: 1300,
            // Viewport height
            height: 900,
            // Output results to file
            target: {
              css: 'critical.css',
              html: 'index-critical.html',
              uncritical: 'uncritical.css',
            },
            // Extract inlined styles from referenced stylesheets
            extract: true,
            // ignore CSS rules
            ignore: {
              atrule: ['@font-face'],
              rule: [/some-regexp/],
              decl: (node, value) => /big-image\.png/.test(value),
            },
          });

          下面的示例用于生成關鍵路徑 CSS,是最基本的用法示例:

          generate({
            base: 'test/',
            src: 'index.html',
            target: 'styles/main.css',
            width: 1300,
            height: 900,
          });

          下面示例生成并壓縮關鍵路徑 CSS:

          generate({
            base: 'test/',
            src: 'index.html',
            target: 'styles/styles.min.css',
            width: 1300,
            height: 900,
          });
          

          而下面的示例用于生成、壓縮和內聯關鍵路徑 CSS:

          generate({
            inline: true,
            base: 'test/',
            src: 'index.html',
            target: {
              html: 'index-critical.html',
              css: 'critical.css',
            },
            width: 1300,
            height: 900,
          });

          值得一提的是,generate 方法支持 callback 和 promise 兩種方式返回處理后的結果,比如下面是 promise 的方式:

          generate({
              base: 'test/',
              src: 'index.html',
              width: 1300,
              height: 900
          }).then((({css, html, uncritical})) => {
              // You now have critical-path CSS as well as the modified HTML.
              // Works with and without target specified.
              ...
          }).error(err => {
              ...
          });

          3.critical.js 高級用法

          生成具有多種分辨率的關鍵路徑 CSS

          當網站是自適應,并且開發者想要為多種屏幕分辨率提供關鍵 CSS 時,這是一個有用的選項。 但是值得注意的是,最終輸出將被壓縮,以消除重復的規則包含。

          generate({
            base: 'test/',
            src: 'index.html',
            target: {
              css: 'styles/main.css',
            },
            dimensions: [
              {
                height: 200,
                width: 500,
              },
              {
                height: 900,
                width: 1200,
              },
            ],
          });

          生成關鍵路徑 CSS 并忽略特定選擇器

          當開發者想要推遲加載網絡字體或背景圖像,可以通過下面的方式:

          generate({
            base: 'test/',
            src: 'index.html',
            target: {
              css: 'styles/main.css',
            },
            ignore: {
              atrule: ['@font-face'],
              decl: (node, value) => /url\(/.test(value),
            },
          });
          

          更多高級用法可以參考文末資料,本文不再過多展開。

          4.critical.js 的可行替代方案

          值得一提的是 Penthouse,同時 FilamentGroup 還維護一個關鍵 CSS 節點模塊,類似于 Penthouse ,其會查找并輸出頁面的關鍵路徑 CSS。

          當開發者啟用 Priority_ritic_css 過濾器時,適用于 nginx、apache、IIS、ATS 和 Open Lightspeed 的 PageSpeed Optimization 模塊可以自動完成所有繁重的工作。

          本文重點關注下 Penthouse,其他類似模塊可以在文末參考資料中獲取。Critical 和 Penthouse 之間的主要區別包括以下幾個點:

          • Critical 會自動從 HTML 中提取樣式表,并生成關鍵路徑 CSS,而其他模塊通常要求開發者預先指定這一點。
          • Critical 提供了內聯關鍵路徑 CSS 的方法(生成 CSS 后的常見下一步邏輯)
          • 由于同時處理生成和內聯,因此能夠抽出一些丑陋的樣板文件,否則需要分別解決這些問題

          總之,如果網站或應用程序有大量樣式需要動態注入到 DOM 中(有時在 Angular 應用程序中很常見),建議直接使用 Penthouse。 但是 Penthouse 要求開發者預先提供樣式,某些情況下可能比 Critical 提供更高的準確性。

          參考資料

          https://github.com/addyosmani/critical

          https://github.com/addyosmani/critical-path-css-demo

          https://github.com/filamentgroup/criticalCSS

          https://github.com/pocketjoso/penthouse

          https://www.tezify.com/how-to/defer_css_loading_with_loadcss/

          https://web.dev/articles/extract-critical-css?hl=zh-cn


          主站蜘蛛池模板: 亚洲A∨精品一区二区三区 | 日本一区午夜艳熟免费| 久久青青草原一区二区| 99精品一区二区三区| 久久久无码精品人妻一区| 精品无码人妻一区二区三区品 | 国产一区二区三区国产精品| 香蕉视频一区二区| 风间由美在线亚洲一区| 无码人妻精品一区二区三区久久 | 国产视频福利一区| 国精产品一区二区三区糖心| 国产在线视频一区二区三区 | 最新欧美精品一区二区三区| 亚洲日韩国产一区二区三区| 在线视频一区二区| 国产凹凸在线一区二区| 国产伦精品一区二区三区不卡| 国产综合精品一区二区三区| 色屁屁一区二区三区视频国产| 亚洲成AV人片一区二区| 内射女校花一区二区三区| 国产精品av一区二区三区不卡蜜| 3d动漫精品啪啪一区二区中| 国产精品视频一区二区三区四| 在线观看免费视频一区| 色狠狠一区二区三区香蕉蜜桃| 在线一区二区观看| 国产精品亚洲一区二区三区久久 | 中文乱码精品一区二区三区| 国产大秀视频一区二区三区| 天堂一区二区三区精品| 国产一区二区三区在线看片| 无码人妻aⅴ一区二区三区有奶水| 国产精品香蕉在线一区| 日本一区中文字幕日本一二三区视频| 国产精品成人一区二区三区| 国产成人精品亚洲一区| 台湾无码AV一区二区三区| 中文字幕在线一区| 国产在线一区二区三区|