ブラウザ互換性に強いCSSカウンタ: @counter-style.fallback


@counter-style.fallback は、CSSの @counter-style ルールにおいて、指定されたカウンタースタイルが特定のカウンタ値に対してマーカー表現を作成できない場合に使用する代替カウンタースタイルを定義するためのプロパティです。これは、カウンタースタイルの柔軟性を高め、さまざまな状況に対応できるようにするのに役立ちます。

構文

@counter-style <カウンタースタイル名> {
  fallback: <代替カウンタースタイル名>;
}
  • <代替カウンタースタイル名>: 代替カウンタースタイルの名前。これは、別の @counter-style ルールで定義されたカウンタースタイル名、または decimaldisc などの標準のカウンタースタイルタイプ名であることができます。
  • <カウンタースタイル名>: 定義するカウンタースタイルの名前

@counter-style roman-upper {
  symbols: "I" "II" "III" "IV" "V" "VI" "VII" "VIII" "IX" "X";
  fallback: decimal;
}

ol {
  list-style: roman-upper;
}

この例では、roman-upper というカウンタースタイルが定義されています。このスタイルは、ローマ数字の大文字(I、II、III、...)を使用してカウンタ値を表します。

fallback: decimal; プロパティにより、カウンタ値が 10 を超える場合、roman-upper スタイルが 10 番目の項目以降に適用されず、代わりに標準の decimal スタイルが使用されます。

使用例

@counter-style.fallback は、次の状況で使用できます。

  • 複雑なカウンタ表現を作成する: 複数のカウンタースタイルを組み合わせることで、複雑なカウンタ表現を作成することができます。fallback プロパティを使用して、各スタイルの適用範囲を制御することで、より柔軟な表現が可能になります。
  • ブラウザの互換性を確保する: ブラウザによっては、すべてのカウンタースタイルをサポートしていない場合があります。fallback プロパティを使用して、サポートされていないスタイルに対して代替スタイルを指定することで、すべてのブラウザで一貫した表示を確保することができます。
  • カウンタースタイルの範囲を拡張する: range プロパティを使用してカウンタースタイルの適用範囲を制限する場合、fallback プロパティを使用して、範囲外の値に対して別のスタイルを指定することができます。

@counter-style.fallback は、CSSにおけるカウンタースタイルの機能を拡張する強力なプロパティです。適切に使用することで、より柔軟で、ブラウザ間で互換性のある、魅力的なカウンタ表現を作成することができます。

  • fallback プロパティは、すべてのブラウザでサポートされているわけではありません。古いブラウザでは、サポートされていない場合があり、デフォルトの decimal スタイルが使用される可能性があります。
  • fallback プロパティは、カウンタースタイルチェーンの一部です。カウンタースタイルが値を表現できない場合、そのスタイルの fallback プロパティで指定されたスタイルが使用されます。
  • @counter-style ルールは、要素レベルで list-style プロパティを使用して適用されます。


例 1: カウンタースタイルの範囲を拡張する

この例では、h2 見出しにカスタムカウンタースタイルを適用し、見出しレベルに応じてローマ数字とアルファベットを組み合わせたカウンタ表現を作成します。

@counter-style h2-counter {
  symbols: "I" "II" "III" "IV" "V" "A" "B" "C";
  range: 1 5;
  fallback: decimal;
}

h2 {
  counter-style: h2-counter;
  counter-reset: h2-counter;
}

このコードでは、h2-counter というカウンタースタイルが定義されています。このスタイルは、カウンタ値が 1 から 5 までの場合にローマ数字(I、II、III、...)、それ以降はアルファベット(A、B、C)を使用します。

range: 1 5; プロパティにより、このスタイルが 1 から 5 までのカウンタ値にのみ適用されます。カウンタ値が 6 以上の場合は、fallback プロパティで指定された decimal スタイルが使用されます。

例 2: ブラウザの互換性を確保する

この例では、section 要素にカスタムカウンタースタイルを適用し、古いブラウザでも一貫した表示を確保します。

@counter-style section-counter {
  symbols: url("section-counter.svg") /* カスタム SVG アイコン */;
  fallback: disc;
}

section {
  counter-style: section-counter;
  counter-reset: section-counter;
}

このコードでは、section-counter というカウンタースタイルが定義されています。このスタイルは、カスタム SVG アイコンを使用してカウンタ値を表します。

fallback: disc; プロパティにより、ブラウザが section-counter スタイルをサポートしていない場合、代わりに標準の disc スタイルが使用されます。

