National Central University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try an AI Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

3

Local AI

--

Uedu Code

--

中央大學 AQI 80 24°C PM2.5 21
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 10

選擇器

class、id、屬性、組合、虛擬類別與虛擬元素
Interaction 25 minute(s)

Learning Objectives

  • 用元素、class、id、全域與屬性選擇器選中元素,並用逗號把規則套到多個選擇器
  • 分辨子孫(空白)、子(>)、相鄰兄弟(+)、一般兄弟(~)四種組合器
  • 用 :hover、:focus、:first-child、:nth-child()、:not() 依狀態或位置選擇元素
  • 用 ::before、::after、::first-line 替元素的一部分加樣式,並知道 ::before 需要 content
  • 依用途選擇 class 或 id,用描述意義的名稱命名

選擇器決定規則套用在誰身上

上一課的規則都很單純:h1 { … } 套用到所有 h1。但真實的網頁常常需要更精準:

  • 導覽列裡的連結和文章裡的連結長得不一樣。
  • 只有「熱門」的標籤要紅色,其他標籤維持灰色。
  • 表格的偶數列加底色,方便眼睛對齊。
  • 連到外部網站的連結後面加一個小圖示。

這些都不需要改 HTML,只要寫出剛好選中那些元素的選擇器(selector)。這一課把常用的選擇器分成四類: 基本選擇器、組合器(看元素之間的關係)、虛擬類別(看位置或狀態)、虛擬元素(選元素的一部分)。

基本選擇器

選擇器 寫法 選中
元素(type) p 所有 <p>
class .tag 所有 class 屬性裡有 tag 的元素
id #music id="music" 的那一個元素
全域(universal) * 所有元素
屬性(attribute) [target] 有 target 屬性的元素

一個元素可以有好幾個 class,用空白隔開:<span class="tag hot">。選擇器可以把條件連在一起寫(中間不留空白),表示「同時符合」: span.tag.hot 是「class 同時有 tag 和 hot 的 span」。

屬性選擇器還能比對屬性值:

寫法 意思 例子
[href="https://example.com"] 值完全相等
[href^="https"] 值開頭是 https 外部連結
[href$=".pdf"] 值結尾是 .pdf 下載檔案的連結
[href*="example"] 值包含 example
[class~="hot"] 值用空白分開的字裡有 hot(和 .hot 一樣)

群組:幾個選擇器要套同一組宣告時,用逗號隔開,不必重寫:

