Chrome / Safariがフレックスの親の高さを100%満たしていない


235

特定の高さの垂直メニューが欲しいのですが。

各子は親の高さを埋め、テキストは中央揃えにする必要があります。

子の数はランダムなので、動的な値を使用する必要があります。

Div .containerにはランダムな数の子(.item)が含まれ、常に親の高さを満たす必要があります。それを実現するために、フレックスボックスを使用しました。

テキストを中央に揃えてリンクを作成するには、display: table-cellテクニックを使用しています。ただし、テーブルディスプレイを使用するには、高さを100%にする必要があります。

私の問題は.item-inner { height: 100% }、webkit(Chrome)で動作しないことです。

  1. この問題の修正はありますか?
  2. または、すべて.itemを中央に揃えた垂直のテキストで親の高さを満たすようにする別のテクニックはありますか?

ここの例jsFiddle、FirefoxとChromeで表示する必要があります

.container {
  height: 20em;
  display: flex;
  flex-direction: column;
  border: 5px solid black
}
.item {
  flex: 1;
  border-bottom: 1px solid white;
}
.item-inner {
  height: 100%;
  width: 100%;
  display: table;
}
a {
  background: orange;
  display: table-cell;
  vertical-align: middle;
}
<div class="container">
  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>

  <div class="item">
    <div class="item-inner">
      <a>Button</a>
    </div>
  </div>
</div>



3
これは特にOPには関係ありませんが、「サファリディスプレイの絶対的な高さ100%が機能しない」などの理由でここに上陸したグーグルには関係があるかもしれません。flexコンテナー内にこのような要素があり、それを指定して期待どおりに表示させる必要がtop:0ありleft:0ました。
AlexMA 2017年

1
@vsyncはまだ修正されていない。stackoverflow.com/questions/46226298/...
TylerHを

回答:


408

解決

ネストされたフレックスコンテナーを使用します。

高さのパーセンテージを取り除きます。テーブルプロパティを削除します。を取り除きvertical-alignます。絶対配置は避けてください。ずっとflexboxを使い続けるだけです。

display: flexフレックスアイテムに適用し(.item)、フレックスコンテナーにします。これは自動的にを設定しalign-items: stretch、子(.item-inner)に親の高さ全体を拡張するよう指示します。

重要:このメソッドを機能させるには、フレックスアイテムから指定した高さを削除してください。子に高さが指定されている場合(例height: 100%:)align-items: stretch、親からの高さは無視されます。以下のためにstretch仕事にデフォルト、子供の高さはに計算しなければならないauto (十分な説明)。

これを試してください(HTMLに変更はありません)。

jsFiddleデモ


説明

私の問題は.item-inner { height: 100% }、webkit(Chrome)で動作しないことです。

パーセンテージの高さを仕様の従来の実装に適合しない方法で使用しているため、機能しません。

10.5コンテンツの高さ:heightプロパティ

パーセンテージの
高さを指定します。パーセンテージは、生成されたボックスの包含ブロックの高さに対して計算されます。包含ブロックの高さが明示的に指定されておらず、この要素が絶対的に配置されていない場合、値はに計算されautoます。

auto
高さは他のプロパティの値に依存します。

つまり、高さのパーセンテージがインフローの子で機能するためには、親に設定された高さが必要です。

コードでは、トップレベルのコンテナーに高さが定義されています。 .container { height: 20em; }

第3レベルのコンテナーには、高さが定義されています。 .item-inner { height: 100%; }

しかし、それらの間に、第2レベルのコンテナは- .item- しない定義された高さを有しています。Webkitはそれをミッシングリンクと見なします。

.item-innerChromeに指示していheight: 100%ます:ください。Chromeは.item参照用に親()を探して応答します。何も表示されませんflex: 1そこにあるルールを無視します)。その結果、height: auto仕様に従って(コンテンツの高さ)が適用されます。

一方、Firefoxは、親のフレックス高さを子のパーセント高さの参照として受け入れます。IE11とEdgeもフレックス高さを受け入れます。

また、Chromeは(を含む数値は機能します(機能しません))と組み合わせて使用​​した場合flex-grow、適切な親参照として受け入れます。ただし、これを書いている時点では、このソリューションはSafariでは失敗します。flex-basisautoflex-basis: 0


4つのソリューション

1.すべての親要素の高さを指定します

信頼できるクロスブラウザーソリューションは、すべての親要素の高さを指定することです。これにより、Webkitベースのブラウザーが仕様の違反と見なすリンクの欠落を防ぎます。

min-heightmax-height受け入れられないことに注意してください。heightプロパティである必要があります。

詳細はこちら: CSS heightプロパティとパーセント値の操作

2. CSSの相対配置と絶対配置

