フレックスボックス:行あたり4アイテム


260

フレックスボックスを使用して、ページに合わせて動的にサイズ変更される8つのアイテムを表示しています。アイテムを強制的に2行に分割するにはどうすればよいですか?(1行に4つ)?

以下は関連する抜粋です。

(または、jsfiddleを使用する場合-http : //jsfiddle.net/vivmaha/oq6prk1p/2/ )

.parent-wrapper {
  height: 100%;
  width: 100%;
  border: 1px solid black;
}
.parent {
  display: flex;
  font-size: 0;
  flex-wrap: wrap;
  margin: -10px 0 0 -10px;
}
.child {
  display: inline-block;
  background: blue;
  margin: 10px 0 0 10px;
  flex-grow: 1;
  height: 100px;
}
<body>
  <div class="parent-wrapper">
    <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
  </div>
</body>


16
[更新]この質問は、応答性の低い設計に基づいていました。以下の回答のいずれかを使用している場合は、注意してください。優れたデザインでは、幅の広い画面ではアイテム数が多くなり、小さな画面ではアイテム数が少なくなります。すべての画面サイズで4つの項目を強制すると、狭い範囲の画面幅でのみ魅力的に見えます。
Vivek Maharajh 2018

回答:


381

あなたはflex-wrap: wrapコンテナに乗りました。デフォルト値であるnowrapsource)をオーバーライドするので、これは良いことです。これはアイテムがグリッドを形成するためにラップしない理由であるいくつかのケース

この場合、主な問題はflex-grow: 1flexアイテムにあります。

flex-growプロパティは、実際のサイズフレックス項目をしません。そのタスクは、コンテナー(source)の空き領域を分散することです。したがって、画面サイズがどれほど小さくても、各アイテムはライン上の空き領域の比例した部分を受け取ります。

より具体的には、コンテナには8つのflexアイテムがあります。を使用するとflex-grow: 1、それぞれが回線上の空きスペースの1/8を受け取ります。アイテムにコンテンツがないため、幅が0に縮小され、折り返されることはありません。

解決策は、アイテムの幅を定義することです。これを試して:

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

.child {
  flex: 1 0 21%; /* explanation below */
  margin: 5px;
  height: 100px;
  background-color: blue;
}
<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>

flex-grow: 1定義されたflex速記、は必要ありませんflex-basis実際に起因する余白に行ごとに3つの項目につながる25%であるとは。

以来flex-grow、行の空き領域を消費します、flex-basis唯一のラップを強制する十分な大きさにする必要があります。この場合、を使用するとflex-basis: 21%、マージン用に十分なスペースがありますが、5番目のアイテムには十分なスペースがありません。


1
うまくいったので気に入ったのですが、「たっぷりのスペース」で少し不安になります。この「見積もり」が私に失敗する可能性のある小さなウィンドウまたは状況はありますか?
ジャクソン

1
どんな状況?ほとんどのレイアウトでは、問題を引き起こす可能性のある極端なケースがあります。このようなケースは通常、発生しないか、ほとんど発生しないため、費用便益分析を通過します。たとえば、上記のソリューションで非常に大きなマージンを設定すると、レイアウトが壊れる可能性があります。問題がある場合は、質問に投稿してください。@ジャクソン
マイケルベンジャミン

2
「余白を非常に大きくすると、レイアウトが崩れる可能性があります」これは、回避したいシナリオの例です。実用性は気にしません。完璧への憧れを楽しませる。より正確にする方法はありますか?
ジャクソン

27
次も使用できますflex: 1 0 calc(25% - 10px);
MarkG '19

2
正解です。margin: 2%;小さなデバイス/解像度でボックスが新しい行にジャンプするのを防ぐために、固定ピクセル数の代わりに使用する小さな改善があります。一般的な式は(100 - (4 * box-width-percent)) / 8、さまざまなボックス幅の%です
thomaspsk

104

.child要素に幅を追加します。個人的には、margin-left行ごとに常に4にしたい場合は、パーセンテージを使用します。

デモ

.child {
    display: inline-block;
    background: blue;
    margin: 10px 0 0 2%;
    flex-grow: 1;
    height: 100px;
    width: calc(100% * (1/4) - 10px - 1px);
}

良いアイデア。このアイデアを少し編集して使用しました。jsfiddle.net/vivmaha/oq6prk1p/6
Vivek Maharajh 2015

1
ああ。これは実際には私の問題を解決しません。例については、こちらをご覧ください:jsfiddle.net/vivmaha/oq6prk1p/7。マージンにパーセンテージを使用する自由がありません。それらは固定幅でなければなりません。これは、固定マージンが考慮されていないため、選択したマジック23%が機能しないことを意味します。
Vivek Maharajh 2015

3
はい、calcが解決します!「calc(100%*(1/4)-10px-1px)」。jsfiddle.net/vivmaha/oq6prk1p/9を
Vivek Maharajh

24
それでも、これでフレックスの使用は何ですか?
–twicejr

