owned mediaウェブ制作に役立つコンテンツを発信中!

Sassで多重階層の入れ子リストのナンバリングした行頭記号を動的に作成する

前回記事「Pugでeach inを使って多重階層の入れ子リストを作成する」では、Pugを使って動的に入れ子リストを作成する方法をまとめていましたが、今回はそのリストに合わせてナンバリングした行頭記号をSassで動的に作成してみたいと思います。なかなか利用シーンとしては限定的ではありますが、先日クライアントワークで作成してみたこともあり備忘録として残しておきたいと思います。   また、今回は序列リスト(ol要素)を使う想定で、行頭記号にはリスト順序に合わせたナンバリングを適用させる形になります。入れ子になっているものは親要素のリスト順を継承する形となり、ドキュメントの章番号を表すようなイメージです。リスト順序に合わせたナンバリングについてはCSSで実装する方法を過去記事「CSSでリスト要素につける連番をカスタマイズする」で詳しく解説していますのでご参考に。   では、早速今回のサンプルとなるHTMLを見ていきます。このようにリストが多重階層の入れ子形式となっており、かなりややこしい感じになっています。後述するスタイルを適用させるため、それぞれのリスト要素に関してはネストの深さに合わせてclass名をあてています。下記はHTMLですが、Pugバージョンも記事下記のサンプル、もしくはこちらで確認できますのでご参考に。 【HTML】※一部抜粋
<ol class="nest-0">
  <li><span>リスト大項目</span>
    <ol class="nest-1">
      <li><span>リスト中項目</span></li>
      <li><span>リスト中項目</span>
        <ol class="nest-2">
          <li><span>リスト小項目</span></li>
          <li><span>リスト小項目</span>
            <ol class="nest-3">
              <li><span>リスト最小項目</span></li>
              <li><span>リスト最小項目</span></li>
            </ol>
          </li>
          <li><span>リスト小項目</span></li>
        </ol>
      </li>
      <li><span>リスト中項目</span>
    </ol>
  </li>
  <li><span>リスト大項目</span></li>
</ol>
  続いてCSS(Sass)でこの入れ子になったリストの行頭記号をスタイリングしていきます。まずは入れ子リストのネスト数(入れ子の深さ)を変数で定義します。この数値があることで、入れ子の深さ別に行頭記号を変化させることができます。まずはリスト要素自体にそれぞれ基本となるスタイルを設定します。今回は行頭記号がナンバリングとなるため、深い入れ子になった場合には文字数が長くなります。そのためある程度の幅をもたせておきます。その影響でリスト全体に対して左側に余白が発生するのでネガティブマージンで調整しています。このあたりが行頭記号のデザインに合わせて調整しましょう。 【Sass(SASS)】
// 入れ子リストのネスト数
$nested: 3
ol
  margin: 0 0 0 -3em
  li
    padding: 0 0 0 6em
    position: relative
    &::before 
      position: absolute
      left: 0
      top: 0
      width: 6em
      text-align: right
  @for $index from 0 through $nested
    &.nest-#{$index} > li
      counter-increment: nest-#{$index}
      &::before
        @if $index == 0
          // 親要素のリスト項目
          content: counter(nest-#{$index})':'
        @else
          $prefix: counter(nest-#{$index - 1})'-'
          @if $index == 1
            // 子要素のリスト項目
            content: $prefix counter(nest-#{$index})':'
          @else
            @for $count from $nested - 1 through $index
              $prefix: join(counter(nest-#{$index - $count})'-', $prefix)
            // 孫要素以下のリスト項目
            content: $prefix counter(nest-#{$index})':'
  中盤以降は行頭記号を動的に生成するための指定になります。まずは「@for」で入れ子の深さ分ナンバリングの桁を増やしていきます。親要素のリストでは1桁に、子要素では2桁、孫要素以降は3桁〜となります。孫要素以降は入れ子の数が変化しても対応できるよう、桁数を増やすために「counter()」で作成した行頭記号を結合させる必要があります。その際にはSassで複数の値を結合できる時に使える「join()」関数を使います。そしてこの結合した値がそのまま行頭記号に出力されるようにします。 ややこしいのでポイントだけまとめますと、、このような感じになりますね。 ・@forで入れ子リストの数だけ個別のスタイル(counter-increment)を作成 ・counter()関数の値にインデックス数を使用して動的に変化 ・join()関数で値を追加していく   この入れ子の深さに合わせて動的に生成される部分ですが、CSSに変換されると下記のようになります。きちんと入れ子の深さに対応して変化しているのがわかりますね。 【CSS】※一部抜粋
ol.nest-0 > li {
  counter-increment: nest-0;
}
ol.nest-0 > li::before {
  content: counter(nest-0) ":";
}
ol.nest-1 > li {
  counter-increment: nest-1;
}
ol.nest-1 > li::before {
  content: counter(nest-0) "-" counter(nest-1) ":";
}
ol.nest-2 > li {
  counter-increment: nest-2;
}
ol.nest-2 > li::before {
  content: counter(nest-0) "-" counter(nest-1) "-" counter(nest-2) ":";
}
ol.nest-3 > li {
  counter-increment: nest-3;
}
ol.nest-3 > li::before {
  content: counter(nest-0) "-" counter(nest-1) "-" counter(nest-2) "-" counter(nest-3) ":";
}
  上記のスタイル指定で作成したリストはこのように表示されます。入れ子の深さに合わせたインデントと桁数が反映された行頭記号が出力されているのがわかりますね。よく見るフォーマットなので使いどころは色々とありそうですね。
1:リスト大項目
  1-1:リスト中項目
  1-2:リスト中項目
    1-2-1:リスト小項目
    1-2-2:リスト小項目
      1-2-2-1:リスト最小項目
      1-2-2-2:リスト最小項目
  1-3:リスト中項目
2:リスト大項目
  実際のソースコードとサンプルは下記にあげていますのでご確認ください。もちろん行頭記号は色々とカスタマイズできますし、入れ子の深さに合わせて文字サイズを調整するなども可能ですので表現の幅は意外と広いのではないでしょうか。

See the Pen nested-list-auto-styling-marker by designsupply (@designsupply) on CodePen.

 
  今回はSassを使って多重階層の入れ子リストにナンバリングした行頭記号を動的に作成してみました。ハードコーディングで書いていくと入れ子が増えた時やHTML構造が複雑になった場合にミスなども起こりやすくなりますし、Sassに用意されている機能を活用することで保守性も高まります。今回は入れ子のリストですが、色々と応用はできるので覚えておいても損はないのではと思います。   (こちらの記事も参考にどうぞ) Pugでeach inを使って多重階層の入れ子リストを作成する CSSでリスト要素につける連番をカスタマイズする
  • はてなブックマーク
  • Pocket
  • Linkedin
  • Feedly

この記事を書いた人

Twitter

sponserd

    keyword search

    recent posts

    • Twitter
    • Github
    contact usscroll to top
      • Facebook
      • Twitter
      • Github
      • Instagram