CSS :has() 選擇器詳解:為什么它是“父選擇器”?如何實現真正的容器查詢?

一、前言

在傳統的 CSS 中,我們只能根據元素的自身屬性、類名、ID 或其子元素/兄弟元素來設置樣式,卻無法根據其父元素或后代元素的狀態來改變自身樣式

直到 :has() 選擇器的出現,這一局面被徹底改變。

:has() 被稱為 “父選擇器”“容器選擇器”,是 CSS 選擇器的一次革命性升級。它不僅讓 CSS 擁有了更強的表達能力,還為 容器查詢(Container Queries) 提供了重要支持。

本文將深入解析 :has() 的語法、用法與實戰場景,帶你掌握這一現代 CSS 強大特性。


二、什么是 :has() 選擇器?

:has() 是一個 關系偽類選擇器(Relational Pseudo-class),用于匹配包含特定后代元素的父元素

? 語法:

parent:has(descendant)?{/*?樣式規則?*/
}

🔍 簡單理解:

“選擇那些 包含 某個特定后代元素的父元素”。


三、基本語法與示例

1. 基礎用法:匹配包含特定子元素的父級

<div?class="card"><h3>標題</h3><p>這是一段描述文字。</p>
</div><div?class="card"><h3>標題</h3><!--?沒有?p?元素?-->
</div>
/*?只有包含?<p>?的?.card?才有邊框陰影?*/
.card:has(p)?{box-shadow:?0?4px?6px?rgba(0,0,0,0.1);border-radius:?8px;
}

2. 支持復雜選擇器

/*?包含?.error?類的表單?*/
.form:has(.error)?{border:?2px?solid?#e74c3c;
}/*?包含圖片的段落,增加行高?*/
p:has(img)?{line-height:?1.8;
}/*?包含至少兩個子項的列表?*/
ul:has(li:nth-child(2))?{background:?#f8f9fa;
}

四、為什么說 :has() 是“父選擇器”?

在 CSS 歷史上,一直無法直接選擇“父元素”。例如:

“如何選中包含 <input type="text"><label>?”

過去只能通過 JavaScript 或調整 HTML 結構解決。

現在,:has() 讓 CSS 原生支持“向上選擇”:

<label>用戶名:<input?type="text"?name="username">
</label>
/*?選中包含?text?input?的?label?*/
label:has(input[type="text"])?{font-weight:?bold;color:?#333;
}

? 這就是所謂的“父選擇器”能力。


五、實戰場景:真正的“容器查詢”(Container Queries)

CSS 容器查詢(@container)允許組件根據其容器大小而非視口大小來響應。:has() 可與之結合,實現更智能的布局。

示例:卡片根據內容動態調整

<div?class="container"?style="width:?300px;"><article?class="card"><img?src="image.jpg"?alt="圖片"><h3>帶圖片的卡片</h3><p>這是一段描述。</p></article>
</div><div?class="container"?style="width:?300px;"><article?class="card"><h3>純文本卡片</h3><p>沒有圖片。</p></article>
</div>
/*?啟用容器查詢?*/
.container?{container-type:?inline-size;
}.card?{display:?grid;gap:?12px;padding:?16px;
}/*?如果卡片包含圖片,使用兩行布局?*/
.card:has(img)?{grid-template-rows:?auto?1fr;
}/*?容器查詢?+?:has():小容器中,有圖片的卡片改為單列?*/
@container?(max-width:?320px)?{.card:has(img)?{grid-template-columns:?1fr;grid-template-rows:?auto?auto?1fr;}
}

? 組件真正實現了“內容感知”與“容器感知”。


六、高級用法與技巧

1. 多條件匹配(與邏輯)

/*?同時包含?h2?和?.btn?的?header?*/
header:has(h2):has(.btn)?{padding:?2rem;background:?#e3f2fd;
}

2. 否定匹配(結合 :not())

/*?不包含圖片的卡片?*/
.card:not(:has(img))?{font-size:?1.1em;
}

3. 表格行高亮(懸停整行)

/*?當?td?被懸停時,高亮其父?tr?*/
tr:has(td:hover)?{background-color:?#f5f5f5;
}

七、瀏覽器兼容性

瀏覽器支持情況
Chrome105+ ?
Edge105+ ?
Safari15.4+ ?
Firefox121+ ?
iOS Safari15.4+ ?

📊 數據來源:Can I use :has()

?? 注意:目前 IE 和舊版瀏覽器不支持,生產環境建議結合漸進增強策略使用。


八、與 JavaScript 的對比

過去類似功能需 JS 實現:

document.querySelectorAll('.card').forEach(card?=>?{if?(card.querySelector('img'))?{card.classList.add('has-image');}
});