position: relative親とposition: absolute子に適用します。

サイズと子供height: 100%width: 100%、またはオフセットプロパティを使用しますtop: 0right: 0bottom: 0left: 0

絶対配置では、パーセンテージの高さは親の高さを指定しなくても機能します。

3.不要なHTMLコンテナを削除します(推奨)

周りに2つのコンテナが必要buttonですか?.itemまたは.item-inner、あるいはその両方を削除しないのはなぜですか?けれどもbutton要素が時々フレックスコンテナとして失敗し、彼らはフレックスアイテムすることができます。またはのbutton子を作成し、不要なマークアップを削除することを検討してください。.container.item

次に例を示します。

4.ネストされたFlexコンテナ(推奨)

高さのパーセンテージを取り除きます。テーブルプロパティを削除します。を取り除きvertical-alignます。絶対配置は避けてください。ずっとflexboxを使い続けるだけです。

display: flexフレックスアイテムに適用し(.item)、フレックスコンテナーにします。これは自動的にを設定しalign-items: stretch、子(.item-inner)に親の高さ全体を拡張するよう指示します。

重要:このメソッドを機能させるには、フレックスアイテムから指定した高さを削除してください。子に高さが指定されている場合(例height: 100%:)align-items: stretch、親からの高さは無視されます。以下のためにstretch仕事にデフォルト、子供の高さはに計算しなければならないauto (十分な説明)。

これを試してください(HTMLに変更はありません)。

jsFiddle


3
height:autoを使用して問題を修正しました
Alfrex92

この素晴らしい投稿の説明リンクから取ったいくつかのコメント-「align-items:stretch」は、フレックスチャイルドをコンテナの交差軸を横切って拡張させます-つまり、フレックスコンテナをフレックス方向にする必要があります行として。
littlewhywhat

3
ネストされたフレックスコンテナーを使用するのが最も効果的であることを確認できます。フレックスボックスをメニューで一貫性なく使用しました。flex:1とdisplay:flexを使用する代わりに、親コンテナでflexを使用しました。場所によっては高さ:100%を使用しました。対応する定義を置き換えた後、すべてが期待どおりに機能しました。ヒントをありがとう@Michael_B!:)
flocbit

1
@ JamesHarrington、CSSは時間とともに成長し、複雑になっています ;-)
DerMike

それぞれの解決策は異なる答えである必要があります。この方法で特定のソリューションに投票するにはどうすればよいですか?
Jp_

14

解決策:.item-innerを削除しheight: 100%.itemを追加display: flexます

デモ:https : //codepen.io/tronghiep92/pen/NvzVoo


おかげで、これは私を助けました。flexの子供は自動的にコンテナの高さまでストレッチしますか?これがなぜ機能するのですか?
リースケニー2017

@ReeceKenney、はい、あなたの質問に。これは私の答えで説明されています。ソリューション#4を参照してください。
マイケルベンジャミン

10

コンテナーにflex属性を指定するとうまくいきました:

.container {
    flex: 0 0 auto;
}

これにより、高さが設定され、大きくなりません。


6

Mobile Safariの場合ブラウザの修正があります。iOSデバイス用に-webkit-boxを追加する必要があります。

display: flex;
display: -webkit-box;
flex-direction: column;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
align-items: stretch;

align-items: stretch;親要素にプロパティを使用している場合height : 100%は、子要素からを削除します。


2

iOS 8、9、10にも同様の問題があり、上記の情報では解決できませんでしたが、1日作業した結果、解決策を見つけました。誰にとっても機能しないことは確かですが、私の場合、アイテムは列に積み上げられ、コンテンツの高さであるはずの高さが0でした。CSSを行とラップに切り替えると、問題が修正されました。これは、単一のアイテムがあり、それらが積み重ねられている場合にのみ機能しますが、これを見つけるのに1日かかったので、修正を共有する必要があると思いました!

.wrapper {
    flex-direction: column; // <-- Remove this line
    flex-direction: row; // <-- replace it with
    flex-wrap: wrap; // <-- Add wrapping
}

.item {
    width: 100%;
}

0

同様のバグがありましたが、高さにはパーセントではなく固定数を使用しました。ボディ内のフレックスコンテナーでもありました(高さは指定されていません)。Safariでは、何らかの理由でフレックスコンテナーの高さが9pxであるように見えましたが、他のすべてのブラウザーでは、スタイルシートで指定された正しい100pxの高さが表示されました。

heightmin-heightプロパティの両方をCSSクラスに追加することで、なんとか機能させることができました。

以下は、Safari 13.0.4とChrome 79.0.3945.130の両方で動作しました。

.flex-container {
  display: flex;
  flex-direction: column;
  min-height: 100px;
  height: 100px;
}

お役に立てれば!

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