# css 選擇器
[toc]
## 1. 簡單選擇器
### 1.1 種類
| 序號 | 選擇器 | 描述 | 舉例 |
| ---- | ---------- | --------------------------- | ---------------- |
| 1 | 元素選擇器 | 根據元素標簽名稱進行匹配 | `div {...}` |
| 2 | 群組選擇器 | 同時選擇多個不同類型的元素 | `h1,h2,h3{...}` |
| 3 | 通配選擇器 | 選擇全部元素,不區分類型 | `* {...}` |
| 4 | 屬性選擇器 | 根據元素屬性進行匹配 | `*[...]` |
| 5 | 類選擇器 | 根據元素 class 屬性進行匹配 | `*.active {...}` |
| 6 | id 選擇器 | 根據元素 id 屬性進行匹配 | `*#top {...}` |
- 元素是使用**標簽和屬性**進行描述,所以使用標簽和屬性來選擇元素非常自然和直觀
- 以上 6 種,其實可分為二類: 元素選擇器和屬性選擇器, 其它的只是二者的特例罷了
- 最常用的是: **元素選擇器, 類選擇器, id 選擇器**
- 當 class,id 選擇器不限定被修改的元素類型時, 星號"`*`"可以省略
### 1.2 示例
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>簡單選擇器</title>
<style>
/* 使用九宮格演示選擇器 */
/* 以下grid, flex布局實現一個九宮格,語法未學到請先忽略 */
/* 類選擇器 */
.container {
width: 300px;
height: 300px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 5px;
}
.item {
font-size: 2rem;
background-color: lightskyblue;
display: flex;
justify-content: center;
align-items: center;
}
/* 簡單選擇器 */
/* 元素選擇器 */
body {
background-color: lightcyan;
}
/* 多類選擇器 */
.item.center {
background-color: lightgreen;
}
/* id選擇器 */
*#first {
background-color: lime;
}
/* id,class默認可添加到所有元素上,所以可省略*/
/* 特別提示: id唯一性由用戶保證,瀏覽器不檢查,應確保唯一,防止JS獲取失敗 */
#first {
background-color: lightpink;
}
/* 為什么id前添加class選擇器仍然有效呢,這是選擇器的權重: class > 元素 */
.item#first {
background-color: lemonchiffon;
}
/* id的優先級大于class */
#first.item {
background-color: violet;
}
/* 樣式權重優先級: 元素 < 類樣式 < ID */
</style>
</head>
<body>
<div class="container">
<div class="item" id="first">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item center">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
</html>
```
---
## 2. 上下文選擇器
- html 文檔,看上去就像一顆倒置的"樹",所以是有層級結構的
- 每一個元素, 在文檔中, 都有自己的位置,即上下文關系
- 所以, 完全可以根據元素的上下文關系,來獲取到它們
### 2.1 一個元素的四種角色
| 序號 | 角色 | 描述 |
| ---- | -------- | ------------------------------------- |
| 1 | 祖先元素 | 擁有子元素,孫元素等所有層級的后代元素 |
| 2 | 父級元素 | 僅擁有子元素層級的元素 |
| 3 | 后代元素 | 與其它層級元素一起擁有共同祖先元素 |
| 4 | 子元素 | 與其它同級元素一起擁有共同父級元素 |
### 2.2 四種上下文選擇器
| 序號 | 選擇器 | 操作符 | 描述 | 舉例 |
| ---- | -------------- | ------ | ------------------------------ | ----------------- |
| 1 | 后代選擇器 | `空格` | 選擇當前元素的所有后代元素 | `div p`, `body *` |
| 2 | 父子選擇器 | `>` | 選擇當前元素的所有子元素 | `div > h2` |
| 3 | 同級相鄰選擇器 | `+` | 選擇擁有共同父級且相鄰的元素 | `li.red + li` |
| 4 | 同級所有選擇器 | `~` | 選擇擁有共同父級的后續所有元素 | `li.red ~ li` |
### 2.3 示例
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>上下文選擇器</title>
<style>
/* 使用九宮格演示選擇器 */
/* 以下grid, flex布局實現一個九宮格,語法未學到請先忽略 */
.container {
width: 300px;
height: 300px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 5px;
}
.item {
font-size: 2rem;
background-color: lightskyblue;
display: flex;
justify-content: center;
align-items: center;
}
/* 后代選擇器 */
.container div {
border: 1px solid coral;
}
/* 父子選擇器,只有外層容器div受影響,內部單元格div不受影響 */
body > div {
border: 3px solid green;
}
/* 同級相鄰選擇器 */
/* 當前是第5個,相鄰的下一個就是第6個單元格 */
.item.center + .item {
background-color: lightgreen;
}
/* 同級所有選擇器 */
.item.center ~ .item {
background-color: lightsalmon;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item center">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
</html>
```
---
## 3. 偽類選擇器
- 學習之前,先分析上下文選擇器的局限性,例如選擇同一個父級下的第二個子元素,就沒那么簡單
- 而偽類就正好彌補了上下文選擇器的短板, 所以偽類,大多數是基于文檔中元素結構的
- **偽**: 本意是假的,不存在的意思, 這里是特指, 不需要在元素上添加額外的屬性來獲取元素
- **類**: 暗指偽類的級別, 仍然是屬于"class"級別, 仍然屬于屬性選擇器范疇,級別高于元素選擇器
我們重點放在偽類最重要的應用場景:
| 場景 | 描述 |
| -------- | ---------------------------- |
| 結構偽類 | 根據子元素的位置特征進行選擇 |
| 表單偽類 | 根據表單控件狀態特征進行選擇 |
### 3.1 結構偽類
#### 3.1.1 不分組匹配
| 序號 | 選擇器 | 描述 | 舉例 |
| ---- | -------------------- | ------------------------ | ------------------------ |
| 1 | `:first-child` | 匹配第一個子元素 | `div :first-child` |
| 2 | `:last-child` | 匹配最后一個子元素 | `div :last-child` |
| 3 | `:only-child` | 選擇元素的唯一子元素 | `div :only-child` |
| 4 | `:nth-child(n)` | 匹配任意位置的子元素 | `div :nth-child(n)` |
| 5 | `:nth-last-child(n)` | 匹配倒數任意位置的子元素 | `div :nth-last-child(n)` |
示例代碼:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>結構偽類選擇器: 不分組匹配</title>
<style>
/* 使用九宮格演示選擇器 */
/* 以下grid, flex布局實現一個九宮格,語法未學到請先忽略 */
.container {
width: 300px;
height: 300px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 5px;
}
.item {
font-size: 2rem;
background-color: lightskyblue;
display: flex;
justify-content: center;
align-items: center;
}
/* 省略父元素,則是給'html'元素的子元素添加背景,html只有2個子元素:head,body */
:first-child {
background-color: wheat;
}
/* 匹配第一個子元素 */
/* 不指定具體父元素, 則會從html開始依次查詢每一個子元素*/
/* 從html開始依次遞歸獲取每一個元素的第一個子元素并添加背景 */
/*<head>, div.container, 第一個div.item 會選中*/
* > :first-child {
background-color: yellow;
}
/* 為防止這種遞歸設置, 應該在具體父元素上調用 */
.container > :first-child {
background-color: lightgreen;
}
/* 偽類前默認為通用選擇器* */
.container > *:first-child {
background-color: lightgreen;
}
/* 可以在偽類前指定具體元素 */
/* 因為大家都有.item類,指不指定無所謂,但權重大于默認的**/
.container > .item:first-child {
background-color: lightgrey;
}
/* 匹配最后一個子元素 */
.container > :last-child {
background-color: lightpink;
}
/* 匹配任意位置的子元素 */
/* 索引是從1開始計數 */
/* 該偽類就是用來獲取子元素, 所以選擇器中間的 ">"可省略 */
.container :nth-child(3) {
background-color: limegreen;
}
/* :nth-child()的參數可以使用表達式 */
/* 例如選中所有的偶數單元格: 表達式中的 "n" 是從 "0" 開始的整數,且必須寫到前面*/
/* 返回的必須是有效的索引,即在(1-9)之間 */
.container :nth-child(2n) {
background-color: magenta;
}
/* (2n)可用關鍵字even代替 */
.container :nth-child(even) {
background-color: magenta;
}
/* 選中所有的奇數單元格*/
.container :nth-child(2n-1) {
background-color: lightcoral;
}
/* (2n-1)可用關鍵字odd代替 */
.container :nth-child(odd) {
background-color: lightcoral;
}
/* 為什么第一個奇數單元格會變色,原因是:first-child前用了類選擇器,權重高于默認的通用選擇器* */
/* 去掉.item:first-child 前面的.item, 背景就會變成"lightcoral" */
/* 也可只選擇一部分,例如前三個 */
.container .item:nth-child(-n + 3) {
background-color: lightseagreen;
}
/* 選擇倒數第2個 */
.container .item:nth-last-child(2) {
background-color: lime;
}
/* 選擇最后3個 */
.container .item:nth-last-child(-n + 3) {
background-color: lime;
}
/* 從指定位置開始選擇 */
/* 從第4個單元格開始選擇剩下所有元素 */
.container .item:nth-child(n + 4) {
background-color: lightgray;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
</html>
```
#### 3.1.2 分組匹配
| 序號 | 選擇器 | 描述 | 舉例 |
| ---- | --------------------- | ------------------------------------ | -------------------------- |
| 1 | `:first-of-type` | 匹配按類型分組后的第一個子元素 | `div :first-of-type` |
| 2 | `:last-of-type` | 匹配按類型分組后的最后一個子元素 | `div :last-of-type` |
| 3 | `:only-of-type` | 匹配按類型分組后的唯一子元素 | `div :only-of-type` |
| 4 | `:nth-of-type()` | 匹配按類型分組后的任意位置的子元素 | `div :nth-of-type(n)` |
| 5 | `:nth-last-of-type()` | 匹配按類型分組后倒數任意位置的子元素 | `div :nth-last-of-type(n)` |
- 允許使用表達式來匹配一組元素,表達式中的"n"是從"0"開始計數,且必須寫到前面
- "-n"表示獲取前面一組元素,正數表示從指定位置獲取余下元素
示例代碼:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>結構偽類選擇器: 分組匹配</title>
<style>
/* 使用九宮格演示選擇器 */
/* 以下grid, flex布局實現一個九宮格,語法未學到請先忽略 */
.container {
width: 300px;
height: 300px;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 5px;
}
.item {
font-size: 2rem;
background-color: lightskyblue;
display: flex;
justify-content: center;
align-items: center;
}
/* 選中第一個span元素: 匹配不上 */
.container span:first-child {
background-color: violet;
}
/* 換成first-of-type, 就匹配上了 */
.container span:first-of-type {
background-color: violet;
}
/*
所謂分組匹配其實有二步:
第一步: 對滿足條件的元素進行分組
第二步: 在分組中根據位置匹配元素
*/
/* 匹配分組中的最后一個 */
.container span:last-of-type {
background-color: violet;
}
/* 匹配任何一個 */
.container span:nth-of-type(3) {
background-color: violet;
}
/* 支持表達式: 匹配前3個 */
.container span:nth-of-type(-n + 3) {
background-color: lightgrey;
}
/* 匹配最后2個 */
.container span:nth-last-of-type(-n + 2) {
background-color: limegreen;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<!-- 修改dom結構,最后二排使用span元素 -->
<span class="item">4</span>
<span class="item">5</span>
<span class="item">6</span>
<span class="item">7</span>
<span class="item">8</span>
<span class="item">9</span>
</div>
</body>
</html>
```
### 3.2 表單偽類
| 序號 | 選擇器 | 描述 |
| ---- | ---------------- | ------------------------------- |
| 1 | `input:enabled` | 選擇每個啟用的 `<input>` 元素 |
| 2 | `input:disabled` | 選擇每個禁用的 `<input>` 元素 |
| 3 | `:checked` | 選擇每個被選中的 `<input>` 元素 |
| 4 | `:required` | 包含`required`屬性的元素 |
| 5 | `:optional` | 不包含`required`屬性的元素 |
| 6 | `:valid` | 驗證通過的表單元素 |
| 7 | `:invalid` | 驗證不通過的表單 |
| 8 | `:read-only` | 選擇只讀表單元素 |
示例代碼:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>表單偽類選擇器</title>
<style>
form {
display: flex;
flex-flow: column nowrap;
}
/*表單偽類選擇器*/
/*選擇所有有效的input表單元素*/
/*下拉列表雖有效,但不是input,所以未選中*/
/*警告信息是禁用項, 所以未選中*/
/*保存密碼項實際上選中的, 通過檢查元素可以查詢*/
input:enabled {
background-color: blanchedalmond;
}
/*選擇禁用元素*/
input:disabled {
background-color: lightgray;
}
/*選擇所有必選項*/
input:required {
background-color: yellow;
}
/*更多選項, 供大家上機練習*/
</style>
</head>
<body>
<h3>用戶登錄</h3>
<form action="" method="post">
<div>
<label for="email">郵箱:</label>
<input type="email" id="email" name="email" required placeholder="example@email.com" />
</div>
<div>
<label for="password">密碼:</label>
<input type="password" id="password" name="password" required placeholder="不得少于6位" />
</div>
<div>
<label for="save">保存密碼:</label>
<input type="checkbox" id="save" name="save" checked readonly />
</div>
<div>
<label for="save_time">保存期限:</label>
<select name="save_time" id="save_time">
<option value="7" selected>7天</option>
<option value="30">30天</option>
</select>
</div>
<div>
<input type="hidden" name="login_time" value="登陸時間戳" />
</div>
<div>
<label for="warning">警告:</label>
<input type="text" id="warning" value="一天內僅允許登錄三次" style="border:none" disabled />
</div>
<script>
// js未學,暫時忽略,只須知道功能即可: 自動生成時間戳,填充到表單隱藏域中
document.querySelector('[type="hidden"]').value = new Date().getTime();
</script>
</form>
</body>
</html>
```
### 3.3 其它偽類
| 序號 | 選擇器 | 描述 |
| ---- | ---------- | -------------------------------------- |
| 1 | `:active` | 向被激活的元素添加樣式 |
| 2 | `:focus` | 向擁有鍵盤輸入焦點的元素添加樣式 |
| 3 | `:hover` | 當鼠標懸浮在元素上方時,向元素添加樣式 |
| 4 | `:link` | 向未被訪問的鏈接添加樣式 |
| 5 | `:visited` | 向已被訪問的鏈接添加樣式 |
| 5 | `:root` | 根元素,通常是`html` |
| 5 | `:empty` | 選擇沒有任何子元素的元素(含文本節點) |
| 5 | `:not()` | 排除與選擇器參數匹配的元素 |
示例代碼:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>其它偽類</title>
<style>
/*根元素*/
:root {
background-color: lightcyan;
}
/*排除元素*/
nav * {
/*background-color: lightgreen;*/
}
/*排除掉第一個:首頁*/
nav :not(:first-child) {
background-color: lightgreen;
}
/*空元素*/
nav :empty {
display: inline-block;
height: 20px;
width: 100px;
background-color: yellow;
}
/*鏈接偽類*/
a:hover {
background-color: #444444;
color: white;
}
a:active,
a:focus {
background-color: red;
}
a:visited {
background-color: yellow;
color: red;
}
</style>
</head>
<body>
<nav>
<a href="">首頁</a>
<a href="">視頻教程</a>
<a href="">社區問答</a>
<a href="">工具軟件</a>
<!-- <a href=""></a>-->
</nav>
</body>
</html>
```
### 3.4 偽元素
- 偽元素, 顧名思義, HTML 源碼并不存在, 而是通過 CSS 添加的
- 主要用于修飾某些元素,添加效果,但又不希望占用元素資源
- 通常與`content`屬性配合使用
| 序號 | 選擇器 | 描述 |
| ---- | ---------- | ------------------ |
| 1 | `::after` | 在當前元素之后添加 |
| 2 | `::before` | 在當前元素之前添加 |
示例代碼:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>偽元素</title>
<style>
/*不會出現在DOM結構中, 不占用頁面空間*/
a::before {
content: "Hello ";
}
a::after {
/*content: ' 歡迎您~~';*/
}
/*可調用當前元素的屬性*/
a::after {
content: "--" attr(href) "--";
}
/*可以插入圖片*/
a:before {
content: url("1.jpg");
/*圖片樣式可使用JS修改*/
}
</style>
</head>
<body>
<a href="htts://www.php.cn">php中文網</a>
</body>
</html>
```
- 教學大綱
- HTML5基礎
- 1-html基礎知識
- 2-語義化結構元素
- 3-語義化文本元素
- 4-鏈接/列表/圖像元素
- 5-表格元素
- 6-表單與控件元素[重點]
- CSS3基礎
- 1-css與html文檔
- 2-css選擇器
- 3-細說盒模型
- Flex布局[精簡版]
- 1-Flex概論
- 2-Flex布局是什么
- 3-Flex基本概念
- 4-Flex容器屬性
- 5-Flex項目屬性
- Flex布局[細說版]
- 1-flex 布局概述
- 2-flex 容器與項目
- 3-flex 容器主軸方向
- 4-flex 容器主軸項目換行
- 5-flex 容器主軸與項目換行簡寫
- 6-flex 容器主軸項目對齊
- 7-flex 容器交叉軸項目對齊
- 8-flex 多行容器交叉軸項目對齊
- 9-flex 項目主軸排列順序
- 10-flex 項目交叉軸單獨對齊
- 11-flex 項目放大因子
- 12-flex 項目收縮因子
- 13-flex 項目計算尺寸
- 14-flex 項目縮放的簡寫
- Flex布局[案例版]
- 1-調整項目順序
- Grid布局[精簡版]
- 1. 常用術語
- 2. 容器屬性
- 3. 項目屬性
- 4. 布局實例
- 1. 經典三列布局
- 2. 媒體查詢
- Grid布局[細說版]
- 1-必知術語
- 2-容器創建與行列劃分
- 3-單元格常用單位
- 4-項目填充到單元格
- 5-項目填充到網格區域
- 6-對齊容器中的所有項目
- 7-對齊單元格中所有項目
- 8-對齊單元格中某個項目
- 9-容器中行與列之間的間距