リストの項目タグである「<li>」を横並びにする様々なやり方

リストの項目タグである「<li>」を横並びにする様々なやり方

思い付く限り列挙すべし!

以前勤めていた会社で、月一程度で「勉強会」なるものをやっていた。もちろん、就業時間内w

こちらで問題を作成し、それぞれのコーダー(マークアップエンジニア)がクライアント案件の合間にその問題を解き、「勉強会」で答え合わせとその解説をするというもの。

といったわけで、当時の資料が出てきたので、そのあたりについて折角なので記事を作成しよう。

尚、内包される要素も縦横のサイズが固定されている限定された条件下であるためボロが出ていないが、運用を前提にすると、それぞれにメリット・デメリットがあるだろう。まぁIE6とかの時代ほどではないがw というわけで何かの参考にされば幸いだ。

元となる問題の作成日が2015年8月のため、若干の手直しはしているが、もしかしたら現状にはそぐわない微妙に間違っている箇所があるかも。その場合は「馬鹿だな」と笑って済ませて欲しいw

問題篇

<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

上記「ul > li *5」の要素を1グループとして、<li>要素は縦横100pxの正方形とする。
この時、1グループずつ違う方法でCSSの指定を行い、100px四方の「ブロック要素」5つを隙間なく横並びにする方法を出来るだけたくさん挙げる事。

対応ブラウザはIE10以上、Chrome/Safari/Firefoxは最新バージョンを想定。
問題作成時は2015年8月のため、IE10以上を指定しているが、現在はIE11以上でOKでしょう(流石に)。但しこの問題に関しては、IE10のための特別な指定は行っていないと記憶している。まぁ、こちらが見逃している答えがあるだろうが…。

HTMLは以下のとおり。基本的なCSSの指定については既に記述してある。<ul>、<li>へのidやclassを追加するのは可だが、タグ自体の追加修正、改変などは不可。そして、<ul>同士は40px空ける。

<!doctype html>
<html lang="jp">
<head>
  <meta charset="utf-8">
  <title>リストの項目タグ<li>を横並びにする方法 | trial vol.01</title>
  <style>
html {
  font-size: 62.5%;
}
body {
  background-color: #fff;
  line-height: 1;
  text-align: center;
  margin: 40px 0 60px;
}
h1 {
  margin-bottom: 40px;
}
ul {
  list-style: none;
}
 li {
  background-color: #ccc;
  width: 100px;
  height: 100px;
}
li:nth-child(2n) {
  background-color: #e6e6e6;
}
/* ++ ▼ 以下にCSSを追記 ▼ ++++++++++++++++++++++++++++++ */



/* ++ ▲ 以上にCSSを追記 ▲ ++++++++++++++++++++++++++++++ */
  </style>
</head>
<body>
  <h1>リストの項目タグ<li>を横並びにする方法</h1>
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
  <ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</body>
</html>

解答篇

nth-of-typeを使って<ul>に個別の指定をしても問題ないが、分かりやすいように<ul>にclassを追加し、<ul class="num1">、<ul class="num2">、<ul class="num3">…《略》として、前もって<ul>自体に共通の指定を追加しておく。

ul {
  width: 500px;        /* 100pxのブロックが5つなので、横幅を500pxに固定 */
  height: 100px;       /* 100pxのブロックの高さをそのまま記入 */
  margin: 0 auto 40px; /* 横幅を固定し、左右のマージンを「auto」にして要素をページのセンターに */
  padding: 0;          /* ブラウザデフォルトのスタイルシートをリセット */
}

.num1 – 定番の「float」を使った指定

.num1 li {
  float: left;
}

今更解説する必要もない定番の手法。

.num2 – これまた定番の「inline-block」を使った指定

.num2 {
  font-size: 0;
}
.num2 li {
  display: inline-block;
}

