これまでの記事で、生成コンテンツの使い方を見てきましたが、今こそもう少し詳しく話をする良い機会だと思い、今回はその内容を紹介します。
これは、 ::before
と ::after
という擬似要素と content
というプロパティを使用して、影響を受ける要素の前または後にコンテンツの塊を表示させることができるというものです。コンテンツの塊は DOM に追加されないので、スクリーンリーダーによっては見えないかもしれません。擬似要素なので、実際の DOM ノードと同じ方法でスタイル設定の対象とすることができます。
これは、すべてのユーザーのアクセシビリティを保証するため代替のインジケーターも利用できる場合に、ラベルやアイコンのような視覚的なインジケーターを要素に追加したい場合に実に有益です。たとえば、カスタムラジオボタンの例では、ラジオボタンが選択されたときにカスタムラジオボタンの内側の円の配置とアニメーションを処理するために生成コンテンツを使用しています。
input[type="radio"]::before {
display: block;
content: " ";
width: 10px;
height: 10px;
border-radius: 6px;
background-color: red;
font-size: 1.2em;
transform: translate(3px, 3px) scale(0);
transform-origin: center;
transition: all 0.3s ease-in;
}
input[type="radio"]:checked::before {
transform: translate(3px, 3px) scale(1);
transition: all 0.3s cubic-bezier(0.25, 0.25, 0.56, 2);
}
これは実に有用です。スクリーンリーダーでは、遭遇したラジオボタンやチェックボックスがチェックまたは選択されているかをすでにユーザーに知らせているので、選択を示す別の DOM 要素を読み上げさせたくはないでしょう。紛らわしくなる可能性があるからです。純粋に視覚的なインジケーターを置くことで、この問題は解決されます。
すべての <input>
型が生成コンテンツを保有することに対応しているわけではありません。動的テキストを入力する text
、password
、button
などの入力型は、すべて生成コンテンツを表示しません。他にも range
、color
、checkbox
などがあり、これらは生成コンテンツを表示します。
先ほどの必須/オプションの例に戻りますが、今回は入力フィールド自体の外観は変更しません。生成コンテンツを使用して、指示するラベルを追加します(こちらでライブで確認するか、こちらでソースコードを確認するかしてください。
まず最初に、フォームの一番上に、何を求めているのか、という段落を追加します。
<p>Required fields are labeled with "required".</p>
スクリーンリーダーには、 "required" が追加情報として読み上げられ、目の見えるユーザーには、このラベルが表示されます。
前に述べたように、テキスト入力フィールドは生成コンテンツに対応していないので、生成コンテンツをぶら下げるために空の <span>
を追加します。
<div>
<label for="fname">First name: </label>
<input id="fname" name="fname" type="text" required />
<span></span>
</div>
この場合、入力フィールドとラベルの両方が width: 100%
に設定されているため、span が入力フィールドの下の新しい行にドロップされてしまうという問題がありました。これを修正するために、親の <div>
をフレックスコンテナーにするスタイルを設定し、さらにコンテンツが長くなりすぎた場合は新しい行に折り返すように指示します。
fieldset > div {
margin-bottom: 20px;
display: flex;
flex-flow: row wrap;
}
この効果として、ラベルと入力フィールドはどちらも width: 100%
なので別個の行に表示されますが、 <span>
は width が 0
なので、入力フィールドと同じ行に表示されます。
次に、生成コンテンツについて説明します。この CSS を使用してコンテンツを作成します。
input + span {
position: relative;
}
input:required + span::after {
font-size: 0.7rem;
position: absolute;
content: "required";
color: white;
background-color: black;
padding: 5px 10px;
top: -26px;
left: -70px;
}
ここでは <span>
を position: relative
に設定しているので、生成されるコンテンツを position: absolute
に設定すると、位置は <body>
ではなく <span>
からの相対位置になります(位置決めのために生成コンテンツは生成要素の子ノードであるかのように動作します)。
そして、生成コンテンツに、このラベルに書かせたい内容である "required" を与え、好きなようにスタイルと位置を設定します。結果は以下のようになります。