給設(shè)計(jì)師看的CSS容器查詢
時(shí)間:2023-10-06 22:18:02 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)
時(shí)間:2023-10-06 22:18:02 來(lái)源:網(wǎng)站運(yùn)營(yíng)
給設(shè)計(jì)師看的CSS容器查詢:網(wǎng)頁(yè)設(shè)計(jì)工作包括處理不同屏幕尺寸的設(shè)計(jì),基于這些設(shè)計(jì),開(kāi)發(fā)人員使用 CSS 媒體查詢來(lái)監(jiān)測(cè)視口寬度或高度,然后基于此更改設(shè)計(jì)。我們?cè)谶^(guò)去的 10 年里就是這樣設(shè)計(jì)網(wǎng)頁(yè)布局的,而且它即將變得更好,我有一些好消息要告訴你。
CSS 容器查詢是網(wǎng)頁(yè)開(kāi)發(fā)者長(zhǎng)期以來(lái)夢(mèng)寐以求的功能,即將出現(xiàn)在 CSS 中,現(xiàn)在作為 Chrome Canary 的一項(xiàng)試驗(yàn)性功能。在本文,我將詳細(xì)介紹它是什么,它將如何改變?cè)O(shè)計(jì)師的工作流程等等。我并不關(guān)心你是否是一個(gè)會(huì)敲代碼的設(shè)計(jì)師,因?yàn)楸疚牡闹攸c(diǎn)是介紹這一概念,以便為下一篇文章做好準(zhǔn)備。如果你碰到完全不懂的 CSS bits(概念) ,你完全可以選擇跳過(guò)它們并繼續(xù)學(xué)習(xí)。
話不多說(shuō),我們開(kāi)始吧!
響應(yīng)式設(shè)計(jì)的現(xiàn)狀
現(xiàn)在,在同一個(gè)網(wǎng)頁(yè)布局的多個(gè)版本上設(shè)計(jì)仍然是可以的,以顯示內(nèi)部部分將如何根據(jù)視口寬度而變化,我們?cè)O(shè)計(jì)不同的尺寸,如手機(jī)、平板電腦和桌面。
在上圖中,設(shè)計(jì)師創(chuàng)造了同一設(shè)計(jì)風(fēng)格下的三種不同展現(xiàn)方式,因此開(kāi)發(fā)者可以知道如何根據(jù)它進(jìn)行相應(yīng)開(kāi)發(fā),到目前為止,一切都挺順暢的。
現(xiàn)在,我將向你展示更詳細(xì)的設(shè)計(jì)和它的變化,這樣我可以闡明 CSS 容器查詢將為我們解決的問(wèn)題。
注意,這是同一個(gè)組件包含著三種風(fēng)格,分別是默認(rèn)、card 以及 featured ,作為一名設(shè)計(jì)師,你已經(jīng)使用了多個(gè)版本的布局來(lái)展示它,這就像是在說(shuō):“這是文章組件在手機(jī)上的布局風(fēng)格,而這是它在平板電腦上的風(fēng)格”。
在 CSS 中,開(kāi)發(fā)者需要針對(duì)該組件創(chuàng)建三種風(fēng)格,并且每一種都是獨(dú)一無(wú)二的,參考下面的基礎(chǔ)樣式:
.c-media { /* 默認(rèn)樣式 */ display: flex; flex-wrap: wrap; gap: 1rem;}@media (min-with: 400px) { .c-media--card { display: block; } .c-media--card img { margin-bottom: 1rem; }}@media (min-with: 1300px) { .c-media--featured { position: relative; /* 其他樣式 */ } .c-media--featured .c-media__content { position: absolute; left: 0; top: 0; width: 100%; height: 100%; }}
上述(三種)風(fēng)格差異取決于媒體查詢或者視口寬度,意味著我們不能根據(jù)其父容器寬度去控制它們。現(xiàn)在你可能在想,這有什么問(wèn)題?嗯,這是個(gè)好問(wèn)題。
問(wèn)題是開(kāi)發(fā)者被限制住了,只能在視口寬度大于某個(gè)特定值時(shí)使用一個(gè)組件的特定樣式類。例如,如果我想在平板電腦中使用“featured”類,那就行不通了,為什么?因?yàn)樗拿襟w查詢?cè)谝暱趯挾却笥诘扔?1300px 時(shí)啟動(dòng)。
不僅如此,我們還可能面臨內(nèi)容比預(yù)期少的問(wèn)題,有時(shí)候,創(chuàng)作者只會(huì)添加一篇文章,而設(shè)計(jì)稿中包含了三篇,在這種情況下,要么我們有一個(gè)空白區(qū)域,要么文章會(huì)適配展開(kāi)以填充可用空間,請(qǐng)看下圖:
在第一種情況下,文章太寬導(dǎo)致正在使用的圖像被破壞(拉伸),而在第二種情況下,效果是一樣的,但有更多的網(wǎng)格項(xiàng)正在擴(kuò)大以填補(bǔ)可用空間,這(體驗(yàn))并不是很好。
如果使用容器查詢,我們可以通過(guò)查詢父容器來(lái)決定如何顯示特定的組件去解決這些問(wèn)題。請(qǐng)看下圖,它展示了我們?nèi)绾问褂萌萜鞑樵儊?lái)解決這個(gè)問(wèn)題。
因此,我們將解決思路轉(zhuǎn)移到組件的父容器上會(huì)發(fā)生什么呢?換句話說(shuō),如果我們查詢其父容器,根據(jù)其父容器的寬度或高度來(lái)決定組件的外觀,該怎么辦?讓我們來(lái)了解下容器查詢的概念。
什么是容器查詢
首先,讓我定義一個(gè)容器,包含著其他子元素的元素,有時(shí)被稱為一個(gè) wrapper(包裝器),如果你有興趣了解更多關(guān)于容器的信息,我有一篇完整的文章。
容器查詢的功能現(xiàn)在可以在 Chrome Canary 瀏覽器的 flag 下開(kāi)啟(譯者注,指的是 chrome://flags )。感謝 Miriam Suzanne 以及其他朋友的努力。
當(dāng)一個(gè)組件被放在一個(gè)容器中時(shí),代表著它被包含在該容器中,這意味著,我們可以查詢其父容器的寬度并基于此對(duì)其進(jìn)行修改。請(qǐng)看下圖:
注意,每張卡片都有一條黃色的輪廓線,它代表每個(gè)組件的父容器。通過(guò) CSS 容器查詢,我們可以基于其父組件的寬度來(lái)修改組件,為了更清楚地說(shuō)明這一點(diǎn),以下是上述(布局)的 HTML 代碼:
<div class="o-grid"> <div class="o-grid__item"> <article class="c-media"></article> </div> <!-- + more items --></div>
該子組件具有 .c-media 類,它的父容器是 .o-grid__item 元素,在 CSS 中,我們可以這樣做:
.o-grid__item { contain: layout inline-size style;}.c-media { /* 默認(rèn)樣式 */}@container (min-width: 320px) { .c-media { /* 樣式 */ }}@container (min-width: 450px) { .c-media { /* 樣式 */ }}
首先,我們告訴瀏覽器每個(gè)具有 .o-grid__item 類的元素都是一個(gè)容器,接著,我們告訴瀏覽器,如果父元素的寬度大于或等于 320px,它就應(yīng)該呈現(xiàn)出不同的布局,對(duì)于 450px 的查詢也是如此,這就是 CSS 容器查詢的工作方式。
此外,我們可以在任何地方定義它們,也就是說(shuō)如果需要的話,我們可以在頂層容器上進(jìn)行查詢?,F(xiàn)在你已經(jīng)了解了 CSS 容器查詢的基本概念,我想給你展示如下圖片。
在左側(cè),這是一個(gè)正在調(diào)整尺寸的視口,在右側(cè),一個(gè)組件(布局)根據(jù)其父組件的寬度改變,這就是容器查詢的強(qiáng)大和有用之處。
如果你想進(jìn)一步了解容器查詢的 CSS 細(xì)節(jié),我寫(xiě)了一篇關(guān)于它的詳細(xì)文章。
設(shè)計(jì)時(shí)考慮容器查詢
作為一名設(shè)計(jì)師,你需要適應(yīng)這個(gè)革命性的 CSS 功能,因?yàn)樗鼘⒏纳莆覀冊(cè)O(shè)計(jì)網(wǎng)頁(yè)和編寫(xiě) CSS 的方式。我們不僅會(huì)針對(duì)屏幕尺寸進(jìn)行設(shè)計(jì),還要考慮到組件在其容器寬度改變時(shí)應(yīng)該如何適配。
現(xiàn)在,設(shè)計(jì)系統(tǒng)越來(lái)越受歡迎,設(shè)計(jì)團(tuán)隊(duì)會(huì)構(gòu)建一套規(guī)則和組件,以便其他成員可以基于此構(gòu)建頁(yè)面,隨著 CSS 容器查詢的到來(lái),我們還需要在設(shè)計(jì)組件時(shí),考慮應(yīng)該如何根據(jù)其父容器寬度進(jìn)行適配。
考慮如下設(shè)計(jì):
請(qǐng)注意,我們有標(biāo)題欄、文章部分、引言和通訊,它們每一個(gè)都應(yīng)該適應(yīng)視口或其父容器寬度。
我可以設(shè)想將組件分為以下幾部分:
- 視口(媒體查詢)
- 父容器(容器查詢)
- 通用型:不受影響的組件,如按鈕、標(biāo)簽、段落。
對(duì)于示例的用戶界面,我們可以這樣劃分組件。
當(dāng)我們以這種思維方式設(shè)計(jì)用戶界面時(shí),我們可以開(kāi)始考慮組件不同的變化,這些變化取決于它們的父容器寬度,讓我們來(lái)探討一下。
在下圖中,請(qǐng)注意文章組件的每個(gè)變化是如何在特定的寬度中發(fā)揮作用的。
作為一名設(shè)計(jì)師,基于父容器寬度考慮如何設(shè)計(jì),一開(kāi)始可能有點(diǎn)奇怪,但這就是未來(lái)的發(fā)展趨勢(shì),我們向前端開(kāi)發(fā)人員提供每個(gè)組件的細(xì)節(jié)和變化,他們可以使用它們(的規(guī)范進(jìn)行編碼)。
不僅如此,我們可能還有一個(gè)組件的布局,它只在特定的環(huán)境下顯示, 例如,事件列表頁(yè)面, 在這種情況下,明確在哪里使用這個(gè)布局是很重要的。
問(wèn)題是,如何告訴設(shè)計(jì)師應(yīng)該在哪里使用這些組件?
與開(kāi)發(fā)人員溝通
良好的溝通是項(xiàng)目成功的一個(gè)重要因素,作為一名設(shè)計(jì)師,希望你能提供指導(dǎo),說(shuō)明組件不同的適配應(yīng)該用在哪里,它可以是一個(gè)完整的頁(yè)面設(shè)計(jì),也可以是一個(gè)顯示每個(gè)組件如何使用的簡(jiǎn)單圖片。
讓我們將其應(yīng)用于我們之前討論的文章組件。
請(qǐng)注意我如何將每個(gè)變化映射到特定上下文,而不是視口。為了進(jìn)一步證明這一點(diǎn),我想向你展示該組件在與 CSS grid 一起使用時(shí)會(huì)有什么不同。
在 CSS grid 布局中,我們可以通過(guò)使用 auto-fit 關(guān)鍵字來(lái)告訴瀏覽器,如果列的數(shù)量少于預(yù)期時(shí),我們希望它能夠延伸(你可以閱讀更多關(guān)于它的信息這里)。這個(gè)功能很強(qiáng)大,因?yàn)樗梢詭椭覀冊(cè)谕画h(huán)境下顯示不同的變化。請(qǐng)看下圖:
擁有一個(gè)能根據(jù)其父容器寬度做出自適應(yīng)的組件是非常有用的,正如你剛才看到的,我們?cè)谧烂娉叽缟喜榭匆粋€(gè)頁(yè)面,并且有不同的部分,每一個(gè)部分的列數(shù)都不一樣。
設(shè)計(jì)響應(yīng)式組件時(shí)要避免復(fù)雜化
重要的是要記住,一個(gè)組件的內(nèi)部組成結(jié)構(gòu)就像樂(lè)高游戲,你可以根據(jù)當(dāng)前變化對(duì)它們進(jìn)行排序,但凡事都有一個(gè)度,有時(shí)候,對(duì)于前端開(kāi)發(fā)人員來(lái)說(shuō),與其用容器查詢來(lái)實(shí)現(xiàn)自適應(yīng),還不如去實(shí)現(xiàn)一個(gè)全新的組件。
請(qǐng)考慮以下幾點(diǎn)。
它有以下幾點(diǎn):
如果內(nèi)部結(jié)構(gòu)保持不變,或者至少不包含新的結(jié)構(gòu),我們可以修改組件,并有以下多種不同布局。
CSS 容器查詢的使用案例
讓我們來(lái)探討一些可以使用 CSS 容器查詢實(shí)現(xiàn)的案例。
聊天列表
我在 Facebook messenger 上看到了這種模式,聊天列表根據(jù)視口寬度變化,我們可以使用 CSS 容器查詢來(lái)實(shí)現(xiàn)。
當(dāng)有足夠的空間時(shí),列表會(huì)展開(kāi)并顯示每個(gè)用戶的名字,聊天列表的父元素可以是一個(gè)被動(dòng)態(tài)調(diào)整大小的元素(例如:通過(guò)使用 CSS 視口單位,或 CSS 比較功能)。
下面是我們?nèi)绾卧?CSS 中實(shí)現(xiàn)這一點(diǎn)。
<div class="content"> <aside> <ul> <li> <img src="shadeed.jpg" alt="Ahmad Shadeed" /> <span class="name">Ahmad Shadeed</span> </li> </ul> </aside> <main> <h2>Main content</h2> </main></div>.content { display: grid; grid-template-columns: 0.4fr 1fr;}aside { contain: layout inline-size style;}@container (min-width: 180px) { .name { display: block; }}
注意側(cè)邊欄的寬度是 0.4f ,所以它是動(dòng)態(tài)寬度,另外,我還添加了 contain 屬性,并且如果容器寬度大于 180px ,則會(huì)顯示用戶名。
與此類似的另一個(gè)案例是側(cè)邊導(dǎo)航欄,我們可以從新的一行或在圖標(biāo)旁邊切換導(dǎo)航項(xiàng)標(biāo)簽的位置。
/
注意,當(dāng)容器(側(cè)邊欄)較小時(shí),導(dǎo)航項(xiàng)標(biāo)簽是如何切換為新的一行的,而當(dāng)有足夠空間時(shí),導(dǎo)航項(xiàng)標(biāo)簽是如何切換到導(dǎo)航圖標(biāo)旁邊的。
演示:
https://codepen.io/shadeed/pen/Popmryw?editors=0100手風(fēng)琴
手風(fēng)琴模式可用于像 FAQs 這樣的場(chǎng)景,在某些情況下,我們可能需要在側(cè)邊欄或用戶界面中的一個(gè)小區(qū)域內(nèi)添加 FAQs 列表,容器查詢可以提供幫助!
下面是我們?nèi)绾问褂?CSS 容器查詢實(shí)現(xiàn)上述功能。
@container (min-width: 180px) { .faq-title { display: flex; justify-content: space-between; font-size: 1.25rem; } .faq__icon { width: 60px; height: 60px; background-color: #4f96e7; }}
演示:
https://codepen.io/shadeed/pen/yLMbmGR?editors=0100搜索框
當(dāng)我們?cè)诙鄠€(gè)地方使用通用搜索框時(shí),這可能非常有用,例如,它可以在一個(gè)主圖使用(在右側(cè)),也可以在一個(gè)較小的范圍內(nèi)使用,如側(cè)邊欄(在左側(cè))。
活動(dòng)清單
我個(gè)人喜歡這種容器查詢的用例,我們可以在多種情況下使用同一個(gè)組件,在上圖中,我們有簡(jiǎn)單、中等和大型的布局展示。下面是一個(gè)關(guān)于如何使用它們的例子。
同樣,這是適應(yīng)其父容器寬度的相同組件, 這不是很棒嗎?對(duì)我來(lái)說(shuō),是的。
作者簡(jiǎn)介
作者簡(jiǎn)介是博客的常見(jiàn)組成部分,從上圖可以看出,它可以在多種情況下,因此它應(yīng)該自適應(yīng)。
社交分享
大多數(shù)時(shí)候我實(shí)現(xiàn)一個(gè)社交分享組件,需要?jiǎng)?chuàng)建一個(gè)在視口大但父容器寬度小的情況下可以使用的版本(例如:側(cè)邊欄),通過(guò)容器查詢,可以通過(guò)自適應(yīng)其父容器寬度來(lái)輕松解決這個(gè)問(wèn)題。
當(dāng)該組件在側(cè)邊欄中使用時(shí)(在左側(cè)),則使用小版本,當(dāng)父容器較大時(shí)(例如:主區(qū)域),將使用完整版本。