1. ホーム
  2. html

[解決済み] 複数行のフレックスボックスレイアウトで改行を指定するには?

2022-03-17 09:04:13

質問

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

例えば このCodePen .

.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; */    
}

解決方法は?

最もシンプルで確実な解決策は、フレックスアイテムを適切な位置に挿入することです。十分な幅がある場合 ( 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つだけです。

これを解決するには、フレックスコンテナの中ではなく、フレックスアイテムの中に疑似要素を生成すればよいのです。しかし、この擬似要素はフレックスアイテムではないので、改行を強制することはできません。

しかし、幸運なことに CSS表示L3 が導入されました。 display: contents (現在、Firefox 37 のみでサポート)。

要素そのものはボックスを生成しませんが、その子要素や 擬似要素でも通常通りボックスが生成されます。の目的のために ボックスの生成とレイアウトを行う場合、その要素はあたかも は、その子要素や擬似要素に置き換えられている。 ツリーになります。

そのため 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-before , break-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>