29

次のプロパティを持つフレックス コンテナー (青い四角) があります。

display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;

したがって、その子 (水色の正方形) は、以下に示すように配置されます。ただし、通常のフローから別の子 (緑色の四角形) を追加し、その親に対して相対的に配置したいと考えています。bottom: 20px;以下に示すように配置するには、理想的にはandのように記述しmargin: auto;ます。

ここに画像の説明を入力

z-index私は無駄に遊んでみました。これにどのようにアプローチすればよいですか?別の親要素を作成する必要がありますか?

4

3 に答える 3

57

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

  1. CSS ポジショニング
  2. 非表示の DOM 要素を持つ Flexbox
  3. 目に見えない疑似要素を持つフレックスボックス
  4. フレックスボックスflex: 1
  5. CSS グリッド レイアウト

方法 #1: CSS ポジショニング プロパティ

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

position: absolute緑のフレックス項目に適用します。

これで、緑色の正方形がフレックス コンテナー内に完全に配置されました。

より具体的には、緑色の四角形はドキュメント フローから削除されますが、最も近い位置にある祖先の境界内にとどまります。

CSS オフセット プロパティtopbottomleftおよびを使用してright、緑色の四角形を移動します。

flex-container {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  position: relative;
  border: 4px solid blue;
  height: 300px;
  width: 300px;
}
flex-container > flex-item:first-child {
  display: flex;
}
flex-container > flex-item:first-child > flex-item {
  border: 4px solid aqua;
  height: 50px;
  width: 50px;
  margin: 0 5px;
}
flex-container > flex-item:last-child {
  position: absolute;
  bottom: 40px;
  left: 50%;
  transform: translateX(-50%); /* fine tune horizontal centering */
  border: 4px solid chartreuse;
  height: 50px;
  width: 50px;
}
<flex-container>
    <flex-item><!-- also flex container -->
	    <flex-item></flex-item>
	    <flex-item></flex-item>
	    <flex-item></flex-item>
    </flex-item>
    <flex-item></flex-item>
</flex-container>

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


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

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

新しいフレックス アイテムは一番下のアイテムと同じで、反対側 (一番上) に配置されます。

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

新しい項目は でビューから削除されますvisibility: hidden

要するに:

  • 緑のボックスの複製を作成します。
  • リストの先頭に配置します。
  • フレックスautoマージンを使用して、青色のボックスを中央に配置し、両方の緑色のボックスが両端から均等にバランスを取るようにします。
  • visibility: hidden複製した緑色のボックスに適用します。

flex-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    border: 4px solid blue;
    height: 300px;
    width: 300px;
}
flex-container > flex-item:first-child {
    margin-top: auto;
    visibility: hidden;
}
flex-container > flex-item:nth-child(2) {
    margin-top: auto;
    display: flex;
}
flex-container > flex-item:last-child {
    margin-top: auto;
    margin-bottom: auto;
}
flex-container > flex-item:first-child,
flex-container > flex-item:last-child {
    border: 4px solid chartreuse;
    height: 50px;
    width: 50px;
}
flex-container > flex-item:nth-child(2) > flex-item {
    border: 4px solid aqua;
    height: 50px;
    width: 50px;
    margin: 0 5px;
}
<flex-container>
    <flex-item></flex-item>
    <flex-item><!-- also flex container -->
	    <flex-item></flex-item>
	    <flex-item></flex-item>
	    <flex-item></flex-item>
    </flex-item>
    <flex-item></flex-item>
</flex-container>


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

このメソッドは #2 と似ていますが、意味がより明確であり、緑色のボックスの高さがわかっている必要があります。

  • 既存の緑色のボックスと同じ高さの疑似要素を作成します。
  • でコンテナの先頭に配置し::beforeます。
  • フレックスautoマージンを使用して、青色のボックスを中央に配置し、緑色の疑似要素と DOM 要素を両端から均等に配置します。

