フレックスコンテナを中央に配置するが、フレックスアイテムを左揃えにする方法


92

フレックスアイテムを中央に配置したいのですが、2行目がある場合は、1の下に5(下の画像から)を配置し、親の中央には配置しません。

ここに画像の説明を入力してください

これが私が持っているものの例です:

ul {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0;
  padding: 0;
}
li {
  list-style-type: none;
  border: 1px solid gray;
  margin: 15px;
  padding: 5px;
  width: 200px;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
</ul>

http://jsfiddle.net/8jqbjese/2/

回答:


79

Flexboxの課題と制限

課題は、フレックスアイテムのグループを中央に配置し、ラップ上で左揃えにすることです。ただし、行ごとに固定数のボックスがあり、各ボックスが固定幅でない限り、これは現在、flexboxでは不可能です。

質問に投稿されたコードを使用して、我々は現在、フレックスコンテナ(ラップ新しいフレックスコンテナ作成することができul、私たちが中心にできるようになる)、ulとしますjustify-content: center

次に、のフレックスアイテムuljustify-content: flex-start。と左揃えにすることができます。

#container {
    display: flex;
    justify-content: center;
}

ul {
    display: flex;
    justify-content: flex-start;
}

これにより、左揃えのフレックスアイテムの中央に配置されたグループが作成されます。

この方法の問題は、特定の画面サイズでは、の右側にギャップがあり、中央にul表示されなくなることです。

ここに画像の説明を入力してください ここに画像の説明を入力してください

これは、フレックスレイアウト(および実際にはCSS一般)ではコンテナが次のように発生するために発生します。

  1. 要素がいつ折り返されるかはわかりません。
  2. 以前に占有されていたスペースが現在空であることを知りません、そして
  3. 幅を再計算して、狭いレイアウトをシュリンクラップしません。

右側の空白の最大長は、コンテナがそこにあると予想していたフレックスアイテムの長さです。

次のデモでは、ウィンドウのサイズを水平方向に変更することで、空白が行き来するのを確認できます。

デモ


より実用的なアプローチ

所望のレイアウトは、フレキシボックスを使用せずに達成することができるinline-blockメディアクエリ

HTML

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
</ul>

CSS

ul {
    margin: 0 auto;                  /* center container */
    width: 1200px;
    padding-left: 0;                 /* remove list padding */
    font-size: 0;                    /* remove inline-block white space;
                                        see https://stackoverflow.com/a/32801275/3597276 */
}

li {
    display: inline-block;
    font-size: 18px;                 /* restore font size removed in container */
    list-style-type: none;
    width: 150px;
    height: 50px;
    line-height: 50px;
    margin: 15px 25px;
    box-sizing: border-box;
    text-align: center;
}

@media screen and (max-width: 430px) { ul { width: 200px; } }
@media screen and (min-width: 431px) and (max-width: 630px) { ul { width: 400px; } }
@media screen and (min-width: 631px) and (max-width: 830px) { ul { width:600px;  } }
@media screen and (min-width: 831px) and (max-width: 1030px) { ul { width: 800px; } }
@media screen and (min-width: 1031px) and (max-width: 1230px) { ul { width: 1000px; } }

上記のコードは、次のように左揃えの子要素を持つ水平方向に中央に配置されたコンテナをレンダリングします。

ここに画像の説明を入力してください

デモ


その他のオプション


3
うん、人々がやりたいと思っていて、最終的にflexboxを使用することになるのは、実際にはグリッドを作成することだけです。幸いなことに、これは、到達がより最終的な状態になったときにCSSグリッドでカバーされます。
TylerH 2016年

1
この投稿をあなたの投稿にリンクしました。同じ問題を解決する方法がもう1つありますが、それでも重複している可能性があるので、それを閉じたいかどうかを自分で判断してください。そして、これの素晴らしい説明のためのプラス1。
Ason 2017年

おそらく別のアイデアはmargin:0 auto、すべてがページの中央に配置されるように、親ラッパーで行うことです。その時点から、すべての子コンポーネント(つまり、最初のフレックスコンテナ)は、通常のフロー行プロセスを実行しますか?このように簡単にできるようです。
klewis

13

あなたはCSSグリッドでそれを達成することができます、ただ使用してください repeat(autofit, minmax(width-of-the-element, max-content))

ul {
       display: grid;
       grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
       grid-gap: 16px;
       justify-content: center;
       padding: initial;
}