<li>に「display: table-cell;」を指定しただけでは、<li>の間に隙間が出てしまうため、今回は<ul>に対して font-size: 0; を指定。条件次第では、HTMLを下記のように記述すれば、<ul>への「font-size: 0;」の指定は不必要。

  <ul class="num2">
    <li></li><!--
    --><li></li><!--
    --><li></li><!--
    --><li></li><!--
    --><li></li>
  </ul>
  <ul class="num2">
    <li></li
    ><li></li
    ><li></li
    ><li></li
    ><li></li
    ></li>
  </ul>
  <ul class="num2">
    <li>
    </li><li>
    </li><li>
    </li><li>
    </li><li>
    </li>
  </ul>
  <ul class="num2">
    <li>
    <li>
    <li>
    <li>
    <li>
  </ul>

.num3 – さらに定番の「table-cell」を使った指定

.num3 li {
  width: 100px;
  display: table-cell;
}

「display: table-cell;」を使う利点はカラム落ちしない事。floatやinline-blockでは、子要素の横幅の合計が親要素の横幅以上になるとカラム落ちが発生するが、table-cellの場合はそれが起きない。

.num4 – 今やこれが主流かな?「flex」を使った指定

.num4 {
  display: flex;
}

このプロパティは記述が「display: box;」→「display: flexbox;」と変化し、現状では「display: flex;」という書き方が正しいらしい(2018/08/21現在)。詳しくは、下記サイトを参照の事(ちょっと古い記事だが…)。

.num5 – 本来の意図とは違う「column-count」を使った指定

.num5 {
  column-count: 5;
  column-gap:   0;
}

見出しにも書いているとおり、この方法はプロパティが策定された意図とは違う使い方になる。ただ、こういうやり方もあるというだけの事。
注意事項として、column-countを設定しただけでは<li>の間に隙間が出てしまうため、「column-gap: 0;」で隙間を「0」にしている。

.num6 – やや苦しいが「absolute」を使った指定

.num6 {
  position: relative;
}
.num6 li {
  position: absolute;
  top: 0;
}
.num6 li:nth-child(1) {
  left: 0;
}
.num6 li:nth-child(2) {
  left: 100px;
}
.num6 li:nth-child(3) {
  left: 200px;
}
.num6 li:nth-child(4) {
  left: 300px;
}
.num6 li:nth-child(5) {
  left: 400px;
}

苦しいというか、一つ前の「.num5」からは、もう無理矢理ですわw あと今更ながら、.num6 liと.num6 li:nth-child(1)はまとめた方がよかったかも。

.num7 – 強引に「margin」の設定だけで

.num7 li:nth-child(2) {
  margin: -100px 0 0 100px;
}
.num7 li:nth-child(3) {
  margin: -100px 0 0 200px;
}
.num7 li:nth-child(4) {
  margin: -100px 0 0 300px;
}
.num7 li:nth-child(5) {
  margin: -100px 0 0 400px;
}

「li:nth-child(1)」もしくは「li:first-child」は、何も指定しなくてもOK。

.num8 – ヤバいくらい強引な「inline」と「padding」の組み合わせ

.num8 {
  overflow: hidden;
}
.num8 li {
  display: inline;
  padding: 0 50px 100px;
}

ul.num8に指定している「overflow: hidden;」がないと、横幅はちょうど100pxで問題ないが(左右のパディングが50pxずつで計100px)、縦幅についてはブラウザによって微妙に数値が変わる(Chrome:115px / Firefox:116pxなど)。

これは、各ブラウザのフォントの解釈が影響しており、さらにフォントサイズやテキストのベースラインも影響しているため、例えば「padding: 50px;」や「padding: 100px 50px 0;」の指定では<ul>の500px × 100pxからズレた位置にブロックが配置される。

よって「font-size: 0;」にして「vertical-align: top;」にすると、<li>への指定だけで大丈夫だが、取り敢えず<ul>に「overflow: hidden;」を指定して、500px × 100pxの範囲からはみ出た部分を見えなくする方法を採用したw

.num9 – もう無茶苦茶~www「transform」を使う

.num9 {
  margin-top: 140px;
  transform-origin: 0 0;
  transform: rotate(-90deg);
}

縦に並んでいるブロック要素を90度回転。transformの場合は、この手法以外にもやり方があるが、そこまで細分化するつもりはない。

以上、9つの方法を何とか捻りだした。