屬性

我們在 HTML 總覽中稍微討論了屬性,現在該深入探究屬性。

屬性是 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。布林屬性包括 autofocusinertcheckeddisabledrequiredreversedallowfullscreendefault, loopautoplaycontrolsmutedreadonlymultiple,selected。 當這類屬性存在時,該元素會停用、必要、唯讀等。如果沒有,系統就不會顯示。

布林值可以省略、設為空白字串,也可以是屬性名稱;但值不必實際設為 true 字串。所有值 (包括 truefalse😀) 無效時,都會解析為 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、連結和元素互動可能無法正常運作。

導覽列包含四個連結。我們稍後會介紹連結元素,但目前我們瞭解的連結不限於以 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>&amp;</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> 開頭與結尾標記之間,則不需要 forid 屬性:這稱為「隱含」標籤。標籤可讓所有使用者瞭解每種表單控制項的用途。

<label>
  Send me a reminder <input type="number" name="min"> before the workshop resumes
</label>.

forid 之間的關聯,可讓輔助技術的使用者都能取得資訊。此外,點選標籤上的任何一處後,焦點就會移至相關元素,擴大控制項的點擊區域。這不僅對精細動作問題影響降低滑鼠操作者的幫助,也可協助所有行動裝置使用者使用比圓形按鈕更寬的手指。

在本程式碼範例中,假測驗的第五題是選擇題。每個表單控制項都有明確的標籤,每個表單控制項都有專屬的 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-labelledbyaria-describedbyaria-detailsaria-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),但不會將元素加入分頁順序序列。0tabindex 值會將元素聚焦於可透過 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>

buttonrole 會通知螢幕閱讀器使用者,這個元素的行為應與按鈕相同。JavaScript 是用來確保按鈕功能保證,包括處理 clickkeydown 事件,以及處理 Enter 和空格鍵按鍵。

表單控制項、連結、按鈕和內容可編輯元素皆可接收焦點;當鍵盤使用者按下 Tab 鍵時,焦點會移至下一個可聚焦元素,就像設定 tabindex="0" 一樣。根據預設,其他元素無法聚焦。在這些元素中加入 tabindex 屬性,可讓這些元素在原本無法聚焦的情況下接收焦點。

如果文件含有 tabindex1 以上的元素,這些元素會納入獨立的分頁序列中。您會注意到,在轉碼器中, Tab 鍵會先從最低值到最高值的順序開始,再按照來源順序依序排列。

如果改變分頁順序,可能會產生非常差的使用者體驗。難以仰賴鍵盤和螢幕閱讀器等輔助技術瀏覽內容。對開發人員來說,管理及維護也非常困難。「焦點」很重要,這個單元有討論重點和聚焦順序的整個單元。

role

role 屬性ARIA 規格的一部分,而不是 WHATWG HMTL 規格role 屬性可用來為內容提供語意含義,讓螢幕閱讀器知道物件的預期使用者互動。

有些常見的 UI 小工具沒有原生 HTML 對應項目,例如下拉式方塊選單列分頁清單樹狀結構。舉例來說,建立分頁式設計模式時,可以使用 tabtablisttabpanel 角色。能夠實際看到使用者介面的使用者,已親身體驗如何瀏覽小工具,點選相關分頁來顯示不同面板。如果要在一組按鈕顯示不同面板時,使用 <button role="tab"> 加入 tab 角色,螢幕閱讀器使用者知道目前具有焦點的 <button> 可將相關面板切換為檢視區塊,而非實作類似按鈕的一般功能。

role 屬性不會變更瀏覽器行為或鍵盤/指標裝置互動,將 role="button" 加入 <span> 並不會將其轉換成 <button>。因此,我們建議您將語意式 HTML 元素用於預定用途。不過,使用正確的元素時,如果非語意元素經過重新設計為語意元素角色,role 屬性會通知螢幕閱讀器使用者。

contenteditable

具有 contenteditable 屬性設為 true 的元素可供編輯、可聚焦,並會像設定 tabindex="0" 一樣新增至分頁順序。Contenteditable 是支援 truefalse 值的列舉屬性,如果屬性不存在或有無效值,則預設值為 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 設為 truefalseinherit,來指定這項屬性。

全域屬性可以套用至所有元素,即使是 <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>

請嘗試將 stylecolor 變更為 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 元素 (但不一定都會對這些元素產生影響)。接下來,我們將深入瞭解未處理的簡介圖片這兩項屬性:targethref,以及其他幾項元素專屬屬性。

隨堂測驗

測驗您對於屬性的相關知識。

在文件中,id 不得重複。

false
請再試一次。
答對了!

選取格式正確的自訂屬性。

data-birthday
正確
birthday
請再試一次。
data:birthday
再試一次