web-dev-qa-db-ja.com

サイドアイテムの幅が異なる場合、中央のアイテムを中央に配置する

enter image description here

次のレイアウトを想像してください。ここで、ドットはボックス間のスペースを表します。

[Left box]......[Center box]......[Right box]

右側のボックスを削除すると、次のように中央のボックスが中央にあるようになります。

[Left box]......[Center box].................

左のボックスを削除する場合も同様です。

................[Center box].................

これで、中央のボックス内のコンテンツが長くなると、中央に配置されたまま、必要なだけ使用可能なスペースを占有します。左右のボックスは縮小することはないため、スペースがなくなると、overflow:hiddentext-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;
}
119
Mark

左右のボックスがまったく同じサイズである場合、希望する効果が得られます。ただし、2つのうちの1つが異なるサイズである場合、センタリングされたボックスはもはや真にセンタリングされません。私を助けることができる人はいますか?

兄弟の幅に関係なく、flexboxを使用して中央のアイテムを中央に配置する方法を次に示します。

主な機能:

  • 純粋なCSS
  • 絶対配置なし
  • jS/jQueryなし

ネストされたフレックスコンテナと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>&#8593;<br>true center</p>

仕組みは次のとおりです。

  • 最上位のdiv(.container)はflexコンテナです。
  • 各子div(.box)は現在、フレックスアイテムです。
  • .boxアイテムには、コンテナスペースを均等に分配するためにflex: 1が与えられます( (詳細 )。
  • これで、アイテムは行のすべてのスペースを消費し、同じ幅になります。
  • 各アイテムを(入れ子になった)フレックスコンテナにして、justify-content: centerを追加します。
  • 現在、各span要素は中央に配置されたフレックスアイテムです。
  • Flex autoマージンを使用して、外側のspansを左右にシフトします。

justify-contentを無視して、autoのマージンのみを使用することもできます。

しかし、autoマージンは常に優先されるため、justify-contentはここで機能します。

8.1。auto margins との整列

justify-contentおよびalign-selfを介した整列の前に、正の空き領域はその次元の自動マージンに分配されます。

90
Michael_B
  1. コンテナで3つのflexアイテムを使用します
  2. flex: 1を最初と最後に設定します。これにより、真ん中の空きスペースに合わせて均等に成長します。
  3. したがって、中央のものは中央に配置される傾向があります。
  4. ただし、最初または最後のアイテムのコンテンツが広い場合、新しいmin-width: auto初期値により、そのフレックスアイテムも大きくなります。

    注Chromeは、これを適切に実装していないようです。ただし、min-width-webkit-max-contentまたは-webkit-min-contentに設定できますが、これも機能します。

  5. その場合にのみ、中央の要素が中央から押し出されます。

.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>
24
Oriol

次のようにこれを行うことができます:

.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>
6
Michael Morton

デフォルトで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

4
Johan