複数行のフレックスボックスレイアウトで改行を指定するにはどうすればいいですか? 質問する

複数行のフレックスボックスレイアウトで改行を指定するにはどうすればいいですか? 質問する

複数行のフレックスボックスで改行する方法はありますか?

例えば、3番目の項目ごとに改行するには、このコードペン

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  height: 100px;
  background: gold;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px;
}
.item:nth-child(3n) {
  background: silver;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

のように

.item:nth-child(3n){
  /* line-break: after; */    
}

ベストアンサー1

最も簡単で信頼性の高い解決策は、適切な場所にフレックス アイテムを挿入することです。フレックス アイテムの幅が十分であれば ( width: 100%)、強制的に改行されます。

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}
.item:nth-child(4n - 1) {
  background: silver;
}
.line-break {
  width: 100%;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="line-break"></div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="line-break"></div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="line-break"></div>
  <div class="item">10</div>
</div>

しかし、これは見苦しく、意味的ではありません。代わりに、フレックス コンテナー内に疑似要素を生成し、orderそれを使用して適切な場所に移動することができます。

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}
.item:nth-child(3n) {
  background: silver;
}
.container::before, .container::after {
  content: '';
  width: 100%;
  order: 1;
}
.item:nth-child(n + 4) {
  order: 1;
}
.item:nth-child(n + 7) {
  order: 2;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>

ただし、制限があります。フレックス コンテナーには、::before::after疑似要素のみを含めることができます。つまり、強制的に改行できるのは 2 回だけです。

これを解決するには、flex コンテナー内ではなく、flex アイテム内に疑似要素を生成します。この方法では、2 つに制限されません。ただし、これらの疑似要素は flex アイテムではないため、強制的に改行することはできません。

しかし幸運なことに、CSS ディスプレイ L3導入したdisplay: contents(現在はFirefox 37、Chrome 65、Safari 11.1、Edge 79):

要素自体はボックスを生成しませんが、その子要素と疑似要素は通常どおりボックスを生成します。ボックスの生成とレイアウトの目的で、要素はドキュメント ツリー内の子要素と疑似要素に置き換えられたかのように扱われる必要があります。

したがって、フレックス コンテナーの子に適用しdisplay: contents、それぞれのコンテンツを追加のラッパー内にラップすることができます。すると、フレックス アイテムは、それらの追加ラッパーと子の疑似要素になります。

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  display: contents;
}
.item > div {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px;
}
.item:nth-child(3n) > div {
  background: silver;
}
.item:nth-child(3n)::after {
  content: '';
  width: 100%;
}
<div class="container">
  <div class="item"><div>1</div></div>
  <div class="item"><div>2</div></div>
  <div class="item"><div>3</div></div>
  <div class="item"><div>4</div></div>
  <div class="item"><div>5</div></div>
  <div class="item"><div>6</div></div>
  <div class="item"><div>7</div></div>
  <div class="item"><div>8</div></div>
  <div class="item"><div>9</div></div>
  <div class="item"><div>10</div></div>
</div>

あるいは、仕様の古いバージョンFlexboxでは、break-beforebreak-afterまたは古い CSS 2.1 エイリアス:

.item:nth-child(3n) {
  page-break-after: always; /* CSS 2.1 syntax */
  break-after: always; /* CSS 3 syntax */
}

しかし、これらの強制改行はFirefoxでのみ機能し、現在の仕様では機能しないと思われます。新しい提案された方法(どこにも実装されていません)は、wrap-beforeまたはwrap-after:

.item:nth-child(3n) {
  wrap-after: flex; /* New proposed syntax */
}

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  align-content: space-between;
  justify-content: space-between;
}
.item {
  width: 100px;
  background: gold;
  height: 100px;
  border: 1px solid black;
  font-size: 30px;
  line-height: 100px;
  text-align: center;
  margin: 10px
}
.item:nth-child(3n) {
  page-break-after: always;
  break-after: always;
  wrap-after: flex;
  background: silver;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
  <div class="item">10</div>
</div>

おすすめ記事