li {
    list-style-type: none;
    border: 1px solid gray;
    padding: 5px;
    width: 210px;
}
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
</ul>

http://jsfiddle.net/rwa20jkh/


面白い。しかし、右側のギャップをなくしたり、グリッドを中央に配置したりすることはできません

2
@ Red1つ間違っていました。に変更justify-items: centerしましたjustify-content:centerが、今では完全に中央に配置されています。
Joe 8220年

中の210px部分がわかりませんminmax。どうすれば同じことをできますが、人為的な制限はあり210pxませんか?フレックスボックスにはそのような制限はありません。フレックスボックスとまったく同じ結果が必要ですが、コンテンツ領域はソリューションのように中央に配置する必要があります。
AndreyMikhaylov-lolmaus20年

1
こんにちは@ AndreyMikhaylov-lolmaus、このメソッドは、すべての要素に固定幅を設定する場合に機能します。質問では、それはとして表現されwidth:200px、私の例では、私が設定したようにwidth:210px、それもminmaxパートに追加する必要があります
Joe82Jun

@ Joe82明確にしてくれてありがとう!🙏任意の幅の要素で機能させる方法を知っていますか?
AndreyMikhaylov-lolmaus20年

0

@michaelが示唆したように、これは現在のフレックスボックスの制限です。ただし、引き続きflexandを使用する場合はjustify-content: center;、ダミーli要素を追加してmargin-left。を割り当てることでこれを回避できます。

    const handleResize = () => {
        const item_box = document.getElementById('parentId')
        const list_length  = item_box.clientWidth
        const product_card_length = 200 // length of your child element
        const item_in_a_row = Math.round(list_length/product_card_length)
        const to_be_added = item_in_a_row - parseInt(listObject.length % item_in_a_row) // listObject is the total number items
        const left_to_set = (to_be_added - 1 ) * product_card_length // -1 : dummy item has width set, so exclude it when calculating the left margin 
        const dummy_product = document.querySelectorAll('.product-card.dummy')[0]
        dummy_product.style.marginLeft = `${left_to_set}px`
    }
    handleResize() // Call it first time component mount
    window.addEventListener("resize", handleResize); 

このフィドル(サイズを変更して参照)またはビデオを参照してください


0

余白のある目的のスタイルを取得する1つの方法は、次のことを行うことです。

#container {
    display: flex;
    justify-content: center;
}

#innercontainer {
    display: flex;
    flex: 0.9; -> add desired % of margin
    justify-content: flex-start;
}

0

他の要素と同じクラス(例では展示目的で削除)で高さを0に設定して、非表示の要素を配置できます。これにより、アイテムをグリッドの最初に位置合わせすることができます。

<div class="table-container">
  <div class="table-content">
    <p class="table-title">Table 1</p>
    <p class="mesa-price">$ 20</p>
  </div>
  
  <!-- Make stuff justified start -->
  <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
  <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
  <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
  <div class="table-content" style="opacity: 0; cursor: default; height: 0; margin-bottom: 0;"></div>
</div>

結果

ここに画像の説明を入力してください


0

フレックス内のコンテンツを中央に配置しようとしたときに、同様の問題に直面していました。私はたくさんのトリックと修正を試みましたが、ばかげたエラーのためにうまくいきませんでした。

これらの回答を読んでも問題を回避できない場合は、ばかげた間違いがないかチェックアウトしてみてください。私の場合、スペーサーとして追加spanするflex-growセット付きでした1


-1

React Nativeでコーディングしているときに、この問題が発生しました。FlexBoxを使用して使用できるエレガントなソリューションがあります。私の特定の状況では、alignItemsを使用して、3つのフレックスボックス(フレックス:2)を別のフレックスボックスの中央に配置しようとしていました。私が思いついた解決策は、それぞれFlex:1の2つの空のを使用することでした。

<View style={{alignItems: 'center', flexWrap: 'wrap', flexDirection: 'row'}}>
  <View style={{flex: 1}} />
    // Content here
  <View style={{flex: 1}} />
</View>

Web / CSSに変換するのに十分簡単です。


あなたはその質問を誤解しました。OPは、3つのアイテムを中央に配置する方法を尋ねません。すべてのアイテムがグループとして中央に配置されているときにアイテムを2行目に左揃えにする方法を尋ねます。そのため、ソリューションは機能しません。
エイソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.