属性

属性については、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 に解決されます。

次の 3 つのタグは同等です。

<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");

列挙型属性

列挙型属性はブール値属性と混同されることがあります。これらは、事前定義された有効な値のセットが限られている HTML 属性です。ブール値属性と同様に、属性は存在しているが値が指定されていない場合は、デフォルト値が使用されます。たとえば、<style contenteditable> を含めると、デフォルトで <style contenteditable="true"> になります。

ただし、ブール値属性とは異なり、属性を省略しても false になるわけではありません。値のない属性が存在する場合、必ずしも true とは限りません。また、無効な値のデフォルトが null 文字列と同じであるとは限りません。この例では、contenteditable が欠落しているか無効な場合、デフォルトで inherit に設定されます。また、明示的に false に設定することもできます。

デフォルト値は属性によって異なります。ブール値とは異なり、属性が存在する場合でも自動的に「true」にはなりません。<style contenteditable="false"> を含めると、要素は編集できません。値が <style contenteditable="😀"><style contenteditable="contenteditable"> などの無効な値の場合、値は無効になり、デフォルトの inherit になります。

列挙型属性の場合、欠損値と無効な値は同じになることがほとんどです。たとえば、<input>type 属性がない場合、値がない場合、または無効な値がある場合、デフォルトは text になります。この動作は一般的ですが、ルールではありません。そのため、どの属性がブール値で、どの属性が列挙型であるかを把握することが重要です。可能な限り値を省略して誤りを防ぎ、必要に応じて値を検索してください。

グローバル属性

グローバル属性は、<head> 内の要素を含む任意の HTML 要素に設定できる属性です。30 個を超えるグローバル属性があります。理論上は、これらすべてを任意の HTML 要素に追加できますが、一部のグローバル属性は、一部の要素に設定しても効果がありません。たとえば、<meta>hidden をメタコンテンツとして設定しても表示されません。

id

グローバル属性 id は、要素の一意の識別子を定義するために使用されます。次のようなさまざまな目的で使用されます。

  • リンクのフラグメント識別子のターゲット。
  • スクリプト用の要素を特定します。
  • フォームの要素とそのラベルを関連付けます。
  • 支援技術のラベルまたは説明を提供する。
  • CSS で(詳細度の高いセレクタまたは属性セレクタとして)スタイルをターゲットに設定します。

id の値はスペースのない文字列です。スペースが含まれていてもドキュメントは壊れませんが、HTML、CSS、JS でエスケープ文字を使用して id をターゲットにする必要があります。その他の文字はすべて有効です。id 値は 😀 または .class にできますが、おすすめしません。現在と将来の自分にとってプログラミングを容易にするため、id の最初の文字を文字にし、ASCII 文字、数字、_- のみを使用します。id の値では大文字と小文字が区別されるため、id の命名規則を考案して、それに従うことをおすすめします。

id はドキュメントに対して一意である必要があります。id を複数回使用しても、ページのレイアウトが崩れることはほとんどありませんが、JavaScript、リンク、要素のインタラクションが想定どおりに動作しない可能性があります。

ナビゲーション バーには 4 つのリンクがあります。リンク要素については後で説明しますが、現時点では、リンクは HTTP ベースの URL に限定されないことを理解しておいてください。リンクは、現在のドキュメント(または他のドキュメント)のページ内のセクションへのフラグメント識別子にすることもできます。

ML ワークショップ サイトのページ ヘッダーにあるナビゲーション バーには、次の 4 つのリンクがあります。