レスポンシブデザインについてはどうですか?子供に固定幅を設定したくない
ろうそくのジャック

40

ここに別のアプローチがあります。

次の方法でも実現できます。

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

.child{
  width: 25%;
  box-sizing: border-box;
}

サンプル:https : //codepen.io/capynet/pen/WOPBBm

そして、より完全なサンプル:https : //codepen.io/capynet/pen/JyYaba


1
子供が4人未満の場合はどうなりますか?私はその空白の空のスペースが嫌いです、子供は反応しません...
キャンドルジャック

Muddasir Abbasによるもう1つの回答はフレックス設定のみを使用しているため、よりクリーンなソリューションだと思います。
Andrew Koster

17

ガターに負のマージンと計算を使用して、このようにします。

.parent {
  display: flex;
  flex-wrap: wrap;
  margin-top: -10px;
  margin-left: -10px;
}

.child {
  width: calc(25% - 10px);
  margin-left: 10px;
  margin-top: 10px;
}

デモ: https : //jsfiddle.net/9j2rvom4/


代替CSSグリッドメソッド:

.parent {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

デモ: https : //jsfiddle.net/jc2utfs3/


14
<style type="text/css">
.parent{
    display: flex;
    flex-wrap: wrap;
}
.parent .child{
    flex: 1 1 25%;
}
</style>    
<div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>

それが役に立てば幸い。詳細については、このリンクをたどることができます


4

この例は、@ dowomenfart よりも必要最小限で理解やすいと思います。

.child {
    display: inline-block;
    margin: 0 1em;
    flex-grow: 1;
    width: calc(25% - 2em);
}

これにより、肉までまっすぐに切りながら同じ幅の計算ができます。計算ははるかに簡単で、そのスケーラビリティとモバイルフレンドリーによりem新しい標準です。


3
emは実際には新しい標準ではありません。それはお尻の痛みになる可能性があり、設計者はEMを考慮して設計しません。
ダニーファンホルテン2018

2

.parent-wrapper {
	height: 100%;
	width: 100%;
	border: 1px solid black;
}
	.parent {
	display: flex;
	font-size: 0;
	flex-wrap: wrap;
	margin-right: -10px;
	margin-bottom: -10px;
}
	.child {
	background: blue;
	height: 100px;
	flex-grow: 1;
	flex-shrink: 0;
	flex-basis: calc(25% - 10px);
}
	.child:nth-child(even) {
	margin: 0 10px 10px 10px;
	background-color: lime;
}
	.child:nth-child(odd) {
	background-color: orange; 
}
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style type="text/css">

	</style>
</head>
<body>
  <div class="parent-wrapper">
    <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
  </div>
</body>
</html>

;)


1
できれば、コードを投稿するだけでなく、なぜこれがOPの質問に答えるのかについての説明を追加してください。
d219

justify-content: space-evenly;prentに追加した場合、それらはうまく整列calcし、子供に対してを実行する必要はありません。しかし、例をありがとう!
Mattijs

0

フレックスラップ+負のマージン

なぜフレックスなのdisplay: inline-blockか?

なぜマイナスマージン?

エッジケース(つまり、列の最初の要素)にSCSSまたはCSS-in-JSを使用するか、デフォルトのマージンを設定して、後で外側のマージンを削除します。

実装

https://codepen.io/zurfyx/pen/BaBWpja

<div class="outerContainer">
    <div class="container">
        <div class="elementContainer">
            <div class="element">
            </div>
        </div>
        ...
    </div>
</div>
:root {
  --columns: 2;
  --betweenColumns: 20px; /* This value is doubled when no margin collapsing */
}

.outerContainer {
    overflow: hidden; /* Hide the negative margin */
}

.container {
    background-color: grey;
    display: flex;
    flex-wrap: wrap;
    margin: calc(-1 * var(--betweenColumns));
}

.elementContainer {
    display: flex; /* To prevent margin collapsing */
    width: calc(1/var(--columns) * 100% - 2 * var(--betweenColumns));
    margin: var(--betweenColumns);
}

.element {
    display: flex;
    border: 1px solid red;
    background-color: yellow;
    width: 100%;
    height: 42px;
}

-12

を使用しない別の方法を次に示しcalc()ます。

// 4 PER ROW
// 100 divided by 4 is 25. Let's use 21% for width, and the remainder 4% for left & right margins...
.child {
  margin: 0 2% 0 2%;
  width: 21%;
}

// 3 PER ROW
// 100 divided by 3 is 33.3333... Let's use 30% for width, and remaining 3.3333% for sides (hint: 3.3333 / 2 = 1.66666)
.child {
  margin: 0 1.66666% 0 1.66666%;
  width: 30%;
}

// and so on!

これですべてです。あなたはより美的なサイズを得るために寸法を凝らすことができますが、これはアイデアです。


6
私はこれをテストしていませんが、CSS構文が間違っている(CSS値は引用符で囲まれておらず、宣言はセミコロンで終了する必要がある)ため、現在の形式では確実に機能しません。
Nick F
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.