カテゴリー
Misc

SVG 三角形

パーツとして使いたい時ように、最小限のコードで SVG の三角形。

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <polygon points="100 0, 0 100, 100 100" fill="red" />
</svg>
カテゴリー
CSS SASS

Flex 左揃え 5列以上も対応

フレックスボックスを使った以下のレイアウト。

  1. フレックスアイテムの幅は可変。
  2. フレックスアイテムの間隔が(ほぼ)一定
  3. フレックスアイテムは左揃え

例としてフレックスアイテムが 3列で間隔(ギャップ)を 10px として、HTML は以下とすると。

<div class="flex">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

まずは、フレックスコンテナーの設定。

.flex {
  display: flex;
  flex-wrap: wrap;
}

次にフレックスアイテムの幅は 100% / 3 – 20px / 3 なので、個々のアイテムの幅を設定。

.flex > div {
   width: calc(100% / 3 - 20px / 3);
   padding-top: calc(100% / 3 - 20px / 3); /* 仮の高さ */
   background-color: #000; /* 仮の背景色 */
}

4個目~のフレックスアイテム用に margin-top を設定。

.flex > div:nth-child(n+4) {
  margin-top: 10px;
}

各行の先頭のフレックスアイテム以外に margin-left を設定。

.flex > div:not(:nth-child(3n+1)) {
  margin-left: 0;
  background-color: #ccc; /* 仮の背景色 */
}

上記で大体 OK のはずだけど、割り切れない時の小数点の扱いによって、想定する列数でなくなるので、各行の最後のフレックスアイテムは margin-left を auto に設定。

.flex > div:nth-child(3n) {
  margin-left: auto;
}

インターネット上の記事でよく space-between + 疑似要素で左寄せにする方法を見るけど、それだと5列以上には対応できないし、疑似要素を追加する必要もないので、一案として。

Sass のミックスインにしておけば4列以上も簡単に書き出せる。

@mixin flex(
  $row: 3,
  $gap: 10px,
) {
  display: flex;
  flex-wrap: wrap;

  $column-gap: ($row - 1) * $gap;
  $second-row: $row + 1;

  & > div {
    width: calc(100% / #{$row} - #{$column-gap} / #{$row});
    padding-top: calc(100% / #{$row} - #{$column-gap} / #{$row}); // 仮の高さ
    background-color: #000; // 仮の背景色
  }

  & > div:nth-child(n+#{$second-row}) {
    margin-top: $gap;
  }

  & > div:not(:nth-child(#{$row}n+1)) {
    margin-left: $gap;
    background-color: #ccc; // 仮の背景色
  }

  & > div:nth-child(#{$row}n) {
    margin-left: auto;
  }
}

5列を書き出す。

.flex {
  @include flex(5);
}

6列で間隔を 15px で書き出す。

.flex {
  @include flex(6, 15px);
}

IE11 にも対応。