:targetを超えた!JavaScriptやHash IDsを使った代替方法で、もっと自由なWebデザインを実現


:target は CSS の擬似クラスの一つで、URL のフラグメント(# 記号で始まる部分)に対応する要素(ターゲット要素)にスタイルを適用するために使用されます。例えば、目次ページで各見出しにリンクを張り、その見出しをハイライト表示したい場合などに役立ちます。

構文

:target {
  /* スタイル定義 */
}

<a href="#section1">セクション1へ移動</a>
<a href="#section2">セクション2へ移動</a>

<h2 id="section1">セクション1</h2>
<h2 id="section2">セクション2</h2>
#section1, #section2 {
  background-color: #f0f0f0; /* デフォルトの背景色 */
}

:target {
  background-color: #ffff00; /* ターゲット要素の背景色 */
}

上記の例では、#section1#section2 にはデフォルトの背景色が設定されています。一方、:target セレクタは、URL のフラグメントに対応する要素(つまり、クリックされた見出し)の背景色を黄色に変更します。

  • :target セレクタは、ページ遷移ではなく、同じページ内でのスクロールにのみ適用されます。別のページに移動した場合、:target セレクタは効果を発揮しません。
  • 複数の要素がターゲット要素になる可能性があります。例えば、同じ ID を持つ要素が複数存在する場合、それらの要素全てに :target セレクタのスタイルが適用されます。
  • :target は、ID 属性を持つ要素にのみ適用されます。クラス名や属性セレクタなどでは使用できません。

利点

  • 目次ページや長い記事ページなどで、ユーザーが目的の情報にたどり着きやすくするのに役立ちます。
  • ユーザーが現在閲覧しているページ内の特定のセクションを視覚的に強調することができます。
  • ターゲット要素を強調しすぎることで、他のコンテンツが見にくくなる可能性があります。デザインを調整する際には、全体のバランスを考慮する必要があります。
  • :target セレクタは、ユーザーの操作に依存するため、アクセシビリティの観点から問題がある場合があります。全てのユーザーがマウスやキーボードを使用できるわけではないことに注意する必要があります。


例1:目次ページのハイライト

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>目次ページ</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>目次</h1>
  <ul>
    <li><a href="#section1">セクション1</a></li>
    <li><a href="#section2">セクション2</a></li>
    <li><a href="#section3">セクション3</a></li>
  </ul>

  <main>
    <h2 id="section1">セクション1</h2>
    <p>セクション1の内容</p>

    <h2 id="section2">セクション2</h2>
    <p>セクション2の内容</p>

    <h2 id="section3">セクション3</h2>
    <p>セクション3の内容</p>
  </main>
</body>
</html>

CSS

body {
  font-family: sans-serif;
}

h1 {
  text-align: center;
}

ul {
  list-style: none;
  padding: 0;
}

li {
  margin-bottom: 10px;
}

a {
  text-decoration: none;
  color: #333;
}

:target {
  background-color: #ffff00;
}

このコードを実行すると、目次ページが表示されます。各見出しにリンクされており、クリックするとその見出しに移動します。現在表示されている見出しは、黄色でハイライト表示されます。

この例では、長い記事ページにナビゲーションバーを追加し、各セクションに簡単に移動できるようにします。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>長い記事</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>長い記事</h1>

  <nav>
    <ul>
      <li><a href="#introduction">はじめに</a></li>
      <li><a href="#content1">コンテンツ1</a></li>
      <li><a href="#content2">コンテンツ2</a></li>
      <li><a href="#conclusion">結論</a></li>
    </ul>
  </nav>

  <main>
    <h2 id="introduction">はじめに</h2>
    <p>記事の概要</p>

    <h2 id="content1">コンテンツ1</h2>
    <p>コンテンツ1の内容</p>

    <h2 id="content2">コンテンツ2</h2>
    <p>コンテンツ2の内容</p>

    <h2 id="conclusion">結論</h2>
    <p>記事のまとめ</p>
  </main>
</body>
</html>

CSS

body {
  font-family: sans-serif;
}

h1 {
  text-align: center;
}

nav {
  margin-bottom: 20px;
}

nav ul {
  list-style: none;
  padding: 0;
}

nav li {
  display: inline-block;
  margin-right: 20px;
}

nav a {
  text-decoration: none;
  color: #333;
}

nav a:hover {
  color: #007bff;
}

:target {
  background-color: #ffff00;
}

このコードを実行すると、長い記事ページが表示されます。記事の上にナビゲーションバーがあり、各セクションへのリンクが並んでいます。現在表示されているセクションは、黄色でハイライト表示されます。



注意点

  • 制約: :target は、ID 属性を持つ要素にのみ適用できます。クラス名や属性セレクタなどでは使用できません。
  • 複雑性: :target を使用すると、CSS コードが複雑になり、メンテナンスが難しくなる可能性があります。
  • アクセシビリティ: :target はユーザー操作に依存するため、全てのユーザーが恩恵を受けられるとは限りません。キーボードのみで操作するユーザーや、スクリーンリーダーを使用するユーザーにとって、ターゲット要素を識別することが困難になる場合があります。

これらの理由から、状況によっては :target の代替方法を検討することが重要です。以下に、いくつかの代替方法を紹介します。

代替方法

  1. JavaScript を使用する: JavaScript を使用して、URL フラグメントに基づいて要素を操作することができます。この方法であれば、アクセシビリティを向上させ、コードをより柔軟に記述することができます。
  2. Hash IDs を使用する: Hash IDs は、ランダムな文字列で作られた ID です。# 記号 followed by a random string. 独自の ID を生成することで、衝突を回避し、よりアクセスしやすいコードを作成することができます。
  3. Data 属性を使用する: Data 属性を使用して、要素にフラグを付けることができます。JavaScript でこのフラグを検出して、要素にスタイルを適用することができます。この方法であれば、CSS コードをシンプルに保つことができます。

JavaScript を使用する

<a href="#section1">セクション1へ移動</a>
<a href="#section2">セクション2へ移動</a>

<h2 id="section1">セクション1</h2>
<h2 id="section2">セクション2</h2>

<script>
  const targetElement = document.querySelector(':target');
  if (targetElement) {
    targetElement.style.backgroundColor = '#ffff00';
  }
</script>

Hash IDs を使用する

<a href="#h_42389">セクション1へ移動</a>
<a href="#h_12938">セクション2へ移動</a>

<h2 id="h_42389">セクション1</h2>
<h2 id="h_12938">セクション2</h2>

Data 属性を使用する

<a href="#section1">セクション1へ移動</a>
<a href="#section2">セクション2へ移動</a>

<h2 data-section="section1">セクション1</h2>
<h2 data-section="section2">セクション2</h2>

<script>
  const targetElement = document.querySelector('[data-section="' + window.location.hash.slice(1) + '"]');
  if (targetElement) {
    targetElement.style.backgroundColor = '#ffff00';
  }
</script>

これらの例は、それぞれ異なる方法で :target の機能を実現しています。最適な方法は、プロジェクトの要件と制約によって異なります。

上記以外にも、CSS ModulesShadow DOM などの新しい技術を使用して、:target の代替となる方法がいくつか提案されています。これらの技術は、よりモジュール化された、保守しやすい、そしてアクセシビリティに優れたコードを作成することができます。