:has() 個案研究

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

CSS 發現無法根據子項直接選取父項元素。多年來,這項技術是開發人員最重視的需求。所有主要瀏覽器現在都支援 :has() 選取器,就能解決這個問題。在 :has() 之前,您通常會鏈結長選取器,或新增樣式掛鉤類別。現在,您可以根據元素與子系的關係來設定樣式。如要進一步瞭解 :has() 選取器,請參閱「2023 年的 CSS 包裝」和「每個前端開發人員應該知道的 5 個 CSS 程式碼片段」。

雖然這個選取器看起來很小,但用途可能很多。本文示範電子商務公司透過 :has() 選取器解鎖的一些用途。

:has() 屬於新推出的基準

瀏覽器支援

  • 105
  • 105
  • 121
  • 15.4

來源

查看本文的完整系列文章,瞭解電子商務公司如何運用全新 CSS 和 UI 功能提升網站成效。

政策博薩爾

透過 :has() 選取器,我們得以取消對使用者選項進行的 JavaScript 驗證,並將其替換為 CSS 解決方案,讓我們能夠提供與過去相同的體驗,並帶來與之前一致的體驗。也就是 Policybazaar 技術主管 Aman Soni

Policybazaar 的投資團隊巧妙套用 :has() 選取器,以視覺化的方式明確顯示正在比較方案的使用者。下圖顯示比較 UI 中兩種類型的方案 (黃色和藍色)。每個方案只能與各自的類型進行比較。使用 :has() 時,當使用者選取某個方案類型無法選取另一種方案時。

實作 :has() 來設定父項元素及其子項的樣式,以建立類別界限選取功能。

程式碼

:has() 可讓您存取父項元素及其子項的樣式。下列程式碼會檢查父項容器是否已設定 .disabled-group 類別。如果是,資訊卡會顯示為灰色,且將 pointer-events 設為 none,就不會回應「新增」按鈕。

.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 的 health 團隊實作的應用實例稍有不同。具有內嵌測驗給使用者,並使用 :has() 檢查問題核取方塊的狀態,確認問題是否已回答。如果是這種情況,動畫就會套用至下一個問題。

health.policybazaar.com/

程式碼

在方案比較範例中,: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。

使用含有選取器的 Tokopedia 頁面螢幕截圖。
使用 :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() 系列選取器中的範例。

資源:

請瀏覽本系列其他文章,瞭解使用新的 CSS 和 UI 功能 (例如捲動式動畫、瀏覽轉換、彈出式視窗和容器查詢) 為電子商務公司帶來哪些好處。