h1, h2, h3 { color: #3C6F9A; }    /* 三種標題都套用 */

組合器:依元素之間的關係選擇

HTML 是一棵樹(第 2 課的 DOM 樹)。組合器(combinator)寫在兩個選擇器中間,說明它們在樹上的關係:

組合器 寫法 選中 例子
子孫(descendant) A B(空白) A 裡面任何一層的 B nav a:導覽列裡所有的連結
子(child) A > B A 下一層的 B .links > li:只有第一層清單項目
相鄰兄弟(next-sibling) A + B 緊接在 A 後面的那一個 B h2 + p:標題正下方的第一段
一般兄弟(subsequent-sibling) A ~ B A 後面同一層的所有 B h2 ~ p:標題後面的每一段

用社團活動週的頁面來看:

<nav class="menu">
  <ul>
    <li><a href="#music">音樂</a></li>
  </ul>
</nav>
  • .menu a 選得到連結:a 在 nav 裡面(隔了 ul、li 兩層也算)。
  • .menu > a 選不到:nav 的下一層是 ul,不是 a。

選擇器是由右往左讀的:.menu a 先找所有的 a,再看它有沒有一個祖先是 .menu。最右邊那一個才是真正被選中、套用樣式的元素。

小測驗:基本選擇器與組合器

1.

HTML 是 <nav class="menu"><ul><li><a href="#">音樂</a></li></ul></nav>。哪個選擇器選得到那個 a?

2.

h1, h2 { color: navy; } 的意思是?

3.

a[href$=".pdf"] 選得到下面哪一個連結?

第 1 次作答

虛擬類別與虛擬元素

虛擬類別(pseudo-class)以一個冒號開頭,依元素的狀態或位置選擇,這些資訊不寫在 HTML 裡:

虛擬類別 選中
:hover 滑鼠移到上面的元素
:focus 目前得到焦點的元素(點選輸入框、用 Tab 移過去)
:first-child/:last-child 在兄弟裡排第一個/最後一個
:nth-child(2) 排第 2 個;(odd) 奇數、(even) 偶數、(3n) 每 3 個
:not(.hot) 不符合括號裡條件的元素
.schedule tr:nth-child(even) { background-color: #f1f5f9; }   /* 斑馬紋 */
a:hover { text-decoration: none; }
input:focus { outline: 3px solid #3C938A; }

:hover 和 :focus 要成對想:用鍵盤操作的人沒有滑鼠,只靠 :focus 看得出自己在哪裡。不要把 focus 的外框拿掉而不給替代樣式。

虛擬元素(pseudo-element)以兩個冒號開頭,選的是元素的一部分,或在元素前後產生內容:

虛擬元素 選中
::before/::after 在元素內容的最前面/最後面產生一段內容,必須搭配 content
::first-line 第一行(隨視窗寬度改變)
::first-letter 第一個字
::placeholder 輸入框的提示文字
.required::after { content: " *"; color: #B5524C; }

::before、::after 產生的內容不在 HTML 裡,螢幕閱讀器不一定會唸,所以只用在裝飾性的東西; 例如必填的星號只是視覺提示,欄位本身仍要加 required 屬性(第 7 課)。

互動練習:斑馬紋、必填星號與第一欄

課程進度表和報名表單都還沒有樣式。只用虛擬類別與虛擬元素完成任務,不要改 HTML、不要加 class。

選擇器實驗室

在輸入框打一個選擇器,預覽會把選到的元素框起來,右邊的 HTML 結構也會標出來。先按幾個範例試試,再完成任務:每個任務都要「剛好」選到指定的元素,多一個少一個都不算。

class 還是 id?怎麼命名?

class id
一頁可以出現幾次 很多次,一個元素也可以有好幾個 class 只能一次,一頁裡不能重複
主要用途 套樣式:同一種外觀的元素 頁內錨點(第 4 課的 #music)、表單 label 的 for、JavaScript 找特定元素
選擇器的強度 普通 很強,之後很難覆蓋(下一課的權重)

所以樣式一律用 class,id 留給錨點和 label。

命名的習慣:

  • 描述用途,不描述外觀:.note、.tag、.btn-primary 比 .yellow-box、.red-text 好;之後把提醒改成藍色,.yellow-box 就名不符實了。
  • 全部小寫,多個字用連字號連接(kebab-case):.club-card、.nav-link。
  • 元件裡的部分可以用「元件名稱+部分」:.club-card、.club-card-title。有些團隊用 BEM 這類命名規則(.card__title、.card--featured),重點是整個專案用同一套。
  • 選擇器不要寫太長:body main section.club div p span.tag 很難讀,而且 HTML 結構一改就失效;.club .tag 通常就夠了。

小測驗:虛擬類別、虛擬元素與命名

1.

一份清單有 5 個 li,li:nth-child(odd) 會選到哪幾個?

2.

section 裡依序是 h2、p、p、ul。h2 + p 選到什麼?

3.

寫了 .new::before { color: red; },畫面上卻什麼都沒出現。最可能的原因是?

4.

活動頁有 6 張外觀相同的社團卡片,要替它們加樣式。用什麼比較好?

第 1 次作答

重點整理

  • 基本選擇器:元素 p、class .tag、id #music、全域 *、屬性 [href^="https"];條件連寫表示同時符合,逗號表示群組。
  • 組合器:空白(任何一層的子孫)、>(下一層)、+(緊接在後的兄弟)、~(後面所有兄弟);選擇器由右往左讀,最右邊是被選中的元素。
  • 虛擬類別看狀態與位置::hover、:focus、:first-child、:nth-child()、:not();不要拿掉 focus 外框而不給替代。
  • 虛擬元素選元素的一部分:::before/::after 要搭配 content,只放裝飾性內容。
  • 樣式用 class,id 留給錨點與 label;名稱描述用途,不描述外觀。

下一課講層疊與權重:同一個元素被好幾條規則選中、而且設定互相衝突時,瀏覽器怎麼決定聽誰的。

這一課完成了!
Next lesson:層疊、權重與繼承
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。