href 属性は、リンクを有効にしたときにユーザーが移動するハイパーリンクを提供します。URL にハッシュマーク(#)とそれに続く文字列が含まれている場合、その文字列はフラグメント識別子です。その文字列がウェブページの要素の id と一致する場合、フラグメントはその要素へのアンカー(ブックマーク)になります。ブラウザはアンカーが定義されている場所にスクロールします。

これらの 4 つのリンクは、id 属性で識別されるページの 4 つのセクションを指しています。ユーザーがナビゲーション バーの 4 つのリンクのいずれかをクリックすると、フラグメント識別子によってリンクされた要素、つまり一致する ID を含む要素(# を除く)がビューにスクロールされます。

ML ワークショップの <main> コンテンツには、ID が設定された 4 つのセクションがあります。サイト訪問者が <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> リンクのフラグメント識別子を比較すると、それぞれが <main><section>id と一致していることがわかります。ブラウザには、ページの先頭へのリンクが無料で用意されています。href="#top"(大文字と小文字を区別しない)または href="#" を設定すると、ユーザーはページの最上部までスクロールされます。

href のハッシュマーク区切り文字は、フラグメント識別子の一部ではありません。フラグメント識別子は常に URL の最後の部分であり、サーバーに送信されません。

CSS セレクタ

CSS では、#feedback などのセレクタを使用して各セクションをターゲットにできます。特異性を低くするには、大文字と小文字を区別する属性セレクタ [id="feedback"] を使用します。

スクリプト

MLW.com には、マウス ユーザー専用のイースター エッグがあります。ライトスイッチをクリックすると、ページのオンとオフが切り替わります。

ライトスイッチの画像のマークアップは次のようになります。

<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 の 1 つの関数で、この機能を利用して id 属性で要素をターゲットにしています。

<script>
  /* Switch is a reserved word in JavaScript, so instead, we use onoff */
  const onoff = document.getElementById('switch');
  onoff.addEventListener('click', function(){
    document.body.classList.toggle('black');
  });
</script>

<label>

HTML <label> 要素には、関連付けられているフォーム コントロールの id を値として受け取る for 属性があります。すべてのフォーム コントロールに id を含め、それぞれをラベルの for 属性とペアにすることで、明示的なラベルを作成すると、すべてのフォーム コントロールにラベルが関連付けられます。

各ラベルは 1 つのフォーム コントロールにのみ関連付けることができますが、1 つのフォーム コントロールに複数のラベルを関連付けることができます。

フォーム コントロールが <label> 開始タグと終了タグの間にネストされている場合、for 属性と id 属性は必須ではありません。これは「暗黙的」ラベルと呼ばれます。ラベルを使用すると、すべてのユーザーが各フォーム コントロールの目的を把握できます。

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

forid の関連付けにより、支援技術のユーザーが情報を利用できるようになります。また、ラベルの任意の場所をクリックすると、関連付けられた要素にフォーカスが移動し、コントロールのクリック領域が拡大されます。これは、マウス操作の精度が低下する運動機能障がいのある方だけでなく、ラジオボタンよりも指の幅が広いモバイル デバイスのユーザーにも役立ちます。

このコード例では、偽のクイズの偽の 5 番目の質問は、単一選択の多肢選択式問題です。各フォーム コントロールには明示的なラベルがあり、それぞれに一意の id があります。ID の重複を避けるため、ID 値は質問番号と値の組み合わせになっています。

ラジオボタンを含める場合、ラベルはラジオボタンの値を説明するため、同じ名前のボタンをすべて <fieldset> で囲み、<legend> をセット全体のラベルまたは質問にします。

ユーザー補助のその他の用途

ユーザー補助とユーザビリティにおける id の使用は、ラベルだけではありません。テキストの概要では、<section>aria-labelledby の値として <h2>id を参照することで、<section> がリージョン ランドマークに変換され、アクセス可能な名前が提供されました。

<section id="about" aria-labelledby="about_heading">
<h2 id="about_heading">What you'll learn</h2>

アクセシビリティを確保するために使用できる aria-* の状態とプロパティは 50 個以上あります。aria-labelledbyaria-describedbyaria-detailsaria-owns は、値としてスペース区切りの id 参照リストを受け取ります。aria-activedescendant: フォーカスされた子孫要素を識別し、値として単一の id 参照(フォーカスされている単一の要素の参照。一度にフォーカスできる要素は 1 つのみ)を取ります。

class

class 属性は、CSS(および JavaScript)で要素をターゲットにするための追加の方法を提供しますが、HTML では他の目的で使用されません(フレームワークやコンポーネント ライブラリでは使用される場合があります)。class 属性の値には、要素の大文字と小文字が区別されるクラスのスペース区切りリストを指定します。

適切なセマンティック構造を構築すると、要素の配置と機能に基づいて要素をターゲットに設定できます。サウンド構造では、子孫要素セレクタ、関係セレクタ、属性セレクタを使用できます。属性について学習する際は、同じ属性または属性値を持つ要素をどのようにスタイル設定できるかを検討してください。class 属性を使用すべきではないということではなく、ほとんどのデベロッパーは、多くの場合、class 属性を使用する必要がないことに気づいていないだけです。

これまでのところ、MLW はクラスを使用していません。単一のクラス名なしでサイトをリリースできますか?様子を見ましょう。

style

style 属性を使用すると、インライン スタイルを適用できます。インライン スタイルとは、属性が設定されている単一の要素に適用されるスタイルです。style 属性は、CSS プロパティ値のペアを値として受け取ります。値の構文は CSS スタイル ブロックの内容と同じです。CSS と同様に、プロパティの後にコロンが続き、値の後にセミコロンが続いて各宣言を終了します。

スタイルは、属性が設定されている要素にのみ適用されます。子孫は、ネストされた要素や <style> ブロック、スタイルシートの他のスタイル宣言によってオーバーライドされない限り、継承されたプロパティ値を継承します。値は、その要素にのみ適用される単一のスタイル ブロックの内容に相当するため、生成されたコンテンツ、キーフレーム アニメーションの作成、その他の @ 規則の適用には使用できません。

style はグローバル属性ですが、使用することは推奨されません。代わりに、スタイルを個別のファイルで定義します。ただし、開発中に style 属性を使用すると、テストなどの目的でスタイリングをすばやく行うことができます。次に、'solution' スタイルを取得して、リンクされた CSS ファイルに貼り付けます。

tabindex

tabindex 属性は、フォーカスを受け取ることができるように、任意の要素に追加できます。tabindex の値は、タブオーダーに追加されるかどうか、およびオプションでデフォルト以外のタブオーダーに追加されるかどうかを定義します。

tabindex 属性は、値として整数を受け取ります。負の値(慣例では -1 を使用)にすると、JavaScript などでフォーカスを受け取れる要素になりますが、タブ順序には追加されません。tabindex の値が 0 の場合、要素はフォーカス可能になり、タブ移動で到達できるようになります。また、ソースコードの順序でページのデフォルトのタブ順序に追加されます。1 以上の値にすると、要素が優先順位付きのフォーカス シーケンスに配置されるため、おすすめしません。

このページには、<button> として機能する <share-action> カスタム要素を使用した共有機能があります。tabindex が 0 の場合、カスタム要素がキーボードのデフォルトのタブ移動順に追加されます。

<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 は、ボタンの機能の約束が守られるようにするために使用されます。これには、クリック イベントと keydown イベントの両方の処理、Enter キーと Space キーのキー押下の処理が含まれます。

フォーム コントロール、リンク、ボタン、コンテンツ編集可能な要素はフォーカスを受け取ることができます。キーボード ユーザーが Tab キーを押すと、tabindex="0" が設定されているかのように、フォーカスが次のフォーカス可能な要素に移動します。他の要素はデフォルトではフォーカスできません。これらの要素に tabindex 属性を追加すると、通常はフォーカスを受け取らない要素がフォーカスを受け取れるようになります。

ドキュメントに tabindex1 以上の要素が含まれている場合、それらは別のタブ順に含まれます。CodePen では、タブ移動は別のシーケンスで開始され、値の小さい順から大きい順に移動してから、ソース順の通常のシーケンスで移動します。

タブ移動の順序を変更すると、ユーザー エクスペリエンスが大幅に低下する可能性があります。支援技術、キーボード、スクリーン リーダーのいずれを使用しても、コンテンツのナビゲーションが困難になります。また、デベロッパーにとっても管理とメンテナンスが困難です。フォーカスは重要です。フォーカスとフォーカス順序について説明するモジュール全体があります。

role

role 属性は、WHATWG HTML 仕様ではなく、ARIA 仕様の一部です。role 属性を使用すると、コンテンツに意味的な意味を持たせることができます。これにより、スクリーン リーダーはサイトのユーザーにオブジェクトの想定されるユーザー操作を伝えることができます。

コンボボックスメニューバータブリストツリーグリッドなど、ネイティブ HTML に相当するものがない一般的な UI ウィジェットがいくつかあります。たとえば、タブ付きのデザイン パターンを作成する場合は、tabtablisttabpanel のロールを使用できます。ユーザー インターフェースを実際に確認できる人は、ウィジェットの操作方法を経験的に理解しており、関連するタブをクリックしてさまざまなパネルを表示できます。ボタンのグループを使用してさまざまなパネルを表示する場合に、<button role="tab"> とともに tab ロールを含めると、スクリーン リーダーのユーザーは、現在フォーカスされている <button> が、通常のボタンのような機能を実装するのではなく、関連するパネルを切り替えて表示できることを認識できます。

role 属性は、ブラウザの動作を変更したり、キーボードやポインティング デバイスの操作を変更したりしません。<span>role="button" を追加しても、<button> にはなりません。そのため、セマンティック HTML 要素を本来の目的で使用することをおすすめします。ただし、適切な要素を使用できない場合は、role 属性を使用すると、非セマンティック要素がセマンティック要素のロールに後付けされたときに、スクリーン リーダーのユーザーに通知できます。

contenteditable

contenteditable 属性が true に設定されている要素は、編集可能で、フォーカス可能であり、tabindex="0" が設定されているかのようにタブ順に追加されます。Contenteditable は、truefalse の値をサポートする列挙型属性です。属性が存在しない場合や値が無効な場合は、デフォルト値の inherit が使用されます。

次の 3 つの開始タグは同等です。

<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.contentEditabletruefalseinherit のいずれかに設定して、このプロパティを指定することもできます。

グローバル属性は、<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>

stylecolorinherit 以外の値に変更してみてください。次に、stylep セレクタに変更してみます。display プロパティを削除すると、スタイル ブロックが消えてしまうため、削除しないでください。

カスタム属性

今回は、HTML グローバル属性の概要について説明しました。1 つまたは限られた要素のセットにのみ適用される属性は他にもあります。何百もの属性が定義されていても、仕様にない属性が必要になることがあります。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 要素に適用できます(ただし、それらの要素に影響を与えるとは限りません)。次に、リンクについて詳しく見ていく中で、紹介画像の 2 つの属性(targethref)と、要素固有の他のいくつかの属性について説明します。

理解度を確認する

属性に関する知識をテストします。

id はドキュメント内で一意である必要があります。

誤り
もう一度お試しください。
正しい
正解です。

正しく作成されたカスタム属性を選択します。

data-birthday
正解
birthday
もう一度お試しください。
data:birthday
再試行