如今人們經過手機閱讀網頁占了大多數,隨著閱讀方式的改動,網頁完成多終端自適應,無論關于防止工程師無謂的反復勞動或者是項目管理的便利性上來說重要性都是非常巨大的。
由于挪動設備越來越多的被人們運用,手機成為訪問互聯網的最常見終端,而我們設計的網頁確是為了呈如今PC端。
手機的屏幕比擬小,寬度通常在600像素以下,而PC的屏幕寬度,普通都在1000像素以上(目前主流寬度是1366×768),有的還到達了2000像素。同樣的內容,要在大小懸殊的屏幕上,都呈現出稱心的效果,并不是一件容易的事。
很多網站的處理辦法,是為不同的設備提供不同的網頁,比方特地提供一個mobile版本,或者iPhone / iPad版本。這樣做固然保證了效果,但是比擬費事,同時要維護好幾個版本,而且假如一個網站有多個portal(入口),會大大增加架構設計的復雜度。
自適應是為了解決如何在不同大小的設備上呈現同樣的網頁。
如何進行自適應網頁設計
通俗的講,移動設備上的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這個特殊的值就行了。
在css中我們一般使用px作為單位,在桌面瀏覽器中css的1個像素往往都是對應著電腦屏幕的1個物理像素,這可能會造成我們的一個錯覺,那就是css中的像素就是設備的物理像素。但實際情況卻并非如此,css中的像素只是一個抽象的單位,在不同的設備或不同的環境中,css中的1px所代表的設備物理像素是不同的。在為桌面瀏覽器設計的網頁中,我們無需對這個津津計較,但在移動設備上,必須弄明白這點。在早先的移動設備中,屏幕像素密度都比較低,如iphone3,它的分辨率為320x480,在iphone3上,一個css像素確實是等于一個屏幕物理像素的。后來隨著技術的發展,移動設備的屏幕像素密度越來越高,從iphone4開始,蘋果公司便推出了所謂的Retina屏,分辨率提高了一倍,變成640x960,但屏幕尺寸卻沒變化,這就意味著同樣大小的屏幕上,像素卻多了一倍,這時,一個css像素是等于兩個物理像素的。
流動布局(fluid grid) "流動布局"的含義是,各個區塊的位置都是浮動的,不是固定不變的。
.main {float: right;width: 70%; }
.leftBar {float: left;width: 25%;}
float的好處是,如果寬度太小,放不下兩個元素,后面的元素會自動滾動到前面元素的下方,不會在水平方向overflow(溢出),避免了水平滾動條的出現。
"自適應網頁設計"的核心,就是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文件。
自適應與響應式的區別
自適應是為了解決如何才能在不同大小的設備上呈現同樣的網頁,讓同一張網頁自動適應不同大小的屏幕,根據屏幕寬度,自動調整網頁內容大小。但是無論怎樣,他們主體的內容和布局是沒有變的。
自適應還是暴露出一個問題,如果屏幕太小,即使網頁能夠根據屏幕大小進行適配,但是會感覺在小屏幕上查看,內容過于擁擠,響應式正是為了解決這個問題而衍生出來的概念。它可以自動識別屏幕寬度、并做出相應調整的網頁設計,布局和展示的內容可能會有所變動。
響應式布局被大家熟知的一個重要原因就是 twitter 開源了 bootstrap。
相比自適應網站,響應式網站省去了很多的控件,同時也省去了不少建立和維護的功夫。響應式布局就是一種流體,在按百分比縮放時也能相當的流暢。
使用響應式設計,你要記住所以的布局。這當然可能會使過程混亂,并且使設計更加復雜。這就意味著你應該專注于中等分辨率的視圖,然后再用media querie調整為更低或更高的分辨率。 所以通常的做法是,在一個新的項目中使用響應式設計,在后期的改造中使用自適應設計。
自適應可用于改造現有的網站使其更好地適應移動端。這使你的設計可控制和開發多個特定的視圖。你開發視圖的數量完全取決于你,你的公司和全面的預算。然而,它也提供了一定量的控件(例如在內容和布局上),如此你便無須使用響應式設計。但當你設計多種分辨率時你會發現,在改變窗口大小的時候將會“跳出”布局。
自適應網站可以用于設計和開發一個擁有多個自適應視圖的網站。所以這種設計通常用于改造網站。
新的 CSS Color Module 規范引入了多種新的顏色表示法. 可以支持多種色彩空間和顏色模型. 這解鎖了很多的玩法. 比如: 基于一個顏色生成更深或更淺的顏色; 根據背景自適應文本色; 使用廣色域顏色等等.
CSS Color Module Level 4 規范
引入了新的顏色表示法, 同時引入了多種色彩空間, 不再僅限于sRGB, 這些方法現代瀏覽器均已支持:
再補充一點, 這些新方法中:
CSS Color Module Level 5 規范
CSS Color Module Level 6 規范
在詳細介紹這些現代新方法之前有必要對一些術語進行解釋:
名詞解釋:
顏色模型是指顏色與坐標系之間的映射和編碼方式, 它定義維度分量與色彩空間的關系. 一個顏色模型就會有一個對應的色彩空間.
色彩空間是某一顏色模型所涵蓋的顏色的定義和命名. 每個顏色空間都由數學模型和關聯的規則集定義. 色彩空間是表示顏色的三維網格, 色彩空間中的每個顏色都由三個通道分量(維度)來表示. 每個顏色空間都有一個定義的色域。
色域指的是它可以表示的特定顏色的范圍, 通常指設備可以顯示的顏色范圍. 如 sRGB, P3, Rec2020 等
可以看出三者有一些共性的東西, 通常來說, 當上下文中使用顏色空間時強調的是它的顏色模型和算法. 當使用色域時強調的是能不能顯示某些顏色
所有色彩空間
比如, 以前用的最多的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])
語法: rgb(from <color> R G B[ / A]), hsl(from <color> H S L [/A]), oklch(from <color> L C H [/A]), ...
相對顏色是指從一個指定顏色的色彩空間轉換到目標色彩空間, 通過對目標色彩空間中的維度變量進行微調后的結果作為輸出.
這聽起來比較繞, 簡單點說就是可以根據原色, 對維度變量進行微調后輸出. 主要特性:
這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關鍵字之后與第一個參數指定的顏色對比度最高的顏色作為輸出.
現代網頁中推薦使用oklch顏色模型, 使用 OKLCH 的好處:
OKLCH 顏色由亮度(明度)、色度(飽和度或純度)、色相三個維度組成, 這也是人類認知里的顏色的三個基本屬性.
詳細分析請看這篇文章: OKLCH in CSS: why we moved from RGB and HSL—Martian Chronicles, Evil Martians’ team blog
使用這個 colorjs.io npm包即可. 它完全支持CSS Color Module Level 4 和 Level 5 的規范
我們的正式開源輕量級的基于Tailwindcss的React 組件庫中的顏色選取組件正在重構中
家好,很高興又見面了,我是"高級前端?進階?",由我帶著大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點贊、收藏、轉發,您的支持是我不斷創作的動力。
構建頁面的渲染樹需要 CSS,而 JavaScript 在頁面的初始構建過程中通常會阻塞 CSS。 因此,開發者應該確保任何非必要的 CSS 都被標記為非關鍵(例如:打印和其他媒體查詢),并且關鍵 CSS 體積應該足夠小,同時加載時間要盡可能短。
借助于關鍵 CSS,用戶可以盡快獲得基本樣式;因為它就在文檔的<head>中的<style>元素中,所以沒有額外的請求到服務器獲取樣式表&等待請求的樣式加載和渲染。
然后在后臺加載下面的折疊或非關鍵樣式,以避免渲染阻塞。
為了獲得最佳性能,開發者可能需要考慮將關鍵 CSS 直接內聯到 HTML 文檔中。
內聯 CSS 消除了關鍵路徑中的額外往返,如果正確設置,可用于提供“單次往返”關鍵路徑長度,其中只有 HTML 是阻塞資源。
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 => {
...
});
當網站是自適應,并且開發者想要為多種屏幕分辨率提供關鍵 CSS 時,這是一個有用的選項。 但是值得注意的是,最終輸出將被壓縮,以消除重復的規則包含。
generate({
base: 'test/',
src: 'index.html',
target: {
css: 'styles/main.css',
},
dimensions: [
{
height: 200,
width: 500,
},
{
height: 900,
width: 1200,
},
],
});
當開發者想要推遲加載網絡字體或背景圖像,可以通過下面的方式:
generate({
base: 'test/',
src: 'index.html',
target: {
css: 'styles/main.css',
},
ignore: {
atrule: ['@font-face'],
decl: (node, value) => /url\(/.test(value),
},
});
更多高級用法可以參考文末資料,本文不再過多展開。
值得一提的是 Penthouse,同時 FilamentGroup 還維護一個關鍵 CSS 節點模塊,類似于 Penthouse ,其會查找并輸出頁面的關鍵路徑 CSS。
當開發者啟用 Priority_ritic_css 過濾器時,適用于 nginx、apache、IIS、ATS 和 Open Lightspeed 的 PageSpeed Optimization 模塊可以自動完成所有繁重的工作。
本文重點關注下 Penthouse,其他類似模塊可以在文末參考資料中獲取。Critical 和 Penthouse 之間的主要區別包括以下幾個點:
總之,如果網站或應用程序有大量樣式需要動態注入到 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
*請認真填寫需求信息,我們會在24小時內與您取得聯系。