logo
  • 現在做什麼
  • 關於我

Kalan

文章分類

  • 前端
  • 開發筆記
  • 雜談
  • 年度回顧

快速連結

  • 現在做什麼
  • 關於我
  • 聯絡我
  • 職涯思考🔗

關注我

在福岡生活的開發者,分享軟體開發與日本生活的點點滴滴。

© 2025 Kalan Made with ❤️. All rights reserved.

HTMLとCSSは多くの問題を解決できますが、JavaScriptも非常に重要です。

作成者:カランカラン2022年11月27日 9:57
ホーム/フロントエンド
💡

質問やフィードバックがありましたら、フォームからお願いします

英語原文

目次

  1. を通じてヒントスタイルを作成する
  2. と隣接セレクタを使用したカスタマイズスタイル
  3. 複数列の等高
  4. フォームの送信
  5. 擬似クラスを活用する
  6. 結論

本文は台湾華語で、ChatGPT で翻訳している記事なので、不確かな部分や間違いがあるかもしれません。ご了承ください

2017年に読んだ記事 – Effective前端1:能使用html/css解决的问题就不要使用JSは、初めて読んだときに非常に共感を覚え、当時まだ熟知していなかった多くの技術を学びました。皆さんにもぜひ読んでみてほしいです。JavaScriptはほとんどの問題を解決できますが、アクセシビリティの観点やパフォーマンス、バンドルサイズの観点から見ると、CSSで解決できることは確実に優れています。しかし、できるだけJSを使わないということは、まったく使わないということではなく、この2つには違いがあります。この記事では、上記で言及した記事を再度読み返し、改善できる点を指摘していきます。

:hoverを通じてヒントスタイルを作成する

確かに、:hoverを使ってユーザーにこのUI要素がインタラクティブであることを知らせることは、フロントエンドエンジニアにとって基本的な常識です。記事の中でも、:hoverを使ってドロップダウンメニューの効果を得ることができると述べられています。

