眾所皆知,CSS 一直以來都缺少直接根據子項選取父項元素的方法。多年來,開發人員一直希望我們提供這項功能。所有主要瀏覽器現在都支援 :has() 選取器,可解決這個問題。在
:has()之前,您通常會串連長選取器,或新增類別做為樣式掛鉤。現在,您可以根據元素與其後代的關係設定樣式。如要進一步瞭解 :has() 選取器,請參閱 CSS Wrapped 2023 和 5 個前端開發人員必知的 CSS 片段。
雖然這個選取器看似很小,但可支援大量使用案例。本文將說明電子商務公司如何運用 :has() 選擇器,達成一些使用案例。
請參閱完整系列文章,瞭解電子商務公司如何運用全新的 CSS 和 UI 功能,提升網站成效。
Policybazaar
有了
:has()選擇器,我們就能淘汰以 JavaScript 為基礎的使用者選取項目驗證,並改用 CSS 解決方案,以與先前相同的體驗,為我們提供無縫運作的服務。—Aman Soni,Policybazaar 技術主管
Policybazaar 的投資團隊巧妙地套用 :has() 選擇器,為比較方案的使用者提供清楚的視覺指標。下圖顯示比較 UI 中的兩種方案 (黃色和藍色)。每個方案只能與同類型方案比較。使用 :has() 時,使用者選取一種方案類型後,就無法再選取其他方案類型。
:has(),為父項元素及其子項設定樣式,建立與類別相關的選取功能。程式碼
:has() 可讓您存取父項元素及其子項的樣式。以下程式碼會檢查上層容器是否已設定 .disabled-group 類別。如果是,資訊卡會呈現灰色,且「新增」按鈕會設為 pointer-eventsnone,防止點選時做出反應。
.plan-group-container:has(.disabled-group) {
opacity: 0.5;
filter: grayscale(100%);
}
.plan-group-container:has(.disabled-section) .button {
pointer-events: none;
border-color: #B5B5B5;
color: var(--text-primary-38-color);
background: var(--input-border-color);
}
Policybazaar 的健康團隊則採用稍有不同的應用案例。他們為使用者提供內嵌測驗,並使用 :has() 檢查問題核取方塊狀態,確認問題是否已回答。如果正確,系統會套用動畫,轉換至下一個問題。
程式碼
在方案比較範例中,:has() 用於檢查類別是否存在。您也可以使用 :has(input:checked) 檢查輸入元素 (例如核取方塊) 的狀態。在顯示測驗的紫色橫幅中,每個問題都是核取方塊。Policybazaar 會使用 :has(input:checked) 檢查問題是否已回答,如果已回答,則會使用 animation: quesSlideOut 0.3s 0.3s linear forwards 觸發動畫,滑動至下一個問題。請參閱下列程式碼,瞭解運作方式。
.segment_banner__wrap__questions {
position: relative;
animation: quesSlideIn 0.3s linear forwards;
}
.segment_banner__wrap__questions:has(input:checked) {
animation: quesSlideOut 0.3s 0.3s linear forwards;
}
@keyframes quesSlideIn {
from {
transform: translateX(50px);
opacity: 0;
}
to {
transform: translateX(0px);
opacity: 1;
}
}
@keyframes quesSlideOut {
from {
transform: translateX(0px);
opacity: 1;
}
to {
transform: translateX(-50px);
opacity: 0;
}
}
Tokopedia
如果產品縮圖包含影片,Tokopedia 會使用 :has() 建立疊加圖片。如果產品縮圖包含 .playIcon 類別,系統會新增 CSS 疊加層。在這裡,:has() 選取器會與涵蓋所有縮圖的 .thumbnailWrapper 類別中的 & 巢狀選取器搭配使用。這會建立更模組化且易讀的 CSS。
:has() 前後。程式碼
下列程式碼使用 CSS 選取器和組合器 (& 和 >),並以 :has() 巢狀結構設定縮圖樣式。如果瀏覽器不支援,系統會改用一般額外 CSS 類別規則。@supports selector(:has(*)) 規則也可用於檢查瀏覽器是否支援。因此,無論使用哪個瀏覽器版本,整體體驗都相同。
export const thumbnailWrapper = css`
padding: 0;
margin-right: 7px;
border: none;
outline: none;
background: transparent;
> div {
width: 64px;
height: 64px;
overflow: hidden;
cursor: pointer;
border-color: ;
position: relative;
border: 2px solid ${NN0};
border-radius: 8px;
transition: border-color 0.25s;
&.active {
border-color: ${GN500};
}
@supports selector(:has(*)) {
&:has(.playIcon) {
&::after {
content: '';
display: block;
background: rgba(0, 0, 0, 0.2);
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
}
& > .playIcon {
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
text-align: center;
z-index: 1;
}
}
`;
使用 :has() 時的注意事項
將 :has() 與其他選取器合併,即可建立更複雜的條件。請參閱具有家庭選取器的 has() 中的一些範例。
資源:
- 2023 年 CSS 總回顧
- :has():系列選取器
- 示範:has()
- 要回報錯誤或提出新功能建議嗎?我們想聽聽你的看法!
歡迎參閱本系列的其他文章,瞭解電子商務公司如何運用捲動驅動動畫、檢視畫面轉場效果、彈出式視窗和容器查詢等全新 CSS 和 UI 功能,提升業務成效。