[CSS] 響應(yīng)式設(shè)計(jì)
響應(yīng)式設(shè)計(jì)基本原則
1. 流式布局
- 頁面需要適應(yīng)當(dāng)前視口寬度(甚至高度);
- 需要適配視口的元素,使用
%單位(或者vh、vw),而不是px; - 使用
max-width取代width。
2. 響應(yīng)式單位
- 對于大部分長度,使用
rem單位取代px,可以簡化整個(gè)布局的自動縮放。
3. 靈活的圖像
- 默認(rèn)情況下,改變視口大小的時(shí)候,圖片不會自動縮放;
- 使用
%單位設(shè)置圖片的大小,并配合max-width使用。 - 為不同尺寸的屏幕提供不同分辨率的圖片。
4. 媒體查詢
- 媒體查詢可以在特定的視口尺寸下應(yīng)用特定的CSS樣式。(特定的視口尺寸成為斷點(diǎn))
- 媒體查詢需要搭配上面三個(gè)原則才能實(shí)現(xiàn)響應(yīng)式布局。
響應(yīng)式設(shè)計(jì)策略
桌面端與移動端的優(yōu)先
響應(yīng)式設(shè)計(jì)有兩種思路:桌面端優(yōu)先和移動端優(yōu)先,它們的區(qū)別是先實(shí)現(xiàn)一種布局,再使用媒體查詢設(shè)置斷點(diǎn),實(shí)現(xiàn)不同屏幕尺寸下的布局,逐漸過渡到另一端。即由大到小和由小到大的區(qū)別。
在設(shè)置媒體查詢的斷點(diǎn)時(shí):
-
桌面端優(yōu)先:使用
max-width;如下圖,我們首先假設(shè)我們開發(fā)的桌面端網(wǎng)頁應(yīng)用寬度是大于1200px的,然后,我們開始考慮小尺寸屏幕的情況,設(shè)置
max-width: 1200px的媒體查詢,匹配所有寬度≤1200px的屏幕。進(jìn)一步細(xì)化后,最終設(shè)置max-width: 900px和max-width: 600px。 -
移動端優(yōu)先:使用
min-width.

注:一種尺寸的屏幕可能會同時(shí)匹配上多個(gè)媒體查詢中的CSS選擇器,媒體查詢并不會改變選擇器的具體程度,因此最后的媒體查詢會覆蓋前面的媒體查詢。
移動端優(yōu)先的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 完全針對移動用戶進(jìn)行了優(yōu)化(移動端應(yīng)用具有便捷性,市場需求量大,現(xiàn)代互聯(lián)網(wǎng)的許多流量都來自于手機(jī),屬于優(yōu)點(diǎn));
- 移動端的設(shè)計(jì)會更注重內(nèi)容,而不是純粹的美學(xué)設(shè)計(jì)。
缺點(diǎn):
- 逐步轉(zhuǎn)變到桌面版本的時(shí)候,布局會顯得很空洞和過于簡化;
- 由于優(yōu)先考慮移動端,“畫板”小,創(chuàng)作自由度低,難以創(chuàng)建有區(qū)別度的產(chǎn)品;
- 特定領(lǐng)域的用戶可能更關(guān)注桌面端應(yīng)用而不是移動端。
斷點(diǎn)的選擇

- BAD:使用流行設(shè)備的尺寸作為斷點(diǎn),這種策略針對流行的設(shè)備做了最大程度的優(yōu)化,但是忽略了其它設(shè)備;同時(shí),這種策略極度依賴設(shè)備尺寸,如果設(shè)備開發(fā)商突然修改了設(shè)備尺寸,則需要大范圍修改代碼。
- GOOD:在互聯(lián)網(wǎng)上查詢盡可能多的設(shè)備尺寸,將他們聚集在一起,并選擇中間的稀疏的尺寸作為斷點(diǎn)。這種策略適用性廣,難度適中,推薦使用。
- PERFECT:完全忽略設(shè)備的尺寸,只關(guān)注網(wǎng)頁的內(nèi)容和設(shè)計(jì),當(dāng)屏幕大小到達(dá)某個(gè)尺寸后開始崩壞,則添加斷點(diǎn)。這種策略實(shí)現(xiàn)難度過大。
在Screen Resolution Stats Worldwide | Statcounter Global Stats可以查看2023年屏幕尺寸的使用量占比。

