クリエイティブ リストのスタイル設定

便利でクリエイティブなリストのスタイル設定方法をご紹介します。

リストと聞いて何を思い浮かべますか?最もわかりやすい例はショッピング リストです。これは最もシンプルなリストで、順不同でアイテムを集めたリストです。しかし、私たちはウェブではさまざまな方法でリストを使用しています。会場で予定されているコンサートのコレクションなどです。リストである可能性が高いです。複数のステップからなる予約プロセスおそらくリストね。画像のギャラリー?それもキャプション付きの画像のリストと見なすことができます。

この記事では、ウェブで利用できるさまざまな HTML リストの種類と、それらのリストを使用する状況について説明します。なかには、あまり知られていない属性も紹介します。また、CSS を使用してクリエイティブのスタイルを設定する便利でクリエイティブな方法についても説明します。

リストの用途

アイテムを意味的にグループ化する必要がある場合は、HTML リスト要素を使用する必要があります。支援技術(スクリーン リーダーなど)は、リストがあることとアイテムの数がユーザーに通知します。たとえばショッピングサイトの商品をグリッド表示にする場合、この情報があると非常に役立ちます。そのため、リスト要素を使用することをおすすめします。

タイプのリスト表示

マークアップに関しては、次の 3 つのリスト要素から選択できます。

  • 順序なしリスト
  • 順序付きリスト
  • 説明リスト

どちらを選択するかは、ユースケースによって異なります。

順序なしリスト(ul)

順序なしリスト要素(<ul>)は、リスト内のアイテムが特定の順序に対応していない場合に特に便利です。デフォルトでは箇条書きで表示されます。たとえば、順序が重要ではないショッピング リストなどです。

パン、ミルク、リンゴなどのアイテムのショッピング リスト。

ウェブ上でより一般的な例としては、ナビゲーション メニューがあります。メニューを作成する際には、支援技術をサポートするために、ulnav 要素でラップし、ラベルでメニューを識別することをおすすめします。また、メニュー内で現在のページを識別する必要があります。それには aria-current 属性を使用します。

<nav aria-label="Main">  
  <ul>  
    <li>  
      <a href="/page-1" aria-current="page">Menu item 1</a>  
    </li>  
    <li>  
      <a href="/page-2">Menu item 2</a>  
    </li>  
    <li>  
      <a href="/page-2">Menu item 2</a>  
    </li>  
      …  
    </ul>  
</nav>  

メニュー構造に関する記事では、すべてのユーザーがナビゲーション メニューにアクセスできるようにするためのおすすめの方法を紹介しています。

順序付きリスト(ol)

複数ステップのプロセスなど、アイテムの順序が重要な場合は、順序付きリスト要素(<ol>)が最適です。デフォルトでは、リストアイテムには番号が付けられます。たとえば、手順を順番に完了しなければならない一連の手順などです。

ミルク入り紅茶を作る手順を詳しく記述したリスト。

<ol> 要素と <ul> 要素はどちらも、直接の子として <li> 要素のみを含めることができます。

説明リスト(dl)

説明文のリストには、用語(<dt> 個の要素)と説明文(<dd>)が含まれます。各用語には複数の説明文を含めることができます。ユースケースとしては、用語の用語集やレストランのメニューなどが考えられます。デフォルトでは、説明のリストにマーカーは表示されませんが、ブラウザでは <dd> 要素がインデントされる傾向があります。

HTML では、<div> を使用して用語とそれに付随する説明をグループ化できます。これはスタイル設定に役立ちます。これについては後で説明します。

<!-- This is valid --> 
<dl>  
    <dt>Term 1</dt>  
    <dd>This is the first description of the first term in the list</dd>  
    <dd>This is the second description of the first term in the list</dd>  
    <dt>Term 2</dt>  
    <dd>This is the description of the second term in the list</dd>  
</dl>

<!-- This is also valid --> 
<dl>  
    <div>  
        <dt>Term 1</dt>  
        <dd>This is the first description of the first term in the list</dd>  
        <dd>This is the second description of the first term in the list</dd>  
    </div>  
    <div>  
        <dt>Term 2</dt>  
        <dd>This is the description of the second term in the list</dd>  
    </div>  
</dl>  

シンプルなリストのスタイル設定

リストの最も簡単な用途の 1 つは、本文のブロック内で使用することです。多くの場合、このような単純なリストでは複雑なスタイルは必要ありませんが、順序付きリストと順序なしリストのマーカーは、ブランドカラーやカスタム画像の使用などで、ある程度カスタマイズしたい場合があります。list-style 疑似要素と ::marker 疑似要素を使用すると、多くのことができます。