:has() 的優勢:

  • 無需 JS,減少腳本依賴。

  • 性能更高,由瀏覽器原生優化。

  • 更簡潔,樣式邏輯集中在 CSS 中。


九、總結

:has() 選擇器是 CSS 發展史上的里程碑特性:

  • ? 實現了“父選擇器”功能,打破 CSS 選擇方向限制。

  • ? 與容器查詢結合,推動組件化、響應式設計進入新階段。

  • ? 減少對 JavaScript 的依賴,提升樣式表達能力。

隨著瀏覽器支持度不斷提升,:has() 將成為現代前端開發的必備技能

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/96682.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96682.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96682.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

李宏毅 Deep Learning

感謝李宏毅老師qwq1. 基礎概念1.1 Machine Learning問題引出&#xff1a;預測后面幾天的觀看人數&#xff1b;初步構建模型&#xff1a;擬合效果不好&#xff0c;就是在原數據上平移了一段距離&#xff1b;此處構建模型的本質&#xff1a;利用特征工程&#xff0c;將“多維特征…

【AI論文】分享即關愛:基于集體強化學習經驗共享的高效語言模型(LM)后訓練方法

摘要&#xff1a;利用強化學習&#xff08;RL&#xff09;對語言模型&#xff08;LMs&#xff09;進行后訓練&#xff0c;無需監督微調即可增強其復雜推理能力&#xff0c;DeepSeek-R1-Zero便證明了這一點。然而&#xff0c;要有效利用強化學習訓練語言模型&#xff0c;需要進行…

工業網關在汽車沖壓車間的應用:EtherNet/IP轉EtherCAT集成實踐

在汽車零部件沖壓車間中&#xff0c;生產線的高效協同與精準控制是提升整體產能的關鍵。隨著自動化設備的多樣化&#xff0c;不同協議的設備之間的通信成為技術難點。例如&#xff0c;羅克韋爾PLC通常采用EtherNet/IP協議&#xff0c;而許多高性能機械臂則依賴EtherCAT協議。如…

【底層機制】【C++】std::move 為什么引入?是什么?怎么實現的?怎么正確用?

C++底層機制推薦閱讀 【C++基礎知識】深入剖析C和C++在內存分配上的區別 【底層機制】【C++】vector 為什么等到滿了才擴容而不是提前擴容? 【底層機制】malloc 在實現時為什么要對大小內存采取不同策略? 【底層機制】剖析 brk 和 sbrk的底層原理 【底層機制】為什么棧的內存…

Redis面試相關

數據過期策略 惰性刪除 當用到那個key的時候再檢查是否過期&#xff0c;過期則刪除&#xff0c;有效則返回key 優點是可以節省檢查過期的時間 缺點是會浪費內存 定期刪除 每隔一段時間對一些key進行檢查并且刪除里面的過期key 有兩種模式 slow模式是定時任務&#xff0c;頻率是…

知識輸出零散沒有體系怎么辦

當面臨知識輸出零散、不成體系的困境時&#xff0c;其根本原因在于未能建立一個從輸入、整合到輸出的閉環系統。要解決這一問題&#xff0c;核心在于構建個人知識管理體系、掌握結構化思維與表達能力、運用合適的工具與方法進行固化、持續實踐并迭代優化。這意味著&#xff0c;…

【C語言選擇排序算法詳解】+ 算法性能優化 + 動態演示實現

文章目錄一、算法介紹二、算法特點三、代碼實現與解析四、代碼解析1. 打印數組函數2. 選擇排序核心邏輯3. 動態展示實現4. 主函數五、算法優化思路與實現優化1&#xff1a;減少交換次數優化原理&#xff1a;優化2&#xff1a;雙向選擇排序優化原理&#xff1a;優化3&#xff1a…

棧(Java)

提示&#xff1a;多練才是王道,加油?(?????)? 棧Java1. 棧2. Java中棧的其中兩種實現方式2.1 Stack類2.1.1 Stack的模擬實現2.2 LinkedList類3. 典型習題講解3.1 逆波蘭表達式求值3.2 匹配括號3.3 合理彈出序列3.4 最小棧1. 棧 棧是一種特殊的線性表,其只允許在固定的一…

LayaAir鼠標(手指)控制相機旋轉,限制角度