這些數(shù)據(jù)可以協(xié)助確定斷點(diǎn),通常需要考慮4種或5種尺寸:手機(jī)、縱向平板、橫向平板、桌面端、(大型桌面端)。
下圖中的斷點(diǎn)分別是:600px,900px,1200px,1800px。

能否使用hover?
我們使用響應(yīng)式設(shè)計(jì)的初衷是為了用戶使用不同屏幕尺寸的設(shè)備都能獲得良好的體驗(yàn)。但是到目前位置我們區(qū)分設(shè)備的指標(biāo)只有簡單的屏幕寬度。
事實(shí)上,橫向平板和桌面端在大部分時(shí)候的布局都是類似的,但是它們的操作方式卻截然不同,前者使用觸屏,后者使用鼠標(biāo)與鍵盤。
同時(shí),現(xiàn)代UI設(shè)計(jì)者在桌面端的設(shè)計(jì)可能結(jié)合hover(鼠標(biāo)懸?。┡c縮放、翻轉(zhuǎn)等動畫,這種交互設(shè)計(jì)使得部分按鈕或文本等內(nèi)容在初始狀態(tài)下是隱藏的,而橫向平板的觸屏操作卻無法查看這些內(nèi)容。
當(dāng)然,這種情況通常發(fā)生在桌面端優(yōu)先的設(shè)計(jì)策略中,并且在兼容橫向平板界面時(shí),遺漏了對于交互、頁面內(nèi)容的兼容。
由此可見,僅通過屏幕寬度區(qū)分設(shè)備的媒體查詢是存在缺陷的,媒體查詢應(yīng)進(jìn)一步地檢查設(shè)備能否使用hover。
媒體查詢 匹配能否使用hover的設(shè)備
@media (hover:none){
/* 這里匹配不能hover的設(shè)備 */
}
@media (hover:hover){
/* 這里匹配可以hover的設(shè)備 */
}
SaSS實(shí)現(xiàn)響應(yīng)式 案例
以 桌面端優(yōu)先 為例,斷點(diǎn)選擇如下:
0 - 600px:手機(jī)600 - 900px:平板豎向900 - 1200px:平板橫向[1200 - 1800]:默認(rèn)樣式,普通桌面端1800px +:大型桌面
使用mixin封裝一個(gè)媒體查詢管理器:
@mixin respond($breakpoint){
@if $breakpoint == phone {
@media only screen and (max-width: 37.5em) { @content; } // 600px
}
@if $breakpoint == tab-port {
@media only screen and (max-width: 56.25em) { @content; } // 900px
}
@if $breakpoint == tab-land {
@media only screen and (max-width: 75em) { @content; } // 1200px
}
@if $breakpoint == big-desktop {
@media only screen and (min-width: 112.5em) { @content; } // 1800px
}
}
需要注意的是,媒體查詢里的em和rem單位都只和瀏覽器默認(rèn)字體大小(16px)有關(guān),和根節(jié)點(diǎn)的字體大小無關(guān)。
上面這段代碼中使用em而不是直接使用px是因?yàn)?strong>用戶可能會更改瀏覽器的默認(rèn)字體大小,使用em更加靈活。
only screen使得媒體查詢更加嚴(yán)謹(jǐn),當(dāng)用戶打算打印頁面時(shí),這些媒體查詢不應(yīng)該生效。
使用:
設(shè)置根節(jié)點(diǎn)的字體大小,使用上面封裝的mixin匹配不同的屏幕尺寸。
這里font-size使用百分比而不是直接使用px與上文同理(用戶可能修改瀏覽器默認(rèn)字體大?。?/p>
html{
// This defines what 1rem is
font-size: 62.5%; // 1rem = 10px, 10/16 = 62.5%
@include respond(tab-land){ // width < 1200?
font-size: 56.25%; // 1rem = 9px, 9/16 = 56.25%
}
@include respond(tab-port){ // width < 900?
font-size: 50%; // 1rem = 8px, 8/16 = 50%
}
@include respond(big-desktop){
font-size: 75%; // 1rem = 12px, 12/16 = 75%
}
}
注:媒體查詢需要注意代碼順序,應(yīng)該先media(max-width: 900px),再media(max-width: 600px),這樣當(dāng)屏幕尺寸小于600px時(shí),雖然兩個(gè)媒體查詢都能匹配到,但是更加“精細(xì)”的后者可以正確地覆蓋前者。
如何實(shí)現(xiàn)響應(yīng)式?
假設(shè)我們以桌面端優(yōu)先,那么此時(shí)CSS代碼都是基于桌面端屏幕尺寸的。
打開瀏覽器開發(fā)者工具,使用設(shè)備工具欄,拖動界面尺寸,觀察到哪一個(gè)斷點(diǎn)開始頁面開始崩壞,然后著手為該部分CSS代碼添加額外的代碼:

需要注意由于選擇桌面端優(yōu)先,并且配置媒體查詢的時(shí)候使用max-width,在寫不同尺寸的CSS代碼的時(shí)候應(yīng)注意由大到小的順序。
如上圖,先tab-port(平板豎向)再phone(移動端)。
響應(yīng)式圖像
應(yīng)用場景:
- 不同尺寸的屏幕:桌面端大屏幕需要較大較清晰的圖片,移動端小屏幕對清晰度要求不高且注重圖片在網(wǎng)絡(luò)傳輸過程中的流量消耗;
- 屏幕分辨率不同(與尺寸無關(guān)):為低分辨率屏幕(1x)和高分辨率屏幕(2x)分別準(zhǔn)備不同的圖片。

HTML實(shí)現(xiàn)
實(shí)現(xiàn)方式:
<picture class="footer__logo">
<source srcset="img/logo-green-small-1x.png 1x, img/logo-green-small-2x.png 2x"
media="(max-width: 37.5em)">
<img srcset="img/logo-green-1x.png 1x, img/logo-green-2x.png 2x" alt="Full logo"
src="img/logo-green-2x.png">
</picture>
-
首先,
source和img的分離可以實(shí)現(xiàn)匹配不同的屏幕尺寸,source支持配置media,與媒體查詢一致,這里設(shè)置的(max-width: 37.5em)匹配上手機(jī)的尺寸,當(dāng)使用手機(jī)屏幕訪問時(shí)瀏覽器會自動選擇source的圖片,否則使用img的圖片。 -
其次,使用
srcset可以匹配不同分辨率(像素密度)的屏幕,語法格式為:圖片路徑1 像素密度1, 圖片路徑2 像素密度2,如上述代碼,低分辨率屏幕匹配1x標(biāo)記,使用img/logo-*-1x.png圖片,高分辨率屏幕匹配2x標(biāo)記的圖片,這一選擇過程由瀏覽器自動完成。 -
另外,可以通過設(shè)置多個(gè)
source匹配多種屏幕尺寸,但沒必要,一般為手機(jī)尺寸單獨(dú)設(shè)置一個(gè)source就足夠了。 -
最后,
img需要繼續(xù)設(shè)置src,避免舊版瀏覽器無法正確識別srcset屬性。
CSS實(shí)現(xiàn)
使用媒體查詢也可以匹配不同分辨率的屏幕。
@media (min-resolution: 192dpi) {
/* 這里匹配高分辨率屏幕 */
}
192dpi是蘋果視網(wǎng)膜屏幕的數(shù)據(jù),每英寸屏幕192像素點(diǎn),超過這個(gè)數(shù)據(jù)的屏幕則認(rèn)為是高分辨率屏幕。
一般會在這里設(shè)置使用較大的圖片,但是目前手機(jī)基本都是高分辨率屏幕,也會匹配到這里的大圖片,不太合理。
因此,可以添加媒體查詢的條件:
@media (min-resolution: 192dpi) and (min-width: 600px){
/* 這里匹配除了手機(jī)以外的高分辨率屏幕 */
}
另外,大圖片不僅應(yīng)用于高分辨率屏幕,低分辨率屏幕尺寸足夠大時(shí)也應(yīng)該使用大圖片,如下:
@media (min-resolution: 192dpi) and (min-width: 600px),
(min-width: 2000px){
/* 這里匹配除了手機(jī)以外的高分辨率屏幕,或者尺寸足夠大的低分辨率屏幕 */
}
考慮到min-resolution在safari不可用,使用-webkit-min-device-pixel-ratio:
@media (min-resolution: 192dpi) and (min-width: 37.5em),
(-webkit-min-device-pixel-ratio: 2) and (min-width: 37.5em),
(min-width: 125em){
...
}

浙公網(wǎng)安備 33010602011771號