@container 和 :has():兩個(gè)強(qiáng)大功能登陸 Chrome

大家好,我是 CUGGZ。

Chrome 105 測試版于 2022 年 8 月 4 日發(fā)布,預(yù)計(jì) 2022 年 8 月下旬成為穩(wěn)定版。@container(容器查詢) 和 :has()(父選擇器) 這兩個(gè)強(qiáng)大的新響應(yīng)式 API 將登陸 Chrome 105。下面就來看看這兩個(gè)強(qiáng)大功能的妙用!

@container:容器查詢
容器查詢使開發(fā)人員能夠查詢父選擇器的大小和樣式信息,使子元素可以擁有其響應(yīng)式樣式邏輯,無論它位于網(wǎng)頁上的哪個(gè)位置。

開發(fā)人員現(xiàn)在也可以查詢頁面內(nèi)元素的大小,而不是依賴于視口來設(shè)置輸入(如可用空間)的樣式。這個(gè)功能意味著組件擁有了其響應(yīng)式樣式邏輯。這使得組件更具彈性,因?yàn)闃邮竭壿嬇c之相連,無論它出現(xiàn)在頁面上的什么位置。

目前瀏覽器對容器查詢的支持如下:



要想使用容器查詢,首先要在父元素上設(shè)置 container-type,該屬性用來聲明元素是一個(gè)查詢?nèi)萜鳎⑶叶x查詢?nèi)萜鞯念愋?。聲明了該屬性就意味著告訴瀏覽器,在該元素上創(chuàng)建一個(gè)容器上下文,之后可能要查詢此容器。

來看一個(gè)例子,有一個(gè)帶有圖像和文本內(nèi)容的卡片,如下所示:



要?jiǎng)?chuàng)建容器查詢,首先要在卡片容器上設(shè)置容器類型(container-type):

.card-container {
  container-type: inline-size;
}
將 container-type 設(shè)置為 inline-size 就會(huì)查詢父級的 inline-direction 大小。在像英語這樣的拉丁語言中,這將是卡片的寬度,因?yàn)槲谋緩淖蟮接覂?nèi)聯(lián)流動(dòng)。

現(xiàn)在,我們可以通過 @container 將樣式應(yīng)用于其任何子項(xiàng):

.card {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

@container (max-width: 400px) {
  .card {
    grid-template-columns: 1fr;
  }
}
這里,當(dāng)容器寬度小于等于 400px 時(shí),@container 中的樣式就會(huì)生效。

Demo:https://codepen.io/web-dot-dev/pen/dymdbpg

has():父選擇器
CSS :has()偽類使開發(fā)人員能夠檢查父元素是否包含具有特定參數(shù)的子元素。例如,p:has(span) 表示一個(gè)段落 (p) 選擇器,其中有一個(gè) span??梢允褂盟鼇碓O(shè)置父元素(段落)本身的樣式,或設(shè)置其子元素的樣式。

目前瀏覽器對父選擇器的支持如下:



我們可以將 :has() 的父選擇功能與容器查詢的父查詢功能結(jié)合起來,以創(chuàng)建一些真正動(dòng)態(tài)的樣式。

讓我們來基于上面的例子進(jìn)行改造,如果有卡片沒有圖像,就增加標(biāo)題的大小,并將網(wǎng)格布局調(diào)整為單列。如下圖所示:



在這個(gè)例子中,帶有圖像的卡片是兩列布局,沒有圖像的卡片是單列布局。此外,沒有圖像的卡片具有更大的標(biāo)題。使用 :has() 編寫此代碼:

.card:has(.visual) {
  grid-template-columns: 1fr 1fr;
}
上面的代碼正在尋找一個(gè)具有 .visual 類的元素來應(yīng)用兩列樣式。另一個(gè)很簡潔的 CSS 函數(shù)是 :not(),它和 :has() 具有相同的規(guī)范,但已經(jīng)存在了更長時(shí)間并且具有更好的瀏覽器支持。我們可以組合使用 :has() 和 :not(),如下所示:

.card:not(:has(.visual)) h1 {
  font-size: 4rem;
}
在上面的代碼中,定義了一個(gè)選擇器,該選擇器為不包含 .visual 類的卡片設(shè)置 h1 的樣式。

Demo:https://codepen.io/web-dot-dev/pen/JjLpPKv

總結(jié)
上面的例子組合使用了 :has()、:not() 和 @container。給這些代碼添加一些樣式,并在網(wǎng)格中并排展示這些卡片,效果如下:



Demo:https://codepen.io/web-dot-dev/pen/XWEZrje

通過上面的例子,可以看到現(xiàn)代 CSS 是如此強(qiáng)大。期待這兩個(gè)強(qiáng)大的功能登陸 Chromium 105 并獲得更多瀏覽器的支持!

參考:https://developer.chrome.com/blog/has-with-cq-m105/

作者:GUOZE


歡迎關(guān)注微信公眾號(hào) :前端充電寶