切換天空盒腳本掛載到相機身上 const { regClass, property } Laya;regClass() export class SmoothCameraController extends Laya.Script {declare owner: Laya.Camera;// 旋轉靈敏度property({ type: Number, name: "旋轉靈敏度" })public rotationSensitivity:…

【數據結構入門】排序算法(4)歸并排序

目錄 1.排序的原理 1.1 保證子數組有序 1.2 時間復雜度 2. 遞歸實現 2.1 思路 2.2 代碼 3. 非遞歸實現 3.1 思路 3.2 代碼 4.面試題 4.1 題目 4.2 思路 1.排序的原理 歸并排序是外排序&#xff0c;所謂外排序就是說能夠對文件中的數據進行排序。 ①首先&#xff…

FLEXSPI_Init 硬件故障問題

使用官方例程發現FLEXSPI_Init會引起硬件故障&#xff0c;查閱相關帖子發現主要有兩個可能&#xff1a;1、外部閃存配置差異修改 LUT&#xff08;查找表&#xff09;命令&#xff1a;示例中擦除扇區命令為 0xD7&#xff0c;寫狀態寄存器命令為 0x01&#xff0c;需分別改為 閃存…

如何用 Rust 重寫 SQLite 數據庫(一):項目探索

要使用 Rust 重寫 SQLite 數據庫&#xff0c;我們需要實現一個簡化的關系型數據庫核心功能&#xff08;如 SQL 解析、存儲引擎、事務管理&#xff09;。以下是一個分步實踐指南&#xff0c;包含關鍵代碼示例。一、項目規劃 我們將實現一個超簡化數據庫 MiniSQL&#xff0c;支持…

JVM之堆(Heap)

一、堆的核心特性 唯一性與共享性 每個JVM實例僅有一個堆&#xff0c;所有線程共享&#xff0c;但可通過線程私有緩沖區&#xff08;TLAB&#xff09;減少多線程分配沖突。內存結構演變 JDK 7及之前&#xff1a;堆分為新生代&#xff08;Young&#xff09;、老年代&#xff08;…

單片機的RAM與ROM概念

RAM與ROM1、RAM與ROM2、 bss、data、heap、stack、text詳細講解3、詳細探討 TCM、OCRAM 和 HBNRAM 之間的區別及其具體作用。3.1、TCM&#xff08;Tightly Coupled Memory&#xff09;3.2、 OCRAM&#xff08;On Chip RAM&#xff09;3.3、HBNRAM (Hibernate RAM)3.4、總結1、R…

實驗3:事件處理(2學時)

實驗目的&#xff08;1&#xff09;熟練掌握 v-on 指令的用法&#xff0c;學會使用 v-on 指令監聽 DOM 元素的事件&#xff0c;并通過該事件觸發調用事件處理程序。&#xff08;2&#xff09;掌握v-on 指令修飾符的基本用法。實驗內容實現購物車功能的拓展&#xff08;商品數量…

商品庫存扣減方案

文章目錄1. Lua腳本 Redis&#xff08;業界首選&#xff0c;綜合最優&#xff09;2. Redis原子命令&#xff08;DECRBY 結果校驗&#xff09;3. Redis事務&#xff08;MULTI/EXEC&#xff09;4. 分布式鎖&#xff08;基于Redis實現&#xff09;5. Redisson客戶端封裝&#xf…

關于在阿里云DMS誤操作后如何恢復數據的記錄

前言 昨天因客戶員工操作錯誤&#xff0c;導致快遞單號和訂單互換。客戶員工那邊讓筆記修改數據。 于是筆者寫下如下SQL來操作&#xff0c;導致了災難性事故。 update t_order_fed_ex_record set tracking_number 884102170661, master_tracking_number 884102170661, push…

【操作系統核心知識梳理】線程(Thread)重點與易錯點全面總結

在多任務操作系統中&#xff0c;線程是比進程更輕量的執行單元&#xff0c;理解線程的特性和實現方式是掌握并發編程的基礎。本文系統梳理了線程相關的核心知識點和常見誤區&#xff0c;助你夯實操作系統基礎。一、線程的基本概念與引入目的 1.1 什么是線程&#xff1f; 線程是…

深入理解 Python 中的 `__call__` 方法

化身為可調用的對象&#xff1a;深入理解 Python 中的 __call__ 方法 引言&#xff1a;函數與對象的邊界模糊化 在 Python 中&#xff0c;我們最熟悉的概念莫過于函數&#xff08;Function&#xff09; 和對象&#xff08;Object&#xff09;。函數是可調用的&#xff08;calla…

云服務器使用代理穩定與github通信方法

使用SSH反向隧道 (SSH Reverse Tunneling) 利用SSH連接在您的本地電腦和云服務器之間建立一個反向的加密通道。 原理&#xff1a; 從本地電腦發起一個SSH命令到您的云服務器&#xff0c;這個命令會告訴云服務器&#xff1a;“請監聽您自己的某個端口&#xff08;例如&#xff1…