フレックスボックス要素を中央揃えおよび右揃え


147

私が持っていると思いますA Bし、C真ん中に整列します。

どうすれDば完全に右に行くことができますか?

前:

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

後:

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

ul {
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  /* magic to throw to the right*/
}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>

https://jsfiddle.net/z44p7bsx/

回答:


214

以下は、このレイアウトを実現するための5つのオプションです。

  • CSSポジショニング
  • 非表示のDOM要素を持つFlexbox
  • 非表示の疑似要素を持つフレックスボックス
  • フレックスボックス flex: 1
  • CSSグリッドレイアウト

方法#1:CSS配置プロパティ

position: relativeフレックスコンテナーに適用します。

position: absolute項目Dに適用します。

これで、このアイテムはフレックスコンテナー内に完全に配置されます。

より具体的には、アイテムDはドキュメントフローから削除されますが、最も近くに配置されている祖先の境界内にとどまります。

CSSオフセットプロパティtopを使用して、rightこの要素を適切な位置に移動します。

この方法の注意点の1つは、一部のブラウザーでは、絶対位置のフレックス項目を通常のフローから完全に削除できない場合があることです。これにより、非標準の予期しない方法で配置が変更されます。詳細:絶対配置されたフレックスアイテムがIE11の通常のフローから削除されない


方法#2:Flexの自動マージンと非表示のFlexアイテム(DOM要素)

autoマージンと新しい非表示のフレックスアイテムの組み合わせにより、レイアウトを実現できます。

新しいflexアイテムはアイテムDと同じで、反対側の端(左端)に配置されます。

より具体的には、フレックスアラインメントは空き領域の分布に基づいているため、新しいアイテムは、中央の3つのボックスを水平方向に中央に保つために必要なバランスです。新しいアイテムは既存のDアイテムと同じ幅でなければなりません。そうしないと、中央のボックスが正確に中央に配置されません。

新しいアイテムはでビューから削除されますvisibility: hidden

要するに:

  • D要素の複製を作成します。
  • リストの最初に配置します。
  • フレックス使用auto維持するマージンをABそしてC両方に、センタリングD要素は両端から等しくバランスを作成します。
  • visibility: hidden複製に適用D


方法#3:Flexの自動マージンと非表示のFlexアイテム(疑似要素)

この方法は#2に似ていますが、意味的によりクリーンであり、幅Dがわかっている必要があります。

  • と同じ幅の疑似要素を作成しますD
  • でコンテナの先頭に配置し::beforeます。
  • フレックス使用auto維持するマージンAB及びC疑似として、完全に中心D要素は両端から等しくバランスを作成します。


方法#4:flex: 1左と右のアイテムに追加する

上記の方法#2または#3から始めて、均等なバランスを維持するために左右のアイテムの幅が等しいことを心配する代わりに、それぞれに1つずつ指定しflex: 1ます。これにより、両方が使用可能なスペースを強制的に消費するため、中央のアイテムが中央に配置されます。

次にdisplay: flex、個々のアイテムに追加して、それらのコンテンツを揃えることができます。

このメソッドをで使用する場合のmin-height注意現在Chrome、Firefox、Edge、およびおそらく他のブラウザーでは、省略ルールflex: 1はこれに分類されます:

  • flex-grow: 1
  • flex-shrink: 1
  • flex-basis: 0%

そのパーセンテージ単位(%)がオンになっているflex-basisと、このメソッドmin-heightがコンテナーで使用されている場合にこのメソッドが壊れます。これは、原則として、子のパーセントの高さheightには親の明示的なプロパティ設定が必要であるためです。

これは1998年に遡る古いCSSルール(CSSレベル2)で、多くのブラウザである程度有効です。詳細については、ここここを参照ください

これは、user2651804のコメントに投稿された問題の図です。

解決策は、パーセント単位を使用しないことです。試してみるpxか、まったく何もしないでください(これは、主要なブラウザの少なくとも一部が何らかの理由でパーセント単位を追加しているという事実にもかかわらず、仕様で実際に推奨されていることです)。


方法#5:CSSグリッドレイアウト

これは最もクリーンで効率的な方法かもしれません。絶対配置、偽の要素、その他のハッカーの必要はありません。

複数の列を持つグリッドを作成するだけです。次に、アイテムを中央と最後の列に配置します。基本的に、最初の列は空のままにしておきます。

ul {
  display: grid;
  grid-template-columns: 1fr repeat(3, auto) 1fr;
  grid-column-gap: 5px;
  justify-items: center;
}

li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }

/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p  { text-align: center; }
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
<p><span>| true center |</span></p>


1
説明ありがとうございます。小さなビューポートのためにコンテンツが中央に配置されている/中央に配置されていないことが出力から実際には明らかではないため、新しく追加されたコードスニペットは、サンプルテキストを短くすることでメリットがあると思います。私だけ?
user2651804 2018年

「新しいアイテムは、既存のDアイテムと同じ幅でなければなりません。そうしないと、中央のボックスが正確に中央に配置されません。」-それは同じ幅でなければならないことを吸うが、CSSグリッドの神に感謝します:)
Vucko

グリッド技術を使用して、アイテムが死んだセンターにないのですが、ロゴ要素を死んだセンターにする方法はありますか?imgur.com/a/SVg9xsj
J86

グリッドソリューションは魅力的なように機能し、最もクリーンですが、グリッドソリューションに精通していません。私が持っている1つの質問は、中央の列に3つすべてに等しくないより多くのスペースを与える方法ですか?
Saba Ahang