.dropdown { position: relative; display: inline-flex; justify-content: space-around; gap: 1em; } .item { display: none; } .dropdown-item:hover + .item { display: block; position: absolute; top: 30px; left: 0; padding: 10px; background-color: #efefef; }
お問い合わせ
  • Item1
  • Item2

ホバー時にdisplay: blockに変更し、通常はdisplay: noneにします。これ自体には大きな問題はないように思えますが、ユーザーがマウスを使用してナビゲートしていない場合はどうでしょうか?ユーザーがキーボードでナビゲートしている場合、:hoverは効果がありません。また、DOMの構造に制限があり、トリガーするUI要素はドロップダウンリストと隣接する必要があります。

したがって、私の提案は、:hoverを使用してユーザーに要素がインタラクティブであることを示す際に、ユーザーがマウス以外でナビゲートする場合にどのようにインタラクトできるかを考慮すべきです。具体的には:

  • 追加で:focusを加えたり、クリックイベントをリッスンしてユーザーがドロップダウンメニューをトリガーできるようにする
  • aria-expandedを追加してスクリーンリーダーに現在のメニューの開閉状態を通知し、キーボードナビゲーションを追加してユーザーが上下キーでオプションを制御できるようにする
.dropdown { position: relative; display: inline-flex; justify-content: space-around; gap: 1em; } .item { display: none; } .dropdown-item:hover + .item, .dropdown-item:focus + .item { display: block; position: absolute; top: 30px; left: 0; padding: 10px; background-color: #efefef; }
  • Item1
  • Item2
function toggleExpanded() { const node = document.querySelector('#dropdown-1'); const prev = node.getAttribute('aria-expanded'); node.setAttribute('aria-expanded', prev === 'true' ? 'false' : 'true'); } const toggle = document.querySelector('#toggle'); toggle.addEventListener('focus', toggleExpanded); toggle.addEventListener('blur', toggleExpanded); toggle.addEventListener('mouseover', toggleExpanded); toggle.addEventListener('mouseleave', toggleExpanded);

この例では、ホバーによってドロップダウンをトリガーするだけでなく、JavaScriptを使用してフォーカスおよびマウスオーバーイベントをリッスンしてaria-expandedを調整しています。キーボードナビゲーションは本記事のテーマとは異なるため、実装していません。もしaria-expandedを使用する場合、CSSを次のように調整することもできます:

.dropdown-item:hover + .item,
.item[aria-expanded="true"]
{
  /* style */
}

:checkedと隣接セレクタを使用したカスタマイズスタイル

カスタマイズされたチェックボックスやラジオボタンを実装する場合、記事で言及されているテクニックを使用する必要があります。擬似クラスと隣接セレクタを組み合わせてカスタマイズされたチェックボックスを簡単に実現できます。

:checkedを使用する利点は、クラスをトグルするために追加のイベントリスナーを登録する必要がないことです。カスタマイズされたチェックボックスやラジオボタンを作成する場合は、できるだけこの方法を優先してください。ゼロから<div>を作成することを避け、考慮すべき点が多く、使用性も見た目が悪いかもしれませんが、最低でも機能するチェックボックスに勝るものはありません。

ただし、この方法を使用する際に注意すべき点がいくつかあります:

  • aria-labelを使用して、スクリーンリーダーにこのチェックボックスやラジオボタンの目的を知らせる(またはaria-labelledbyを使用)
  • 値の変化を通知するために<div role="status"></div>や他の方法を使用する(必要な場合)
  • フォーカスのスタイルを実装する

スクリーンリーダーがチェックボックスを読み上げる際、ラベル名と選択状態のみが読み上げられます。チェックボックスの目的が選択と未選択以外である場合(例えば、ダークテーマの切り替えなど)、追加のヒントを提供することでスクリーンリーダーが理解しやすくなります。

.label:has(input:focus-visible) { outline: 2px solid blue; } .track { position: relative; display: inline-block; width: 50px; height: 1.2rem; border-radius: 9999px; background-color: #778da9; cursor: pointer; } .track .cursor { position: absolute; left: 0; top: 1px; display: inline-block; width: 1.1rem; height: 1.1rem; border-radius: 50%; border: 1px solid #efefef; transition: transform 0.3s ease-in; background-color: #fff; } .checkbox .cursor { transform: translateX(0); } .checkbox:checked~.track .cursor { transform: translateX(1.3rem); } .checkbox:checked~.track { background-color: #778da9; } /* keep hidden but focusable */ .hidden { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; }
toggle.addEventListener('change', function(e) { const node = document.getElementById('status') node.innerHTML = '現在のテーマが切り替わりました' })

inputを隠しつつフォーカス効果を持たせるために、直接display: noneを使用せず、他のCSSプロパティを使用して隠します。また、キーボードナビゲーション時にフォーカススタイルが表示されるように、:focus-visibleを追加しました。これにより、キーボードナビゲーション(例:タブ)時のみルールが適用され、クリック時にはフォーカスの枠が表示されません。

複数列の等高

この記事は2016年に書かれたもので、そこに記載されている方法は実行可能ですが、少し古いスタイルです。2022年にはflexのサポートが非常に高いため、flexboxを直接使用して解決できます。さらに細かい制御が必要な場合はgridを使用できます。

原理は、flexレイアウトの特性を利用して、align-itemsはデフォルトでstretchになっており、コンテナの高さは同じ行内で最も高い要素に基づきます。複数の行が必要な場合は、flex-wrap: wrapを追加することを忘れないでください。さもなければ、デフォルトではflexboxは同じ行にすべて詰め込もうとします。

.container { max-width: 1200px; width: 95%; margin: 0 auto; display: flex; /* comment me */ flex-wrap: wrap; justify-content: flex-start; gap: 1em; } .card { width: 30%; // display: inline-block; /* comment me */ padding: 8px; background-color: #efefef; } .card img {max-width: 100%}

情報

この写真はUnsplashのClay Banksによって撮影されました

東京

この写真はUnsplashのJezael Melgozaによって撮影されました。

東京が好きな理由は、人々の溶け込みを見ることができる素晴らしい場所だからです。

フォームの送信

私は、著者が指摘したように、多くの人が実際にネイティブのフォーム<form>が数十年も存在していることを見落としていることに同意します。<form>を使用してフォーム内容を定義することで、大量のJavaScriptコードを節約できます。

記事の中で、ブラウザのネイティブなフォーム検証メカニズムと:invalid擬似クラスを組み合わせてスタイル処理を行うことができると述べられています。例では、無効状態のときに提出ボタンのopacity: 0.5に設定しています。しかし、作者は例の関係で<span>を使用しており、実装上は<button>を使用し、JavaScriptで入力値が不正な場合にdisabledを追加するのが一般的です。

フォームにまだ不慣れな方は、以下の2つの記事を参照してください:

  • HTMLにおけるForm Dataを理解する
  • formタグとFormDataの応用

擬似クラスを活用する

著者は、:checked、:focus、:invalidなどを利用することを提案しており、これらの擬似クラスを活用することで、不要なJavaScriptを節約でき、読みやすくなります。

擬似クラスに関しては、私も比較的新しい擬似クラスを紹介する記事を書いていますので、興味があればご覧ください。レイアウトに役立つ擬似クラス

結論

2017年はちょうど私がフロントエンドを始めた時期で、細部の処理にあまり自信がありませんでした。今振り返ってみると、良好なユーザー体験を実現するためには、多くの細部を考慮する必要があり、単にCSSを適用するだけでは終わりません。アクセシビリティを考慮するためには、JavaScriptがしばしば不可欠な役割を果たすことが多いのです。

← 配置に役立つ擬似クラス2022 Advent Of Code: カソード線管 →

この記事が役に立ったと思ったら、下のリンクからコーヒーを奢ってくれると嬉しいです ☕ 私の普通の一日が輝かしいものになります ✨

☕Buy me a coffee

目次

  1. を通じてヒントスタイルを作成する
  2. と隣接セレクタを使用したカスタマイズスタイル
  3. 複数列の等高
  4. フォームの送信
  5. 擬似クラスを活用する
  6. 結論