中央に揃えて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>
ベストアンサー1
このレイアウトを実現するための 5 つのオプションを以下に示します。
- CSS ポジショニング
- 目に見えないDOM要素を持つFlexbox
- 目に見えない疑似要素を備えた Flexbox
- フレックスボックス
flex: 1
- CSS グリッドレイアウト
方法 1: CSS 配置プロパティ
position: relative
フレックスコンテナに適用します。
position: absolute
項目Dに適用します。
これで、このアイテムはフレックス コンテナー内に絶対位置で配置されます。
具体的には、項目Dは文書フローから削除されますが、最も近い位置にある祖先。
この要素を所定の位置に移動するにはtop
、CSS オフセット プロパティを使用します。right
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
この方法の注意点は、一部のブラウザでは絶対配置されたフレックス アイテムを通常のフローから完全に削除できない場合があることです。これにより、配置が非標準の予期しない方法で変更されます。詳細:絶対位置のフレックスアイテムはIE11の通常のフローから削除されません
方法 2: Flex 自動マージンと非表示の Flex アイテム (DOM 要素)
の組み合わせでauto
余白新しい非表示のフレックスアイテムを使用してレイアウトを実現できます。
新しいフレックス アイテムはアイテム D と同一で、反対側の端 (左端) に配置されます。
具体的には、フレックス配置は空きスペースの配分に基づいているため、新しい項目は、中央の 3 つのボックスを水平方向に中央に配置するために必要なカウンターバランスとなります。新しい項目は、既存の D 項目と同じ幅である必要があります。そうしないと、中央のボックスが正確に中央に配置されません。
新しいアイテムは でビューから削除されますvisibility: hidden
。
要するに:
- 要素の複製を作成します
D
。 - リストの先頭に配置します。
- フレックス
auto
マージンを使用してA
、、B
をC
中央に配置し、両方のD
要素が両端から均等にバランスをとるようにします。 visibility: hidden
重複に適用D
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
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;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li><!-- new; invisible spacer item -->
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
方法3: Flexの自動マージンと非表示のFlexアイテム(疑似要素)
この方法は #2 と似ていますが、意味的に明確であり、幅がD
わかっている必要があります。
- と同じ幅の疑似要素を作成します
D
。 - コンテナの先頭に配置します
::before
。 - フレックス
auto
マージンを使用してA
、、B
およびをC
完全に中央に配置し、疑似要素とD
要素が両端から均等なバランスになるようにします。
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
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;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
方法4:flex: 1
左と右のアイテムに追加する
上記の方法 2 または 3 から始めて、左右のアイテムが均等なバランスを保つために均等な幅を気にするのではなく、それぞれに を指定します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)は、多くのブラウザで依然として何らかの形で有効です。詳細については、ここそしてここ。
これはコメント欄に投稿された問題のイラストです。ユーザー2651804:
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
解決策は、パーセンテージ単位を使わないことです。試してみるpx
か、何もしないことです(これは仕様で実際に推奨されていることだただし、少なくとも一部の主要ブラウザでは、何らかの理由でパーセンテージ単位が追加されているにもかかわらずです。
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY
#flex-container > div:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
*/
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
方法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>