web-dev-qa-db-ja.com

複数行のフレックスボックスレイアウトで改行を指定する方法

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

たとえば、 このCodePen の各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; */    
}
170
Artem Svirskyi

最も簡単で信頼性の高い解決策は、適切な場所にフレックスアイテムを挿入することです。それらが十分に広い場合(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>

しかしそれは醜く、意味的ではありません。代わりに、flexコンテナ内に擬似要素を生成し、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>

しかし制限があります:flexコンテナは::before::after疑似要素しか持つことができません。つまり、強制改行は2行だけです。

これを解決するために、フレックスコンテナ内ではなくフレックスアイテム内に擬似要素を生成できます。これにより、2に限定されることはありません。ただし、これらの擬似要素はフレックス項目にはならないため、強制的に改行することはできません。

しかし幸運なことに、 CSS Display L3display: contents を導入しました(現在Firefox 37でのみサポートされています):

要素自体はボックスを生成しませんが、その子と擬似要素は通常どおりボックスを生成します。ボックス生成とレイアウトの目的のために、要素は、それが文書ツリー内でその子要素と擬似要素で置き換えられたかのように扱われなければなりません。

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

.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>

あるいは、 Fragmenting Flex Layout および CSS Fragmentation に従って、Flexboxでは break-beforebreak-after 、またはそれらのCSS 2.1エイリアスを使用して強制中断を行うことができます。

.item:nth-child(3n) {
  page-break-after: always; /* CSS 2.1 syntax */
  break-after: always; /* New 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;
  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>

Flexboxでの強制改行はまだ広くサポートされていませんが、Firefoxでは動作します。

260
Oriol

2017年10月の時点で悲しいことに@Oriolは素晴らしい答えを持っています、どちらもdisplay:contentsも、page-break-afterも広くサポートされていませんが、他のプレイヤーではなくFirefoxをサポートしています。それはそれがページをモバイルにやさしいものにすることを非常に難しくするためです。

言ったようにそれはハックであり、欠点はあなたが無用のためにかなり多くの余分な要素を追加する必要があるということですが、それはトリックをし、日付を記入されたIE11上でもクロスブラウザで動作します。

「ハック」は各divの後に追加の要素を追加することです。これはdisplay:noneに設定され、css nth-childを使用して実際に表示されるものを決定し、次のように行ブレーキを強制します。

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  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-1) {
  background: silver;
}
.breaker {display:none;}
.breaker:nth-child(3n) {
  display:block;
  width:100%;
  height:0;
 }
<div class="container">
  <div class="item">1</div><p class=breaker></p>
  <div class="item">2</div><p class=breaker></p>
  <div class="item">3</div><p class=breaker></p>
  <div class="item">4</div><p class=breaker></p>
  <div class="item">5</div><p class=breaker></p>
  <div class="item">6</div><p class=breaker></p>
  <div class="item">7</div><p class=breaker></p>
  <div class="item">8</div><p class=breaker></p>
  <div class="item">9</div><p class=breaker></p>
  <div class="item">10</div><p class=breaker></p>
</div>
20
Emil Borconi

私の考えでは、<hr>要素を改行として フレックスアイテムの間に使用するほうが意味的です。

<div class="container">
  <div>1</div>
  <div>2</div>
  <hr>
  <div>3</div>
  <div>2</div>
  ...
</div>

CSSは以下の通りです

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

.container hr {
  width: 100%;
}

Chrome 66、Firefox 60、Safari 11でテスト済み。

15
Petr Stepanov

意味のある改行をしたいですか?

それから<br>の使用を検討してください。 W3Schoolsでは、BRは詩を書くためのものであることをお勧めしています(もうすぐです)が、スタイルを変更して、コンテンツを次の行にプッシュする幅100%のブロック要素として動作するようにできます。 'br'が中断を示唆しているなら、hrや100%のdivを使うよりも私にはふさわしいと思われ、htmlを読みやすくします。

改行が必要な場所に<br>を挿入し、このようにスタイルを設定します。

 // Use `>` to avoid styling `<br>` inside your boxes 
 .container > br 
 {
    width: 100%;
    content: '';
 }

必要に応じて<br>blockまたはnoneに設定することで、 メディアクエリでdisplay:を無効にする _を実行できます(この例を含めましたが、コメントアウトしたままにしています)。

必要ならばorder:を使って順番を設定することもできます。

そして、クラスや名前を変えて好きなだけ置くことができます:-)

.container {
  background: tomato;
  display: flex;
  flex-flow: row wrap;
  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
}

.container > br
{
  width: 100%;
  content: '';
}

// .linebreak1 
// { 
//    display: none;
// }

// @media (min-width: 768px) 
// {
//    .linebreak1
//    {
//       display: block;
//    }
// }
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <br class="linebreak1"/>
  <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>

W3Schoolsの発言に限定する必要はありません。

enter image description here

6
Simon_Weaver

私は伝統的なやり方が柔軟で理解しやすいと思います。

マークアップ

<div class="flex-grid">
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>

    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>

    <div class="col-3">.col-3</div>
    <div class="col-9">.col-9</div>

    <div class="col-6">.col-6</div>
    <div class="col-6">.col-6</div>
</div>

grid.css fileを作成します。

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

.col-1 {flex: 0 0 8.3333%}
.col-2 {flex: 0 0 16.6666%}
.col-3 {flex: 0 0 25%}
.col-4 {flex: 0 0 33.3333%}
.col-5 {flex: 0 0 41.6666%}
.col-6 {flex: 0 0 50%}
.col-7 {flex: 0 0 58.3333%}
.col-8 {flex: 0 0 66.6666%}
.col-9 {flex: 0 0 75%}
.col-10 {flex: 0 0 83.3333%}
.col-11 {flex: 0 0 91.6666%}
.col-12 {flex: 0 0 100%}

[class*="col-"] {
  margin: 0 0 10px 0;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

@media (max-width: 400px) {
  .flex-grid {
    display: block;
  }
}

の例を作成しました(jsfiddle)

400pxの下でウィンドウのサイズを変更してみてください、それは敏感です!

5
Moshe Quantz

余分なマークアップを追加する必要のない別の可能な解決策は、要素を区切るために動的なマージンを追加することです。

例の場合、これはcalc()の助けを借りて行うことができ、margin-leftmargin-rightを3n + 2要素に追加するだけです(2、5、8)

.item:nth-child(3n+2) {
  background: silver;
  margin: 10px calc(50% - 175px);
}

スニペットの例

.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+2) {
  background: silver;
  margin: 10px calc(50% - 175px);
}
<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>
1
Juanma Menendez

将来の質問については、floatプロパティを使用して、3つの要素ごとにクリアすることでも可能です。

これが私が作った例です。

.grid {
  display: inline-block;
}

.cell {
  display: inline-block;
  position: relative;
  float: left;
  margin: 8px;
  width: 48px;
  height: 48px;
  background-color: #bdbdbd;
  font-family: 'Helvetica', 'Arial', sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  text-indent: 4px;
  color: #fff;
}

.cell:nth-child(3n) + .cell {
  clear: both;
}
<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell">5</div>
  <div class="cell">6</div>
  <div class="cell">7</div>
  <div class="cell">8</div>
  <div class="cell">9</div>
  <div class="cell">10</div>
</div>
0
Gabriel