属性については、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 に解決されます。
次の 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");
SVG などの XML 言語では、論理属性を含め、すべての属性に値を含める必要があります。
列挙型属性
列挙型属性はブール値属性と混同されることがあります。これらは、事前定義された有効な値のセットが限られている 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>&</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 セレクタを使用して各セクションをターゲットにできます。また、特異性を低くする場合は、大文字と小文字が区別される属性セレクタ([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>
要素には、関連付けられているフォーム コントロールの id
を値として受け取る for
属性があります。すべてのフォーム コントロールに id
を含め、それぞれをラベルの for
属性とペアにすることで、明示的なラベルを作成すると、すべてのフォーム コントロールにラベルが関連付けられます。
各ラベルは 1 つのフォーム コントロールにのみ関連付けることができますが、1 つのフォーム コントロールに複数のラベルを関連付けることができます。
フォーム コントロールが <label>
開始タグと終了タグの間にネストされている場合、for
属性と id
属性は必須ではありません。これは「暗黙的」ラベルと呼ばれます。ラベルを使用すると、すべてのユーザーが各フォーム コントロールの目的を把握できます。
<label>
Send me a reminder <input type="number" name="min"> before the workshop resumes
</label>.
for
と id
の関連付けにより、支援技術のユーザーが情報を利用できるようになります。また、ラベルの任意の場所をクリックすると、関連付けられた要素にフォーカスが移動し、コントロールのクリック領域が拡大されます。これは、マウス操作の精度が低下する運動機能障がいのある方だけでなく、ラジオボタンよりも指の幅が広いモバイル デバイスのユーザーにも役立ちます。
このコード例では、偽のクイズの偽の 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-labelledby
、aria-describedby
、aria-details
、aria-owns
は、値としてスペース区切りの id
参照リストを受け取ります。aria-activedescendant
: 現在フォーカスされている子孫要素を識別します。値として、フォーカスされている単一の要素の id
参照を 1 つ取ります(一度にフォーカスできる要素は 1 つだけです)。
class
class
属性は、CSS(および JavaScript)で要素をターゲットにするための追加の方法を提供しますが、HTML では他の目的で使用されません(ただし、フレームワークやコンポーネント ライブラリでは使用されることがあります)。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>
button
の role
は、この要素がボタンのように動作することをスクリーン リーダーのユーザーに伝えます。JavaScript は、ボタンの機能の約束が守られるようにするために使用されます。これには、クリック イベントと keydown イベントの両方の処理、Enter キーと Space キーのキー押下の処理が含まれます。
フォーム コントロール、リンク、ボタン、コンテンツ編集可能な要素はフォーカスを受け取ることができます。キーボード ユーザーが Tab キーを押すと、tabindex="0"
が設定されているかのように、フォーカスが次のフォーカス可能な要素に移動します。他の要素はデフォルトではフォーカスできません。これらの要素に tabindex
属性を追加すると、通常はフォーカスを受け取らない要素がフォーカスを受け取れるようになります。
ドキュメントに tabindex
が 1
以上の要素が含まれている場合、それらは別のタブ順序に含まれます。codepen で確認できるように、タブ移動は、ソース順の通常のシーケンスをたどる前に、値の小さい順から大きい順に別のシーケンスで開始されます。
タブ移動の順序を変更すると、ユーザー エクスペリエンスが大幅に低下する可能性があります。そのため、キーボードやスクリーン リーダーなどの支援技術を使用してコンテンツを操作することが難しくなります。また、デベロッパーにとっても管理とメンテナンスが困難です。フォーカスは重要です。フォーカスとフォーカス順序について説明するモジュール全体があります。
role
role
属性は、WHATWG HTML 仕様ではなく、ARIA 仕様の一部です。role
属性を使用すると、コンテンツに意味的な意味を与えることができます。これにより、スクリーン リーダーはサイトのユーザーにオブジェクトの想定されるユーザー操作を伝えることができます。
コンボボックス、メニューバー、タブリスト、ツリーグリッドなど、ネイティブ HTML に相当するものがない一般的な UI ウィジェットがいくつかあります。たとえば、タブ付きのデザイン パターンを作成する場合は、tab
、tablist
、tabpanel
のロールを使用できます。ユーザー インターフェースを実際に確認できるユーザーは、ウィジェットの操作方法を経験的に理解しており、関連するタブをクリックしてさまざまなパネルを表示できます。ボタンのグループを使用してさまざまなパネルを表示する場合に、<button role="tab">
とともに tab
ロールを含めると、スクリーン リーダーのユーザーは、現在フォーカスされている <button>
が、通常のボタンのような機能を実装するのではなく、関連するパネルを切り替えて表示できることを知ることができます。
role
属性は、ブラウザの動作を変更したり、キーボードやポインタ デバイスの操作を変更したりしません。<span>
に role="button"
を追加しても、<button>
にはなりません。そのため、セマンティック HTML 要素を本来の目的で使用することをおすすめします。ただし、適切な要素を使用できない場合は、role
属性を使用することで、非セマンティック要素がセマンティック要素のロールに後付けされたことをスクリーン リーダーのユーザーに通知できます。
contenteditable
contenteditable
属性が true
に設定されている要素は、編集可能で、フォーカス可能で、tabindex="0"
が設定されているかのようにタブ順に追加されます。Contenteditable
は、true
と false
の値をサポートする列挙型属性です。属性が存在しない場合や無効な値が指定されている場合のデフォルト値は 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.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
セレクタに変更してみます。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 つの属性(target
と href
)と、要素固有の他のいくつかの属性について説明します。
理解度を確認する
属性に関する知識をテストします。
id
はドキュメント内で一意である必要があります。
正しく作成されたカスタム属性を選択します。
data-birthday
birthday
data:birthday