例 3: 複雑なカウンタ表現を作成する

この例では、ネストされたリストにカスタムカウンタースタイルを適用し、階層構造を表す複雑なカウンタ表現を作成します。

@counter-style nested-list {
  symbols: none;
  counter-increment: nested-list;
  fallback: decimal;
}

@counter-style nested-list-item {
  symbols: "(" counter(nested-list, ".") ")";
  fallback: disc;
}

ol {
  list-style: nested-list;
  counter-reset: nested-list;
}

ol li {
  list-style: nested-list-item;
}

このコードでは、2 つのカウンタースタイルが定義されています。

  • nested-list-item スタイルは、nested-list カウンタの現在の値をカッコ内に囲んで表示します。
  • nested-list スタイルは、カウンタ値をインクリメントするだけで、マーカー表現を作成しません。

ネストされたリストの場合、nested-list-item スタイルが nested-list スタイルの上に適用されます。これにより、各リスト項目の前に、その項目の階層レベルを示すカウンタ表現が表示されます。

これらの例は、@counter-style.fallback を使用してさまざまなカウンター表現を作成できることを示しています。

  • これらの例はあくまで基本的なものであり、より複雑なカウンター表現を作成するために @counter-style.fallback を組み合わせることもできます。


以下に、@counter-style.fallback の代替方法をいくつか紹介します。

複数の @counter-style ルールを使用する

@counter-style.fallback の代わりに、カウンタ値の範囲ごとに個別の @counter-style ルールを定義することができます。

@counter-style roman-upper-1 {
  symbols: "I" "II" "III";
  range: 1 3;
}

@counter-style roman-upper-2 {
  symbols: "IV" "V" "VI";
  range: 4 6;
}

@counter-style roman-upper-rest {
  symbols: "VII" "VIII" "IX" "X";
  fallback: decimal;
}

ol {
  list-style: roman-upper-1;
}

この例では、3 つの @counter-style ルールが定義されています。

  • roman-upper-rest スタイルは、カウンタ値が 7 以上の場合は適用され、代わりに fallback プロパティで指定された decimal スタイルが使用されます。
  • roman-upper-2 スタイルは、カウンタ値が 4 から 6 までの場合に適用されます。
  • roman-upper-1 スタイルは、カウンタ値が 1 から 3 までの場合に適用されます。

この方法は、単純なカウンター表現の場合に有効です。ただし、複雑なカウンター表現の場合は、複数のルールを管理するのが難しくなる可能性があります。

counter-set プロパティを使用する

counter-set プロパティを使用して、カウンタ値を個別に設定することができます。この方法により、@counter-style.fallback を使用せずに、カウンタ値の範囲を制御することができます。

ol {
  list-style: none;
  counter-reset: item;
}

li:nth-child(1) {
  counter-increment: item;
  content: counter(item, roman-upper) ". ";
}

li:nth-child(2) {
  counter-increment: item;
  content: counter(item, roman-upper) ". ";
}

/* ... 以降のリスト項目に対して同様の処理を行う */

この例では、counter-set プロパティを使用して item というカウンタを初期化しています。その後、各リスト項目に対して counter-increment プロパティを使用してカウンタ値を増分し、content プロパティを使用してカウンタ値をローマ数字で表示しています。

この方法は、柔軟性が高く、複雑なカウンター表現を作成する場合に適しています。ただし、コードが冗長になる可能性があります。

JavaScript を使用する

JavaScript を使用して、カウンタ値を動的に生成することができます。この方法により、より高度なカウンタ表現を作成することができます。

<!DOCTYPE html>
<html>
<head>
  <title>Counter Example</title>
  <style>
    ol {
      list-style: none;
    }

    li {
      counter-increment: item;
    }
  </style>
</head>
<body>
  <ol id="counter-list"></ol>

  <script>
    const list = document.getElementById('counter-list');

    for (let i = 1; i <= 10; i++) {
      const listItem = document.createElement('li');
      listItem.textContent = getRomanNumeral(i);
      list.appendChild(listItem);
    }

    function getRomanNumeral(num) {
      // ローマ数字に変換するロジック
    }
  </script>
</body>
</html>

この例では、JavaScriptを使用して getRomanNumeral 関数を作成し、カウンタ値をローマ数字に変換しています。その後、この関数を用いて、各リスト項目のコンテンツを生成しています。

この方法は、最も柔軟性が高く、複雑なカウンター表現を作成する場合に適しています。ただし、JavaScript の知識が必要となります。