::マーカー

リスト マーカーの基本的なスタイル設定に加え、周期的な箇条書きも作成できます。ここでは、::marker 疑似要素の content 値に 3 つの異なる画像 URL を使用しています。これにより、(すべてに 1 つの画像を使用するのではなく)ショッピング リストの例を手書きした印象になります。

::marker {  
    content: url("/marker-1.svg") ' ';  
}

li:nth-child(3n)::marker {  
    content: url("/marker-2.svg") ' ';  
}

li:nth-child(3n - 1)::marker {  
    content: url("/marker-3.svg") ' ';  
}  

カスタム カウンタ

順序付きリストによっては、カウンタ値を使用して別の値を付加したい場合があります。list-item カウンタをマーカーの content プロパティの値として使用し、他のコンテンツを追加できます。

::marker {  
    content: counter(list-item) '🐈 ';  
}  

カウンタは自動的に 1 ずつインクリメントされますが、リストアイテムで counter-increment プロパティを設定することで、別の値でインクリメントすることもできます。たとえば、これによりカウンタは毎回 3 ずつ増えます。

li {  
    counter-increment: list-item 3;  
}  

カウンタには他にも多くの機能があります。いくつかの機能について詳しくは、CSS リスト、マーカー、カウンタの記事をご覧ください。

::マーカーのスタイル設定の制限事項

マーカーの位置やスタイルを細かく制御したい場合があります。たとえば、フレックスボックスやグリッドを使用してマーカーを配置することはできません。そのため、他の位置揃えが必要な場合は、デメリットになることがあります。::marker は、スタイル設定用の限られた数の CSS プロパティを公開します。基本的なスタイル設定以外のものが必要な場合は、別の疑似要素を使用した方がよいかもしれません。

リストのように見えないリストのスタイル設定

デフォルトのスタイルとはまったく異なる方法でリストのスタイルを設定したい場合があります。ナビゲーション メニューでは、このようなケースがよくあります。たとえば、通常はすべてのマーカーを削除したい場合、Flexbox を使用してリストを横に表示できます。一般的には、list-style プロパティを none に設定します。つまり、マーカーの疑似要素は DOM 内でアクセスできなくなります。

::before のカスタム マーカー

::before 疑似要素のスタイル設定は、::marker が登場する前は、カスタムリスト マーカーを作成する一般的な方法でした。今でも、必要に応じてより柔軟に、視覚的に複雑なリストのスタイル設定が可能になります。

::marker と同様に、content 属性を使用して独自のカスタム箇条書きスタイルを追加できます。::marker を使用する場合とは異なり、list-style-position による自動的なメリットは得られないため、手動によるポジショニングを行う必要があります。ただし、Flexbox を使用すると比較的簡単に配置でき、配置の可能性が大きく広がります。たとえば、マーカーの位置を変更できます。

::before 要素を使用して順序付きリストのスタイルを設定する場合は、カウンタを使用して数値マーカーを追加することもできます。

li::before {  
  counter-increment: list-item;  
  content: counter(list-item);  
}  

::marker ではなく ::before を使用すると、カスタム スタイル設定のための CSS プロパティに完全にアクセスできるだけでなく、アニメーションと遷移も許可できます(::marker のサポートは制限されています)。

リスト属性

順序付きリストの要素では、いくつかのオプションの属性を受け入れることができます。これは、さまざまなユースケースに役立ちます。

逆のリスト

過去 1 年間のトップ 10 アルバムのリストがある場合、10 枚から 1 枚までカウントダウンしてみましょう。そのためにカスタム カウンタを使用して、マイナスのカウンタをインクリメントすることもできます。または、HTML で reversed 属性を使用するという方法もあります。カウンタが純粋にプレゼンテーション用でない限り、CSS でカウンタにネガティブなインクリメントを行うのではなく、reversed 属性を使用するのが一般的にセマンティックな意味があると言えます。CSS の読み込みに失敗した場合でも、HTML 内で数字が正しくカウントダウンされます。さらに、スクリーン リーダーがリストをどのように解釈するかも考慮する必要があります。

2021 年のトップ 10 アルバムのデモをご覧ください。CSS のみでカウンタをインクリメントした場合、スクリーン リーダーを使用してページにアクセスしたユーザーは、数字が上向きにカウントされたと結論付ける可能性があります。したがって、10 は実際には 1 です。

