我們在 HTML 總覽中稍微討論了屬性,現在該深入探究屬性。
屬性是 HTML 如此強大的功能。屬性是以空格分隔的名稱和名稱/值組合顯示在開頭標記中,提供元素的相關資訊和功能。
屬性可定義元素的行為、連結和功能。有些屬性是全域性質,也就是說,這些屬性可以出現在任何元素的起始標記中。其他屬性適用於多個元素,並非全部,而其他屬性則適用於特定元素,只與單一元素相關。在 HTML 中,除了布林值以外的所有屬性,以及某些程度的列舉屬性中,都需要一個值。
如果屬性值含有空格或特殊字元,則必須加上引號。因此,為了提高易讀性,我們一律建議引用。
雖然 HTML 不區分大小寫,但有些屬性值是。HTML 規格中的值不區分大小寫。 已定義的字串值 (例如類別和 ID 名稱) 會區分大小寫。在 HTML 中,如果是在 CSS 和 JavaScript 中做為屬性選取器的一部分使用時,屬性值區分大小寫;在其他情況下則否。
<!-- the type attribute is case insensitive: these are equivalent -->
<input type="text">
<input type="TeXt">
<!-- the id attribute is case sensitive: they are not equivalent -->
<div id="myId">
<div id="MyID">
布林值屬性
如果有布林值屬性,則該屬性一律為 true。布林屬性包括 autofocus
、inert
、checked
、disabled
、required
、reversed
、allowfullscreen
、default,
loop
、autoplay
、controls
、muted
、readonly
、multiple,
和 selected
。
當這類屬性存在時,該元素會停用、必要、唯讀等。如果沒有,系統就不會顯示。
布林值可以省略、設為空白字串,也可以是屬性名稱;但值不必實際設為 true
字串。所有值 (包括 true
、false
和 😀
) 無效時,都會解析為 true。
以下三個標記是同等的:
<input required>
<input required="">
<input required="required">
如果屬性值為 false,請省略這項屬性。如果屬性為 true,請填入這項屬性,不要提供值。
舉例來說,required="required"
不是 HTML 中的有效值,但 required
是布林值,因此無效值會解析為 true。
不過,無效的列舉屬性不一定能解析為遺漏值,因此更容易瞭解省略值的習慣,比起記住哪些屬性是布林或列舉的屬性,還可能會提供無效的值。
在 true 和 false 之間切換時,使用 JavaScript 即可新增及移除這項屬性,不要切換值。
const myMedia = document.getElementById("mediaFile");
myMedia.removeAttribute("muted");
myMedia.setAttribute("muted");
請注意,在 XML 語言 (例如 SVG) 中,所有屬性都必須加入值,包括布林值屬性。
列舉屬性
列舉屬性有時會與布林值屬性混淆。這些是 HTML 屬性,預先定義的有效值有限。如同布林值屬性,只要有屬性,但缺少屬性值,這兩個屬性就會有預設值。舉例來說,如果您加入 <style contenteditable>
,就會預設為 <style contenteditable="true">
。
但與布林值屬性不同的是,省略該屬性並不代表它就是 false;沒有值的屬性不一定是 true;且無效值的預設值不一定等於空值字串。延續這個範例,如果缺少或無效,contenteditable
會預設為 inherit
,而且可以明確設為 false
。
預設值視屬性而定。與布林值不同的是,如果屬性存在屬性,系統不會自動設為「true」。如果您加入 <style contenteditable="false">
,則無法編輯元素。如果值無效 (例如 <style contenteditable="😀">
),或者在意料之外的 <style contenteditable="contenteditable">
,該值無效,且預設為 inherit
。
在多數情況下,列舉屬性、缺少值和無效值皆相同。舉例來說,如果 <input>
上的 type
屬性缺少值,但沒有值或含有無效值,則預設值為 text
。雖然這個行為很常見,但這並非規則。因此,請務必瞭解哪些屬性是布林值與列舉值;如果可以,請省略值,以免出現錯誤,必要時查詢該值。
全域屬性
全域屬性是可在任何 HTML 元素 (包括 <head>
中的元素) 中設定的屬性。有超過 30 個全域屬性。雖然這些屬性都可以加到任何 HTML 元素中,但某些全域屬性在對部分元素設定時沒有任何作用。舉例來說,在 <meta>
上設定 hidden
時,系統不會顯示中繼內容。
id
全域屬性 id
是用來定義元素的專屬 ID。可用於許多用途,包括:
- 連結的片段 ID 目標。
- 找出用於編寫指令碼的元素。
- 將表單元素與自身標籤建立關聯。
- 為輔助技術提供標籤或說明。
- 在 CSS 中使用 (明確明確或以屬性選取器) 的指定目標樣式。
id
值是沒有空格的字串。文件包含空格並不會中斷,但您必須以 HTML、CSS 和 JS 中的逸出字元指定 id
。所有其他字元都有效。id
值可以是 😀
或 .class
,但我們不建議這麼做。為了方便您目前和未來的程式設計,請將 id
的第一個字元設為字母,並且只使用 ASCII 字母、數字、_
和 -
。建議您先制定 id
命名慣例,然後繼續使用,因為 id
值區分大小寫。
id
應專屬於文件。如果多次使用 id
,網頁的版面配置可能不會損毀,但您的 JavaScript、連結和元素互動可能無法正常運作。
連結片段 ID
導覽列包含四個連結。我們稍後會介紹連結元素,但目前我們瞭解的連結不限於以 HTTP 為基礎的網址,這些連結可以是目前文件 (或其他文件) 中網頁區段的片段 ID。
在機器學習研討會網站上,網頁標題的導覽列包含四個連結:
href 屬性提供啟用連結並將使用者導向的超連結。如果網址含有雜湊標記 (#
),後接一串字元,該字串就會是片段 ID。如果這個字串與網頁中某個元素的 id
相符,該片段就會成為該元素的錨點或書籤。瀏覽器將捲動至定義錨定標記的點。
這四個連結指向我們網頁中由 id
屬性識別的四個部分。當使用者按一下導覽列中的任一連結時,由片段 ID 相連結的元素 (包含相符 ID 的元素減去 #
) 就會捲動至檢視畫面中。
機器學習研討會的 <main>
內容分成四個部分,以及 ID。當網站訪客點選 <nav>
中的其中一個連結時,含有該片段 ID 的區段就會捲動至檢視畫面中。標記類似:
<section id="reg">
<h2>Machine Learning Workshop Tickets</h2>
</section>
<section id="about">
<h2>What you'll learn</h2>
</section>
<section id="teachers">
<h2>Your Instructors</h2>
<h3>Hal 9000 <span>&</span> EVE</h3>
</section>
<section id="feedback">
<h2>What it's like to learn good and do other stuff good too</h2>
</section>
比較 <nav>
連結中的片段 ID 時,您會注意到,每個 ID 都與 <main>
中 <section>
的 id
相符。瀏覽器提供免費的「網頁頂端」連結。如果設定 href="#top"
、不區分大小寫,或僅設為 href="#"
,系統會將使用者捲動至頁面頂端。
href
中的雜湊標記分隔符並非片段 ID 的一部分。片段 ID 一律為網址的最後一部分,不會傳送至伺服器。
CSS 選取器
在 CSS 中,您可以使用 ID 選取器 (例如 #feedback
) 指定各個區段;而在明確性方面,屬性選取器 ([id="feedback"]
) 須區分大小寫。
影片腳本
MLW.com 上有一顆彩蛋,僅供滑鼠使用者使用。按一下燈光切換按鈕,即可開啟或關閉頁面。
淺色開關圖片的標記如下:
html
<img src="svg/switch2.svg" id="switch"
alt="light switch" class="light" />
id
屬性可做為 getElementById()
方法的參數,加上 #
前置字串,包含在 querySelector()
和 querySelectorAll()
方法的參數中。
const switchViaID = document.getElementById("switch");
const switchViaSelector = document.querySelector("#switch");
我們的 JavaScript 函式會運用以下功能,透過元素的 id
屬性指定元素:
<script>
/* switch is a reserved word in js, so we us onoff instead */
const onoff = document.getElementById('switch');
onoff.addEventListener('click', function(){
document.body.classList.toggle('black');
});
</script>
<label>
HTML <label>
元素的 for
屬性會將其值視為相關聯表單控制項的 id
。如要建立明確標籤,請在每個表單控制項中加入 id
,然後將每個標籤與標籤的 for
屬性配對,以確保每個表單控制項都有相關聯的標籤。
雖然每個標籤只能與一個表單控制項建立關聯,但表單控制項可以有多個相關聯的標籤。
如果表單控制項位於 <label>
開頭與結尾標記之間,則不需要 for
和 id
屬性:這稱為「隱含」標籤。標籤可讓所有使用者瞭解每種表單控制項的用途。
<label>
Send me a reminder <input type="number" name="min"> before the workshop resumes
</label>.
for
和 id
之間的關聯,可讓輔助技術的使用者都能取得資訊。此外,點選標籤上的任何一處後,焦點就會移至相關元素,擴大控制項的點擊區域。這不僅對精細動作問題影響降低滑鼠操作者的幫助,也可協助所有行動裝置使用者使用比圓形按鈕更寬的手指。
在本程式碼範例中,假測驗的第五題是選擇題。每個表單控制項都有明確的標籤,每個表單控制項都有專屬的 id
。為了確保不會意外複製 ID,ID 值會由問題編號和值組成。
當標籤說明圓形按鈕的值時,我們會在 <fieldset>
中納入所有相同名稱的按鈕,且整個組合中的 <legend>
是標籤或問題。
其他無障礙功能使用
在無障礙和可用性中使用 id
時,不限於標籤。在文字簡介中,<section>
已參照 <h2>
的 id
做為 <section>
aria-labelledby
的值以提供無障礙名稱,藉此轉換為區域地標:
<section id="about" aria-labelledby="about_heading">
<h2 id="about_heading">What you'll learn</h2>
有超過 50 種 aria-*
狀態和屬性可用於確保無障礙功能。aria-labelledby
、aria-describedby
、aria-details
和 aria-owns
將做為值,並採用以空格分隔的 id
參考清單。aria-activedescendant
可識別目前聚焦的子系元素,將其值作為單一 id
參照:具有焦點的單一元素 (一次只能聚焦一個元素)。
class
class
屬性是透過 CSS (和 JavaScript) 指定元素的額外方法,但在 HTML 中不具備其他用途 (儘管架構和元件程式庫可能會使用這些元素)。類別屬性會採用以空格分隔的清單,列出元素的區分大小寫類別。
建立聲音語意結構後,就能根據元素的位置和功能來指定元素。可透過音效結構使用子系元素選取器、關聯選取器和屬性選取器。本節將說明屬性/屬性值相同的元素可以設定樣式。您並不該使用類別屬性,只是大多數開發人員並不瞭解他們通常不需要。
目前 MLW 尚未使用任何類別。即使沒有單一類別名稱,也能啟動網站嗎?等著瞧吧。
style
style
屬性可讓您套用內嵌樣式,樣式會套用至設定該屬性的單一元素。
style
屬性採用其值的 CSS 屬性值組合,其值的語法與 CSS 樣式區塊的內容相同:屬性後面會加上冒號 (就像在 CSS 中一樣),而分號則在值之後的結尾。
樣式只會套用至屬性設定目標的元素。如果子元素未遭到巢狀元素或 <style>
區塊或樣式表中的其他樣式宣告覆寫,子系則會沿用沿用的屬性值。這個值與只套用至該元素的單一樣式區塊內容相等,因此無法用於產生的內容、建立主要畫面格動畫,或是套用任何其他位於規則的規則。
雖然 style
確實是全域屬性,但我們不建議使用。而是在單獨的檔案或檔案中定義樣式。也就是說,style
屬性在開發期間可派上用場,例如用於測試的快速樣式。接著,採用解決方案的樣式,並在連結的 CSS 檔案中加以貼合。
tabindex
您可以為任何元素新增 tabindex
屬性,讓該屬性接收焦點。tabindex
值會定義值是否加入分頁順序,以及視需要加入非預設的分頁順序。
tabindex
屬性會將其值視為整數。負值 (慣例是使用 -1
) 則讓某個元素能夠接收焦點 (例如透過 JavaScript),但不會將元素加入分頁順序序列。0
的 tabindex
值會將元素聚焦於可透過 Tab 鍵存取,並按照原始碼順序新增至頁面的預設分頁順序。如果值為 1
或以上值,系統會將元素置於優先順序最高的焦點順序中,因此不建議使用。
在這個頁面上,有一個使用 <share-action>
自訂元素做為 <button>
的分享功能。以下為零的 tabindex
,可將自訂元素新增至鍵盤預設 Tab 鍵順序:
<share-action authors="@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, twitter" role="button" tabindex="0">
<svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
<use href="#shareIcon" />
</svg>
<span>Share</span>
</share-action>
button
的 role
會通知螢幕閱讀器使用者,這個元素的行為應與按鈕相同。JavaScript 是用來確保按鈕功能保證,包括處理 click 和 keydown 事件,以及處理 Enter 和空格鍵按鍵。
表單控制項、連結、按鈕和內容可編輯元素皆可接收焦點;當鍵盤使用者按下 Tab 鍵時,焦點會移至下一個可聚焦元素,就像設定 tabindex="0"
一樣。根據預設,其他元素無法聚焦。在這些元素中加入 tabindex
屬性,可讓這些元素在原本無法聚焦的情況下接收焦點。
如果文件含有 tabindex
為 1
以上的元素,這些元素會納入獨立的分頁序列中。您會注意到,在轉碼器中, Tab 鍵會先從最低值到最高值的順序開始,再按照來源順序依序排列。
如果改變分頁順序,可能會產生非常差的使用者體驗。難以仰賴鍵盤和螢幕閱讀器等輔助技術瀏覽內容。對開發人員來說,管理及維護也非常困難。「焦點」很重要,這個單元有討論重點和聚焦順序的整個單元。
role
role
屬性是 ARIA 規格的一部分,而不是 WHATWG HMTL 規格。role
屬性可用來為內容提供語意含義,讓螢幕閱讀器知道物件的預期使用者互動。
有些常見的 UI 小工具沒有原生 HTML 對應項目,例如下拉式方塊、選單列、分頁清單和樹狀結構。舉例來說,建立分頁式設計模式時,可以使用 tab
、tablist
和 tabpanel
角色。能夠實際看到使用者介面的使用者,已親身體驗如何瀏覽小工具,點選相關分頁來顯示不同面板。如果要在一組按鈕顯示不同面板時,使用 <button role="tab">
加入 tab
角色,螢幕閱讀器使用者知道目前具有焦點的 <button>
可將相關面板切換為檢視區塊,而非實作類似按鈕的一般功能。
role
屬性不會變更瀏覽器行為或鍵盤/指標裝置互動,將 role="button"
加入 <span>
並不會將其轉換成 <button>
。因此,我們建議您將語意式 HTML 元素用於預定用途。不過,使用正確的元素時,如果非語意元素經過重新設計為語意元素角色,role
屬性會通知螢幕閱讀器使用者。
contenteditable
具有 contenteditable
屬性設為 true
的元素可供編輯、可聚焦,並會像設定 tabindex="0"
一樣新增至分頁順序。Contenteditable
是支援 true
和 false
值的列舉屬性,如果屬性不存在或有無效值,則預設值為 inherit
。
這三個開頭標記是相同的:
<style contenteditable>
<style contenteditable="">
<style contenteditable="true">
加入 <style contenteditable="false">
後,元素無法編輯 (除非預設為可編輯,例如 <textarea>
)。如果值無效,例如 <style contenteditable="😀">
或 <style contenteditable="contenteditable">
,則值會預設為 inherit
。
如要切換狀態,請查詢 HTMLElement.isContentEditable 唯讀屬性的值。
const editor = document.getElementById("myElement");
if(editor.contentEditable) {
editor.setAttribute("contenteditable", "false");
} else {
editor.setAttribute("contenteditable", "");
}
或者,您也可以將 editor.contentEditable
設為 true
、false
或 inherit
,來指定這項屬性。
全域屬性可以套用至所有元素,即使是 <style>
元素也沒問題。您可以運用屬性和 CSS 來建立實際運作的 CSS 編輯器。
<style contenteditable>
style {
color: inherit;
display:block;
border: 1px solid;
font: inherit;
font-family: monospace;
padding:1em;
border-radius: 1em;
white-space: pre;
}
</style>
請嘗試將 style
的 color
變更為 inherit
以外的值。接著,請嘗試將 style
變更為 p
選取器。請勿移除顯示屬性,否則樣式區塊會消失。
自訂屬性
我們僅認識 HTML 全域屬性的表面。還有更多屬性僅適用於一或一組元素。即使已有數百種定義的屬性,您可能也需要有規格不支援的屬性。沒問題,
您可以新增 data-
前置字元,建立所需的任何自訂屬性。您可以將任何以 data-
開頭的屬性命名,後面接著任何開頭是 xml
且不含冒號 (:
) 的小寫字元。
雖然 HTML 能夠發揮創意且不會損毀,但如果您建立開頭為 data
的不支援的屬性,或者即便以 xml
做為自訂屬性或包含 :
,建立有效的自訂屬性仍有一些好處,而且該屬性是以 data-
為開頭。使用者知道自己不會不小心用現有的屬性名稱來輸入自訂資料屬性。自訂資料屬性能因應未來趨勢。
雖然瀏覽器不會針對任何特定 data-
前置字元屬性實作預設行為,但有內建的資料集 API,可疊代您的自訂屬性。透過 JavaScript,自訂屬性是傳達應用程式專屬資訊的絕佳方法。以 data-name
的格式將自訂屬性新增至元素,然後針對相關元素使用 dataset[name]
,透過 DOM 存取這些屬性。
<blockquote data-machine-learning="workshop"
data-first-name="Blendan" data-last-name="Smooth"
data-formerly="Margarita Maker" data-aspiring="Load Balancer"
data-year-graduated="2022">
HAL and EVE could teach a fan to blow hot air.
</blockquote>
您可以使用完整屬性名稱來使用 getAttribute()
,也可以使用較簡單的 dataset
屬性。
el.dataset["machineLearning"]; // workshop
e.dataset.machineLearning; // workshop
dataset
屬性會傳回每個元素的 data-
屬性的 DOMStringMap
物件。<blockquote>
提供數個自訂屬性,若使用資料集屬性,您不需要瞭解這些自訂屬性,就能存取這些屬性名稱和值:
for (let key in el.dataset) {
customObject[key] = el.dataset[key];
}
本文中的屬性為全域性,因此可以套用至任何 HTML 元素 (但不一定都會對這些元素產生影響)。接下來,我們將深入瞭解未處理的簡介圖片這兩項屬性:target
和 href
,以及其他幾項元素專屬屬性。
隨堂測驗
測驗您對於屬性的相關知識。
在文件中,id
不得重複。
選取格式正確的自訂屬性。
data-birthday
birthday
data:birthday