虛擬類別選擇器 ( 表單輸入 )
虛擬類別選擇器有許多種,這篇教學會介紹「表單輸入」相關的虛擬類別選擇器,例如 :checked、:disabled、:in-range、:valid、:required 等等,運用這些虛擬類別選擇器,就能精準控制輸入元素在不同狀態下的樣式。
「表單輸入」虛擬類別選擇器
下方列出和「表單輸入」有關的虛擬類別選擇器 ( 支援度 All 表示主流瀏覽器都支援 ):
虛擬類別選擇器 | 說明 | 支援度 |
---|---|---|
:checked | 被勾選的狀態。 | All |
:disabled、:enabled | 禁用或啟用。 | All |
:read-only、:read-write | 唯獨或可以讀寫。 | IE 不支援 |
:in-range、:out-of-range | 數值範圍之內或之外。 | IE 不支援 |
:valid、:invalid | 是否通過驗證規則。 | 部分情況 IE 不支援 |
:user-valid、:user-invalid | 與使用者互動後判斷是否通過驗證規則。 | IE 不支援 |
:required、:optional | 必填或選填。 | All |
:default | 預設選取的元素。 | IE 不支援 |
:placeholder-shown | 沒有輸入文字顯示預設內容時。 | IE 不支援 |
:indeterminate | 不確定輸入數值。 | IE 不支援 |
:autofill | 由瀏覽器自動填入。 | IE 不支援 |
:checked
「:checked
」表示「被勾選的狀態」,會搭配具有「checkbox
和 radio
」屬性的 input 元素使用,下方的範例使用會在使用者勾選選項時,將勾選框的邊框變成紅色。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
<input type="radio" name="a"><span>Apple</span>
<input type="radio" name="a"><span>Ball</span>
<input type="radio" name="a"><span>Cat</span>
<br>
<input type="checkbox" name="b"><span>Orange</span>
<input type="checkbox" name="b"><span>Banana</span>
<input type="checkbox" name="b"><span>Grap</span>
</form>
<!-- CSS 程式碼 -->
<style>
input:checked {outline: 2px solid red;}
</style>
使用 :checked
通常會搭配「文件結構選擇器」選取「相鄰兄弟」進行樣式調整,如果將 CSS 改成下方的範例,當使用者勾選選項時,選項後方的文字會一併變色。
注意,由於純文字不能當作任何元素,如果後方是接著「沒有任何標籤包覆的純文字」,就無法使用選擇器選取。
input:checked + * {color: red;} /* 勾選元素的相鄰兄弟變成紅色文字 */
:disabled、:enabled
「:disabled
」表示「禁用狀態」,「:enabled
」表示「啟用狀態」,通常會搭配「支援輸入狀態表單元素」一起使用,只要不使用 :disabled
的表單輸入元素,一率表示為 enabled
狀態,兩個狀態必定存在一種,下方的範例執行後,具有 disabled 屬性的輸入元素就會呈現灰色文字、灰色虛線背景,而其他輸入元素則會呈現黃色背景。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
<input type="text" value="oxxo.studio" disabled> <!-- 加上 disabled 屬性 -->
<br>
<input type="password">
<br>
<br>
<textarea cols="20" rows="5" name="content"></textarea>
<br>
<button type="submit">送出</button>
<button type="submit" disabled>重填</button> <!-- 加上 disabled 屬性 -->
</form>
<!-- CSS 程式碼 -->
<style>
form *:disabled {
color: #ccc;
border:1px dashed #bbb;
}
form *:enabled {
background:#ff0;
}
</style>
:read-only、:read-write
「:read-only
」表示「唯讀狀態」,「:read-write
」表示「可讀寫狀態」,通常會搭配「文字輸入的表單元素」一起使用,只要不使用 :read-only
的表單輸入元素,一率表示為 :read-write
狀態,兩個狀態必定存在一種,但如果是按鈕相關的輸入元素,則都使用 :read-only
。
- 注意!
:read-only
選擇器的中間有破折號「-」,但實際屬性名稱卻是「readonly
」。- 有些元素使用
:read-only
選擇器會影響:disabled
樣式,兩者的差異在於「送出表單」時,具有readonly
屬性的內容會被送出,但屬性為disabled
的內容不會被送出。
下方的範例執行後,具有 readonly 屬性的輸入元素就會呈現灰色文字、灰色虛線背景 ( 按鈕也會變成這種狀態 ),而其他輸入元素則會呈現黃色背景。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
<input type="text" value="oxxo.studio" readonly> <!-- 加上 readonly 屬性 -->
<br>
<input type="password">
<br>
<br>
<textarea cols="20" rows="5" name="content"></textarea>
<br>
<button type="submit">送出</button>
<button type="submit">重填</button>
</form>
<!-- CSS 程式碼 -->
<style>
form *:read-only {
color: #ccc;
border:1px dashed #bbb;
}
form *:read-write {
background:#ff0;
}
</style>
:in-range、:out-of-range
「:in-range
」表示「在數值範圍內」,「:out-of-range
」表示「超出數值範圍」,會搭配「具有 min 與 max 屬性」的數字或時間元素一起使用,使用 :out-of-range
時,只要輸入的數值在 min 與 max 數值範圍之外,就會套用相對應的樣式,其他一率表示為 :in-range
狀態,兩個狀態必定存在一種。
下方的範例執行後,當手動輸入的日期或數值超過範圍 ( 不使用下拉選單,因為下拉選單會鎖定範圍 ),背景就會變成紅色。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
範圍 0~100
<br/>
<input type="number" min="0" max="100">
<br/>
<br/>
範圍 2024-05-01 ~ 2024-05-07
<br/>
<input type="date" min="2022-05-01" max="2024-05-07">
</form>
<!-- CSS 程式碼 -->
<style>
form *:out-of-range {
background: red;
}
</style>
:valid、:invalid、:user-valid、:user-invalid
「:valid
」表示「通過驗證規則」,「:invalid
」表示「未通過驗證規則」,會搭配「具有 pattern 正規表達式驗證屬性」的輸入元素一起使用,使用 :invalid
時,只要輸入的數值經過驗證回傳 False ( 未通過驗證 ) 就會套用樣式,其他一率表示為 :valid
狀態,兩個狀態必定存在一種。
「::user-valid
」和「:user-invalid
」也是判斷「有沒有通過驗證規則」,但差別在於 ::user-valid
和 :user-invalid
需要「與使用者的互動」才會進行驗證,:valid
和 :invalid
則是在輸入當下就進行驗證。
下方的範例執行後,第一個輸入欄位限制一定要三個英文大小寫字母,第二個和第三個輸入欄位限制兩個數字,但第三個輸入欄位要在使用者按下 Enter 之後才會驗證,如果沒有通過驗證就會是紅色背景 ( 正規表達式可以使用 ChatGTP 或 Poe.AI 輔助產生 )。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
範圍:三個大小寫英文字母
<br/>
<input type="text" pattern="[A-Za-z]{3}">
<br/>
<br/>
範圍:兩個數字
<br/>
<input type="text" pattern="\b\d{1}\d{1}\b">
<br/>
<br/>
範圍:兩個數字 ( 按下 enter 後才會驗證 )
<br/>
<input class="user" type="text" pattern="\b\d{1}\d{1}\b">
</form>
<!-- CSS 程式碼 -->
<style>
form *:invalid {background: red; }
form .user:invalid {background: white;} /* 避免上一行選擇器影響到背景 */
form .user:user-invalid {background: red;}
</style>
:required、:optional
「:required
」表示「必填」,「:optional
」表示「選填」,使用 :required
時,只要元素具有 required 屬性就會套用樣式,其他一率表示為 :optional
狀態,兩個狀態必定存在一種。下方的範例執行後,必填欄位後方的星號會是紅色,選填欄位則會是黃色背景。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
帳號:<input type="text" required> <span>*</span>
<br>
密碼:<input type="password" required> <span>*</span>
<br>
外號:<input type="text">
<br>
生日:<input type="date">
<br>
<br>
<button type="submit">送出</button>
<button type="submit">重填</button>
</form>
<!-- CSS 程式碼 -->
<style>
form input:required + * {color: red;}
form input:optional {background: yellow;}
</style>
:default
「:default
」表示「預設選項」,對應有「selected
」屬性的表單元素 ( 下拉選單受限於瀏覽器樣式,只有部分瀏覽器支援 )。下方的範例執行後,有 selected 屬性的選項就會變成紅色文字。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
<select>
<optgroup label="iPhone">
<option value="15p">iPhone 15 Pro</option>
<option value="15" selected>iPhone 15</option>
<option value="14p">iPhone 14 Pro</option>
<option value="14">iPhone 14</option>
<option value="13p">iPhone 13 Pro</option>
</optgroup>
<optgroup label="iPad">
<option value="air">iPad Air</option>
<option value="pro">iPad Pro</option>
</optgroup>
</select>
<br/>
<input type="radio" name="a"><span>Apple</span>
<input type="radio" name="a" checked><span>Ball</span>
<input type="radio" name="a"><span>Cat</span>
<br>
<input type="checkbox" name="b"><span>Orange</span>
<input type="checkbox" name="b"><span>Banana</span>
<input type="checkbox" name="b" checked><span>Grape</span>
</form>
<!-- CSS 程式碼 -->
<style>
form *:default {
font-size:100px;
outline:1px solid red;
}
form *:default + * {
color: red;
}
</style>
:placeholder-shown
「:placeholder-shown
」表示「沒有輸入文字顯示預設內容的狀態」,只要元素具有「placeholder
」屬性,在沒有任何輸入內容 ( 包含空白 ) 的狀態下,就會套用這個虛擬類別選擇器的樣式,但只要有輸入內容 ( 包含空白 ) 就會離開這個狀態,下方的範例執行後,預設兩個具有 placeholder 屬性的欄位都會是黃色背景,輸入文字後就會是白色背景。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
帳號:<input type="text" placeholder="oxxo">
<br>
姓名:<input type="password" placeholder="oxxo.studio">
<br>
外號:<input type="password">
<br>
<br>
<button type="submit">送出</button>
<button type="submit">重填</button>
</form>
<!-- CSS 程式碼 -->
<style>
form input:placeholder-shown{
background:yellow;
}
</style>
:indeterminate
「:indeterminate
」表示「不確定輸入數值的狀態」,通常會出現這個狀態表示「使用者尚未輸入、使用 JavaScript 方式自動輸入」,只要是這種狀態的元素,就會套用這個虛擬類別選擇器的樣式,下方的範例執行後,會利用 JavaScript 替每個 input 元素加上 indeterminate 屬性,這時樣式就會套用預設 :indeterminate
選擇器,但如果使用者手動點擊後,這個狀態就會消失,也就不會套用相關樣式。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
<input type="radio" name="a"><span>Apple</span>
<input type="radio" name="a"><span>Ball</span>
<input type="radio" name="a"><span>Cat</span>
</form>
<form action="/test.aspx" method="post">
<input type="checkbox" name="b"><span>Orange</span>
<input type="checkbox" name="b"><span>Banana</span>
<input type="checkbox" name="b"><span>Grape</span>
</form>
<!-- CSS 程式碼 -->
<style>
form input:indeterminate + *{
background:yellow;
}
</style>
<!-- JavaScript 程式碼 -->
<script>
const inputs = document.getElementsByTagName("input");
for (let i = 0; i < inputs.length; i++) {
inputs[i].indeterminate = true;
}
</script>
:autofill
「:autofill
」表示「由瀏覽器自動填入的內容」,通常會出現這個狀態表示「瀏覽器自動抓取快取茲料填入表單」,如果使用者手動點擊後,這個狀態就會消失,也就不會套用相關樣式。 ,下方的範例執行後,會利用 JavaScript 替每個 input 元素加上 indeterminate 屬性,這時樣式就會套用預設 :indeterminate
選擇器,但如果使用者手動點擊後,這個狀態就會消失,也就不會套用相關樣式。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
email: <input type="email" name="email" autocomplete="email">
<br>
url: <input type="url" name="url" autocomplete="url">
<br>
<input type="submit" style="margin-top:10px;">
</form>
<!-- CSS 程式碼 -->
<style>
form input:autofill{
color:red;
}
</style>
小結
在表單數量多的網頁裡,「表單輸入」相關的虛擬類別選擇器是絕對要使用的選擇器,不僅可以協助表單排版,讓使用者更清楚自己的操作過程,此外也更能運用樣式的設定,讓後端 JavaScript 處理更為簡便,是非常使用的選擇器。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~