flex-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    border: 4px solid blue;
    height: 300px;
    width: 300px;
}
flex-container::before {
  content: "";
  margin-top: auto;
  height: calc(50px + 8px);  /* height + borders */
  visibility: hidden;
}
flex-container > flex-item:first-child {
  margin-top: auto;
  display: flex;
}
flex-container > flex-item:last-child {
  margin-top: auto;
  margin-bottom: auto;
  border: 4px solid chartreuse;
  height: 50px;
  width: 50px;
}
flex-container > flex-item:first-child > flex-item {
  border: 4px solid aqua;
  height: 50px;
  width: 50px;
  margin: 0 5px;
}
<flex-container>
    <flex-item><!-- also flex container -->
        <flex-item></flex-item>
	    <flex-item></flex-item>
	    <flex-item></flex-item>
    </flex-item>
    <flex-item></flex-item>
</flex-container>


flex: 1方法 #4:上下のアイテムに追加する

上記の方法 2 または 3 から始めて、上部と下部のアイテムの高さを同じにしてバランスを保つのではなく、それぞれにflex: 1. これにより、両方が使用可能なスペースを消費するようになり、中央のアイテムが中央に配置されます。

display: flex次に、コンテンツを揃えるために一番下のアイテムに追加できます。


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

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

3 行のグリッドを作成するだけです。次に、2 行目と 3 行目の項目を中央揃えにします。最初の行は空のままにすることができます。

grid-container {
  display: grid;
  grid-template-rows: repeat(3, 1fr);
  align-items: center;
  justify-items: center;
  border: 4px solid blue;
  height: 300px;
  width: 300px;
}

grid-item:nth-child(2) {
  display: flex;
}

grid-item:nth-child(2)>flex-item {
  width: 50px;
  height: 50px;
  margin: 0 5px;
  border: 4px solid aqua;
}

grid-item:nth-child(3) {
  border: 4px solid chartreuse;
  height: 50px;
  width: 50px;
}
<grid-container>
  <grid-item></grid-item>
  <grid-item><!-- also flex container -->
    <flex-item></flex-item>
    <flex-item></flex-item>
    <flex-item></flex-item>
  </grid-item>
  <grid-item></grid-item>
</grid-container>

于 2016-03-24T01:11:17.547 に答える
4

コンテナとposition: relative緑の四角を position:absolute;

body {
  margin: 0;  
}

#container {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  width: 192px;
  height: 192px;
  border: 4px solid indigo;
  position: relative;
  background: lavender;
}

.blue {
  margin: 10px;
  width: 30px;
  height: 30px;
  outline: 4px solid skyblue;
  background: honeydew;
}

#green {
  position: absolute;
  width: 30px;
  height: 30px;
  left: 0;
  right: 0;
  margin: auto;
  bottom: 20px;
  outline: 4px solid yellowgreen;
  background: greenyellow;
}
<div id=container>
<div class=blue></div><div class=blue></div><div class=blue></div>
<div id=green></div>
</div>

于 2016-03-24T01:17:02.040 に答える
3

疑似を使用して最初の 3 つのコンテナを 1 行下に移動し、margin:auto最後のコンテナに a を適用できます

div {
  display:flex;
  flex-wrap:wrap;
  border:#0066FD solid;;
  width:200px;
  height:200px;
  justify-content:space-around;
  /* show me box center */
  background:linear-gradient(to top,rgba(0,0,0,0.2) 50%, transparent 50%),linear-gradient(to left,rgba(0,0,0,0.2) 50%, transparent 50%)
 
}

span, div:before {
  width:50px;
  height:50px;
  border:solid #01CDFF;
  margin:0 auto 0;
}
span:last-of-type , div:before{
  margin: 12px auto;
  border:solid  #01FE43;
}
div:before {
  content:'';
  width:100%;
  border:none;
}

span {
   /* show me box center */
  background:linear-gradient(45deg,rgba(0,0,0,0.1) 50%, transparent 50%),linear-gradient(-45deg,rgba(0,0,0,0.1) 50%, transparent 50%)
  }
<div>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
</div>

于 2016-03-24T01:22:16.527 に答える