5

最も簡単な方法

.box{
  display:flex;
  justify-content:center;
}
.item1{
   flex:1;
   display: flex;
   justify-content: center;
   transform: translateX(10px);/*D element Width[if needed]*/
}
 <div class="box">
   <div class="item1">
      <div>A</div>
      <div>B</div>
      <div>C</div>
   </div>
   <div class="item2">D</div>
 </div>


2

整列させる場合は、空のスパンを接続して、3つの子スパンをそれらに分割するだけです。


2
ステートメントをバックアップする短いデモを提供できますか?
クレウィス

2

最も簡単な解決策は、コンテンツセンターを親コンテナーに揃え、最初と最後の子要素にmargin-left autoを与えることです。

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


.a,.d {
  margin-left:auto;
}
<ul>
  <li class="a">A</li>
  <li>B</li>
  <li>C</li>
  <li class="d">D</li>
</ul>


1

このdisplay:gridアプローチを使用すると、すべてのul子を同じセルに配置して、次のように設定できjustify-selfます。

ul {
  display: grid;
}

ul > * {
  grid-column-start: 1;
  grid-row-start: 1;
  justify-self:center;
}

ul > *:last-child {
  justify-self: right;
}

/* Make Fancy */
li {
  display:inline-block;
  margin: 1px;
  padding: 5px;
  background: #bbb;
}
<ul>
  <span>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  </span>
  <li>D</li>
</ul>


0

非常に明確な質問。数時間掘り下げて答えを投稿せざるを得ませんでした。テーブル、テーブルセル、絶対位置、変換を使用してこれを解決できましたが、フレックスボックスを使用して実行する必要がありました:)

.parent {
  display: flex;
  justify-content: flex-end;
}

.center {
  margin: auto;
}

http://codepen.io/rgfx/pen/BLorgd


8
スペース全体ではなく残りのスペースのみを考慮に入れるため、これは真ん中のアイテムを真に中央に配置しません。codepen.io/anon/pen/QKGrRk
Michael Benjamin

@Michael_B、あなたの権利はそれに気づかなかった、私の悪い。。戻る絶対位置を使用する:(たぶん、あなたの高い担当者のお手伝いをしようとしている今下げるとしても、私は希望の恩恵は、これは良いのために解決し得る設定する必要がありますが、私は非常に低い担当者を持っている。
rgfx

賞金でフレックスボックスモデルに新しい動作を追加するつもりはありません。Michael_Bによって、与えられた答えは今日と同じくらい良いです。
エイソン2017年

0

Michael_B答えを拡張しました

.center-flex__2-of-3 > :nth-child(1), .center-flex__2-of-3 > :nth-child(3) {
  flex: 1;
}
.center-flex__2-of-3 > :nth-child(1) {
  justify-content: flex-start;
}
.center-flex__2-of-3 > :nth-child(3) {
  justify-content: flex-end;
}
.center-flex__1-of-2 > :nth-child(1) {
  margin: auto;
}
.center-flex__1-of-2 > :nth-child(2) {
  flex: 1;
  justify-content: flex-end;
}
.center-flex__2-of-2 > :nth-child(1) {
  flex: 1;
  justify-content: flex-start;
}
.center-flex__2-of-2 > :nth-child(2) {
  margin: auto;
}
.center-flex__1-of-2:before, .center-flex__1-of-1:before {
  content: '';
  flex: 1;
}
.center-flex__1-of-1:after, .center-flex__2-of-2:after {
  content: '';
  flex: 1;
}

[class*=center-flex] {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  border: 10px solid rgba(0, 0, 0, 0.1);
}
[class*=center-flex] > * {
  display: flex;
}
li {
  padding: 3px 5px;
}
2 of 3
<ul class="center-flex__2-of-3">
  <span>
    <li>Accusamus</li>
    <li>Porro</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
1 of 2
<ul class="akex center-flex__1-of-2">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
</ul>

<br><br>
2 of 2
<ul class="akex center-flex__2-of-2">
  <span>
    <li>Porro</li>
    <li>Culpa</li>
    <li>Sit</li>
  </span>
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

<br><br>
1 of 1
<ul class="center-flex__1-of-1">
  <span>
    <li>Lorem</li>
    <li>Dolor</li>
  </span>
</ul>

ここでは、SASSをコードペンとして使用します


0

@Michal Benjaminのソリューションの方法5のCSSグリッドレイアウトに触発されました。Tailwindを使用しているため、現在のところ、デフォルトではすべてのグリッドオプションにアクセスできません。これはうまくいくようです:

ul {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
li:nth-child(1) { justify-content: flex-start; } // OR: margin-right: auto
li:nth-child(3) { justify-content: flex-end; } // OR: margin-left:auto
li: {align-self: center;}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

PS:このようにフレックスとグリッドを混同することが良いアイデアかどうかはわかりません!


1
グリッドとフレックスを混在させていない場合、justifty-contentはCSSグリッドプロパティとフレックスボックスプロパティです(align-selfと同じ)
Temani Afif

-1

グリッドテンプレート領域を使用して、偽の要素なしでそれを実行できるため、受け入れられた回答は少し変更できます

grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr

-1
ul { 
  padding: 0; 
  margin: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
}
li {
  display: flex;
  margin: 1px;
  padding: 5px;
  background: #aaa;
}
li:last-child {
  background: #ddd;
  position:absolute;
  right:10px;

}
<ul>
  <li>A</li>
  <li>B</li>
  <li>C</li>
  <li>D</li>
</ul>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.