次のレイアウトを想像してください。ここで、ドットはボックス間のスペースを表します。
[Left box]......[Center box]......[Right box]
右側のボックスを削除すると、次のように中央のボックスが中央にあるようになります。
[Left box]......[Center box].................
左のボックスを削除する場合も同様です。
................[Center box].................
これで、中央のボックス内のコンテンツが長くなると、中央に配置されたまま、必要なだけ使用可能なスペースを占有します。左右のボックスは縮小することはないため、スペースがなくなると、overflow:hidden
とtext-overflow: Ellipsis
が有効になり、コンテンツが中断されます。
[Left box][Center boxxxxxxxxxxxxx][Right box]
上記はすべて私の理想的な状況ですが、この効果を達成する方法はわかりません。私がそのようなフレックス構造を作成するとき:
.parent {
display : flex; // flex box
justify-content : space-between; // horizontal alignment
align-content : center; // vertical alignment
}
左右のボックスがまったく同じサイズの場合、目的の効果が得られます。ただし、2つのうちの1つが異なるサイズのものである場合、中央揃えボックスはもう真ん中にありません。
私を助けることができる人はいますか?
更新
justify-self
はいいでしょう、これは理想的です:
.leftBox {
justify-self : flex-start;
}
.rightBox {
justify-self : flex-end;
}
左右のボックスがまったく同じサイズである場合、希望する効果が得られます。ただし、2つのうちの1つが異なるサイズである場合、センタリングされたボックスはもはや真にセンタリングされません。私を助けることができる人はいますか?
兄弟の幅に関係なく、flexboxを使用して中央のアイテムを中央に配置する方法を次に示します。
主な機能:
ネストされたフレックスコンテナとauto
マージンを使用します。
.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box:first-child > span { margin-right: auto; }
.box:last-child > span { margin-left: auto; }
/* non-essential */
.box {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
p {
text-align: center;
margin: 5px 0 0 0;
}
<div class="container">
<div class="box"><span>short text</span></div>
<div class="box"><span>centered text</span></div>
<div class="box"><span>loooooooooooooooong text</span></div>
</div>
<p>↑<br>true center</p>
仕組みは次のとおりです。
.container
)はflexコンテナです。.box
)は現在、フレックスアイテムです。.box
アイテムには、コンテナスペースを均等に分配するためにflex: 1
が与えられます( (詳細 )。justify-content: center
を追加します。span
要素は中央に配置されたフレックスアイテムです。auto
マージンを使用して、外側のspan
sを左右にシフトします。justify-content
を無視して、auto
のマージンのみを使用することもできます。
しかし、auto
マージンは常に優先されるため、justify-content
はここで機能します。
8.1。
auto
margins との整列
justify-content
およびalign-self
を介した整列の前に、正の空き領域はその次元の自動マージンに分配されます。
flex: 1
を最初と最後に設定します。これにより、真ん中の空きスペースに合わせて均等に成長します。ただし、最初または最後のアイテムのコンテンツが広い場合、新しいmin-width: auto
初期値により、そのフレックスアイテムも大きくなります。
注Chromeは、これを適切に実装していないようです。ただし、min-width
を-webkit-max-content
または-webkit-min-content
に設定できますが、これも機能します。
その場合にのみ、中央の要素が中央から押し出されます。
.outer-wrapper {
display: flex;
}
.item {
background: Lime;
margin: 5px;
}
.left.inner-wrapper, .right.inner-wrapper {
flex: 1;
display: flex;
min-width: -webkit-min-content; /* Workaround to Chrome bug */
}
.right.inner-wrapper {
justify-content: flex-end;
}
.animate {
animation: anim 5s infinite alternate;
}
@keyframes anim {
from { min-width: 0 }
to { min-width: 100vw; }
}
<div class="outer-wrapper">
<div class="left inner-wrapper">
<div class="item animate">Left</div>
</div>
<div class="center inner-wrapper">
<div class="item">Center</div>
</div>
<div class="right inner-wrapper">
<div class="item">Right</div>
</div>
</div>
<!-- Analogous to above --> <div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item animate">Center</div></div><div class="right inner-wrapper"><div class="item">Right</div></div></div><div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item">Center</div></div><div class="right inner-wrapper"><div class="item animate">Right</div></div></div>
次のようにこれを行うことができます:
.bar {
display: flex;
background: #B0BEC5;
}
.l {
width: 50%;
flex-shrink: 1;
display: flex;
}
.l-content {
background: #9C27B0;
}
.m {
flex-shrink: 0;
}
.m-content {
text-align: center;
background: #2196F3;
}
.r {
width: 50%;
flex-shrink: 1;
display: flex;
flex-direction: row-reverse;
}
.r-content {
background: #E91E63;
}
<div class="bar">
<div class="l">
<div class="l-content">This is really long content. More content. So much content.</div>
</div>
<div class="m">
<div class="m-content">This will always be in the center.</div>
</div>
<div class="r">
<div class="r-content">This is short.</div>
</div>
</div>
デフォルトでflexboxを使用する代わりに、グリッドを使用すると、最上位の子の内部に追加のマークアップなしで2行のCSSで解決されます。
HTML:
<header class="header">
<div class="left">variable content</div>
<div class="middle">variable content</div>
<div class="right">variable content which happens to be very long</div>
</header>
CSS:
.header {
display: grid;
grid-template-columns: [first] 20% auto [last] 20%;
}
.middle {
/* use either */
margin: 0 auto;
/* or */
text-align: center;
}
Flexboxは優れていますが、すべての答えになるとは限りません。この場合、グリッドが明らかに最もクリーンなオプションです。
テストの喜びのためにコードペンを作成しました: https://codepen.io/anon/pen/mooQOV