このデモでは、reversed 属性を使用することで、特別な作業を行わなくてもマーカーに正しい値が設定済みであることがわかります。ただし、::before 疑似要素を使用してカスタムリスト マーカーを作成する場合は、カウンタを調整する必要があります。必要なのは、リストアイテム カウンタに負のインクリメントを指定することだけです。

li::before {  
  counter-increment: list-item -1;  
  content: counter(list-item);  
}  

Firefox ではこれで十分ですが、Chrome と Safari では、マーカーのカウントダウンは 0 から -10 までとなります。start 属性をリストに追加すると、この問題を修正できます。

リストの分割

start 属性を使用すると、リストを開始する数値を指定できます。これは、リストをグループに分割する場合に役立ちます。

トップ 10 のアルバムを例に考えてみましょう。実際には上位 20 件のアルバムを 10 枚のグループに分けてカウントダウンしたいかもしれません。2 つのグループの間には他のページ コンテンツがあります。

列の途中で要素が列にまたがるワイヤフレーム リスト。

HTML で 2 つの別々のリストを作成する必要がありますが、どうすればカウンタが正しくなるでしょうか。現在のマークアップでは、どちらのリストも 10 から 1 までカウントダウンされますが、これは望ましくありません。ただし、HTML では start 属性値を指定できます。最初のリストに start の値 20 を追加すると、マーカーが再び自動的に更新されます。

<ol reversed start="20">  
  <li>...</li>  
  <li>...</li>  
  <li>...</li>  
</ol>  

複数列リストのレイアウト

これまでのデモからわかるように、マルチカラム型レイアウトがリストに適している場合があります。列幅を設定することで、リストが自動的にレスポンシブになり、十分なスペースがある場合にのみ 2 つ以上の列に重なるようになります。列と列の間にギャップを設け、さらに目立たせるために、スタイル付きの column-rule を追加します(border プロパティと同様の省略形を使用します)。

ol {  
    columns: 25rem;  
    column-gap: 7rem;  
    column-rule: 4px dotted turquoise;  
}  

列を使用すると、リストアイテムが見づらくなってしまうことがありますが、期待どおりの効果が得られないことがあります。

コンテンツが 2 列に分割される様子を示すデモ。

リストアイテムで break-inside: avoid を使用すると、このような強制的な挿入を防ぐことができます。

li {  
    break-inside: avoid;  
}  

カスタム プロパティ

CSS カスタム プロパティを使用すると、リストのスタイル設定の可能性が広がります。リストアイテムのインデックスがわかっている場合は、それを使用してプロパティ値を計算できます。残念ながら現時点では、CSS だけで要素のインデックスを(どのような用途でも)特定する方法はありません。カウンタでは、content プロパティでその値しか使用できず、計算はできません。

ただし、HTML の style 属性内に要素のインデックスを設定できます。これにより、特にテンプレート言語を使用している場合は、計算の実行が容易になります。次の例は、Nunjucks を使用してこれを設定する方法を示しています。

<ol style="--length: items|length">  
  
</ol>  

Splitting.js は、クライアント側で同様の関数を実行するライブラリです。

カスタム プロパティ値を使用すると、さまざまな方法でリストの進行状況を示すことができます。一つは、ステップのリストの進行状況バーです。この例では、線形グラデーションを持つ疑似要素を使用して、ユーザーがリストのどこまでたどり着いたかを示す各アイテムのバーを作成しています。

li::before {  
    --stop: calc(100% / var(--length) * var(--i));  
    --color1: deeppink;  
    --color2: pink;  

    content: '';  
    background: linear-gradient(to right, var(--color1) var(--stop), var(--color2) 0);  
}  

また、hsl() カラー関数を使用して、リストが進むにつれて色相を調整することもできます。hue の値は、カスタム プロパティを使用して計算できます。

説明リストのスタイル設定

前述のように、用語とその定義を dldiv でラップすると、スタイル設定の選択肢が増えます。たとえば、リストをグリッドとして表示できます。各グループをラッパー div なしでリストで display: grid に設定すると、用語と説明が別々のグリッドセルに配置されます。以下の例のように、パイのメニューと説明を表示すると便利です。

リスト自体にグリッドを定義して、用語と説明が常に列で整列し、列幅が最長の用語によって決まるようにできます。

一方、説明カード形式の用語で明確にグループ化する場合は、ラッパー <div> は非常に便利です。

リソース