疑似クラス:has()は、CSS Level 4にて策定された引数の中で指定したセレクタとマッチする場合、スタイルを適用する優れものです。2023年末にはFirefoxでも:has()がサポート範囲となったことから、すべての主要ブラウザが対応したとなり、使用されている方も多いかと思います。
form button{
// スタイル
}
form:has(.checkbox:checked) button{
//スタイル
}
これはcheckboxというクラスを持つinput要素がチェックされたらbuttonタグのスタイルを変更するという例です。もし:has()機能が使用できない場合はどうしたらよいでしょうか。私であれば、JavaScriptにて実装が一般的な流れになりますね。疑似クラス:has()は
A要素を含んでいるB親要素を選択することができる
A要素が隣接しているまたは直後にある、B要素を選択することができる
:hasクラスが採用されたことで、JavaScriptで対応していたギミックが、使い方次第で様々な実装可能となりました。hasクラスの基本については理解できたかと思います。それでは本題をご紹介させていただきます。
知人のディレクターより、「とあるアプリで、システムからはきだされているアンケートフォームを装飾してほしい」という相談がありました。お話聞くと作業の制約として
コントロールパネルがあり、チェックボックスやラジオボタンを選択してドラックアンドドロップでHTML等一切さわらず、コンパネ内で無限にフォームを作成することができる。
※契約されたクライアントへ各フォームを提供してアンケートやお問合せとして利用してもらう一元管理、のほうが伝わるかもしれませんね
コンパネで作成されたフォームへのマークアップ構造の追加・変更はできない
クラス名はシステムで割り当てられている、追加はできない
JavaScriptの追加や追記はできない
CSSファイルへの追記はできる
とんでもない制約でした。アンケートフォームは一般的なシンプルフォームなんですが、結論はCSSファイルの追記しかできない。どうやら知人へ相談されたクライアント様が購入されたエンジンのようで、システム改修してアンケートフォームを装飾できるようにしたいという相談をシステム会社(国外)にされたらとんでもない改修への見積費用がきたとの事。購入時点よりできることは、CSSファイルへの追記(コンパネ内)だけはできる。まぁあるあるです。盛り上がってまいりました。
一度システムではきだされた構造みせてほしいと伝え、確認するとこれは難題。
下記はその一部の例です。
<div class="form-group">
<div class="form-group-wrap">
<label for="form-group-lead" class="text-color-Black">フォーム選択01</label>
<div class="checkboxes">
<div>
<div class="checkbox">
<label class="text-wrap" for="form-group-checkbox_50">
<input type="checkbox" id="form-group-checkbox_50" class="checkbox-absolute" name="checkbox_1" value="0">チェック1
</label>
</div>
</div>
<div>
<div class="checkbox">
<label class="text-wrap" for="form-group-checkbox_51">
<input type="checkbox" id="form-group-checkbox_51" class="checkbox-absolute" name="checkbox_2" value="1">チェック2
</label>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="form-group-wrap">
<label for="form-group-lead" class="text-color-Black">フォーム選択02</label>
<div class="checkboxes">
<div>
<div class="checkbox">
<label class="text-wrap" for="form-group-checkbox_52">
<input type="checkbox" id="form-group-checkbox_52" class="checkbox-absolute" name="checkbox_1" value="2">チェック1
</label>
</div>
</div>
<div>
<div class="checkbox">
<label class="text-wrap" for="form-group-checkbox_53">
<input type="checkbox" id="form-group-checkbox_53" class="checkbox-absolute" name="checkbox_2" value="3">チェック2
</label>
</div>
</div>
</div>
</div>
</div>
システムで割り振られたforとid以外は同名のみ。これをどうされたいかと聞くとデフォルトのチェックボックスを下記の仕組み・見え方にしたいというお話。
クリックされたら各色別に変更
これは相談内容の一部分で、まぁ項目数はまだまだあります。普通ならこの程度となる作業でしたがJavaScript追加だめ、マークアップ構造修正・クラス追加修正もできない。軽く頭を抱えてしまいました。さらに盛り上がってまいりました。
Level4が策定した疑似クラスがなければ結構アウトな相談でした。各チェックボックスが同じマークアップ構造の中で唯一の各要素へシステムより振り分けられているvalue属性に振られている番号があります。これを:has()の考え、【A要素を含んでいるB親要素を選択することができる】にてコーディングした例が下記になります。
.checkboxes {
display: flex;
flex-wrap: wrap;
align-content: space-around;
}
.checkboxes input[type=checkbox] {
display: none;
}
.checkboxes label {
display: block;
width: 3.5rem;
height: 1rem;
text-align: center;
line-height: 1rem;
padding: 0 5rem;
border-radius: 5px;
margin-right: .5rem;
cursor: pointer;
color: #fff;
background-color: #ccc;
}
.checkboxes label:has(input[type=checkbox][value="0"]:checked){
background: #95ECEC;
}
.checkboxes label:has(input[type=checkbox][value="1"]:checked){
background: #E0E82D;
}
.checkboxes label:has(input[type=checkbox][value="2"]:checked){
background: #224949;
}
.checkboxes label:has(input[type=checkbox][value="3"]:checked){
background: #BC408A;
}
いかがでしょうか。わりとすっきり解決していますね。今回はアプリという事もありましたが皆さんがもし:has()を使用する場合は、Firefoxのサポートがされたばかりという事を念頭にその点はクライアントやディレクターに説明をしておきましょう。IE7/8でいろいろ苦労した私からの助言です。
いかがでしたでしょうか。今回はLevel4より疑似クラス:has()について紹介させていただきました。今回紹介した方法以外でも、JavaScriptでクラスを付与し:has()を実装するなど考え方次第でコーディングの可能性がバージョンアップしたかと思います。効率のよいコーディングに是非ご活用ください。
以上となります。できる限りわかりやすく伝えようとしても書くのは難しいです。
コードや記事の書き方について気になるところがあれば、アドバイスいただけると嬉しいです。
要件定義からブラッシュアップ/実装運用まで一貫して担当。また内部対策を中心に、GTM・GA4・Looker Studioと分析・改善案の策定も進めています。北緯43度マルチエンジニア