コンテナーがオーバーフローしているフレックスアイテムの上部にスクロールできません


259

したがって、フレックスボックスを使用して便利なモーダルを作成しようとしたときに、ブラウザーの問題のように見えるものが見つかり、既知の修正または回避策があるかどうか、またはそれを解決する方法についての考えがあります。

私が解決しようとしていることには、2つの側面があります。最初に、モーダルウィンドウを垂直方向に中央揃えにします。これは期待どおりに機能します。2つ目は、モーダルウィンドウをスクロールすることです-外部的に、モーダルウィンドウ全体をスクロールしますが、その中のコンテンツはスクロールしません(これにより、ドロップダウンや、モーダルの境界外に拡張できるその他のUI要素を使用できます-カスタム日付ピッカーなど)

ただし、垂直方向のセンタリングとスクロールバーを組み合わせると、モーダルがオーバーフローし始めると、モーダルの上部にアクセスできなくなる可能性があります。上記の例では、オーバーフローを強制するようにサイズ変更できます。そうすることで、モーダルの一番下までスクロールできますが、一番上まではスクロールできません(最初の段落は切り取られます)。

これはサンプルコードへのリンクです(非常に簡略化されています)

https://jsfiddle.net/dh9k18k0/2/

.modal-container {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
  overflow-x: auto;
}
.modal-container .modal-window {
  display: -ms-flexbox;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  // Optional support to confirm scroll behavior makes sense in IE10
  //-ms-flex-direction: column;
  //-ms-flex-align: center;
  //-ms-flex-pack: center;
  height: 100%;
}
.modal-container .modal-window .modal-content {
  border: 1px solid #ccc;
  border-radius: 4px;
  background: #fff;
  width: 100%;
  max-width: 500px;
  padding: 10px
}

これは(現在の)Firefox、Safari、Chrome、Operaに影響します。IE10ベンダーの接頭辞cssでコメントすると、IE10で興味深い動作をします。IE11でのテストはまだしていませんが、動作はIE10と同じであると想定しています。 。

どんなアイデアでもいいでしょう。既知の問題へのリンク、またはこの動作の背後にある理由も役立ちます。

回答:


478

問題

Flexboxにより、センタリングが非常に簡単になります。

単純に適用することによって、align-items: centerおよびjustify-content: centerフレックスコンテナに、あなたのフレックス項目(複数可)垂直方向と水平方向中心になります。

ただし、フレックスアイテムがフレックスコンテナーよりも大きい場合、このメソッドには問題があります。

質問で述べたように、フレックスアイテムがコンテナーからオーバーフローすると、上部にアクセスできなくなります。

ここに画像の説明を入力してください

水平オーバーフローの場合、左側のセクション(またはRTL言語の右側のセクション)にアクセスできなくなります。

以下はjustify-content: center、3つのflexアイテムを持つLTRコンテナーの例です。

ここに画像の説明を入力してください

この動作の説明については、この回答の下部を参照してください。


ソリューション#1

この問題を修正するには、ではなくflexbox auto marginsを使用してくださいjustify-content

auto余白、あふれフレックス項目は、垂直方向と水平方向その一部へのアクセスを失うことなくセンタリングすることができます。

したがって、フレックスコンテナーでのこのコードの代わりに:

#flex-container {
    align-items: center;
    justify-content: center;
}

次のコードをflexアイテムで使用します。

.flex-item {
    margin: auto;
}

ここに画像の説明を入力してください

改訂されたデモ


解決策#2(ほとんどのブラウザーではまだ実装されていません)

次のように、safe値をキーワードの配置ルールに追加します。

justify-content: safe center

または

align-self: safe center

CSSボックス整合モジュール仕様

4.4。オーバーフローの配置:safeおよびunsafeキーワードとスクロールの安全制限

【フレックスアイテム】が【フレックスコンテナ】より大きい場合はオーバーフローします。一部の配置モードは、この状況で採用された場合、データの損失を引き起こす可能性があります。たとえば、サイドバーのコンテンツが中央に配置されている場合、オーバーフローすると、ボックスの一部がビューポートの開始エッジを超えて送信され、スクロールできません。 。

この状況を制御するために、オーバーフロー調整モードを明示的に指定できます。Unsafeアライメントは、データ損失を引き起こしたとしても、オーバーフロー状況で指定されたアライメントモードを尊重しますsafeが、アライメントは、データ損失を回避するためにオーバーフロー状況でアライメントモードを変更します。

デフォルトの動作では、スクロール可能領域内に配置サブジェクトが含まれますが、執筆時点では、この安全機能はまだ実装されていません。

safe

[フレックスアイテム]のサイズが[フレックスコンテナー]をオーバーフローする場合、[フレックスアイテム]は、配置モードが[ flex-start]であるかのように配置されます。

unsafe

[フレックスアイテム]と[フレックスコンテナー]の相対的なサイズに関係なく、指定された配置値が優先されます。

注:ボックス配置モジュールは、単なるフレックスではなく、複数のボックスレイアウトモデルで使用するためのものです。したがって、上記の仕様の抜粋では、括弧内の用語は、実際には「配置の対象」、「配置のコンテナ」、「start」を示しています。この特定の問題に焦点を合わせるために、フレックス固有の用語を使用しました。


MDNからのスクロール制限の説明:

フレックスアイテムの考慮事項

Flexboxの配置プロパティは、CSSの他のセンタリング方法とは異なり、「真の」センタリングを行います。つまり、フレックスコンテナーからオーバーフローしても、フレックスアイテムは中央に配置されたままになります。

ただし、コンテンツがそこにある場合でも、その領域にスクロールできないため、ページの上端または左端[...]を超えてオーバーフローすると、問題が発生することがあります。

将来のリリースでは、配置プロパティが拡張され、「安全な」オプションも追加される予定です。

今のところ、これが問題になる場合は、マージンを使用してセンタリングを行うことができます。マージンが「安全」に応答し、オーバーフローするとセンタリングが停止するためです。

align-プロパティを使用する代わりに、auto中央に配置するフレックスアイテムにマージンを設定するだけです。

justify-プロパティの代わりに、フレックスコンテナー内の最初と最後のフレックスアイテムの外側の端に自動マージンを配置します。

autoマージンは「フレックス」して残りのスペースを想定し、残りのスペースがある場合はフレックスアイテムを中央に配置し、ない場合は通常の配置に切り替えます。

ただし、justify-content複数行のフレックスボックスでマージンベースのセンタリングに置き換えようとすると、各行の最初と最後のフレックスアイテムにマージンを配置する必要があるため、おそらくうまくいかないでしょう。どの項目がどの行に配置されるかを事前に予測できない限り、justify-contentプロパティを置き換えるために主軸でマージンベースのセンタリングを確実に使用することはできません。


4
はい、それはより良いソリューションです。追加の貴重な洞察を提供していただきありがとうございます。
jejacks0n 2015年

1
IE11では動作しないことに注意してください。背景は切り取られます。
Daniel

2
@Daniel、私はIE11でコードをテストしました。アクセスできないものはありません。実際、質問で説明されている問題はIE11にも存在しません。IE11でのみ発生するテキストオーバーフローを参照している可能性があります。それは別の質問の別の問題です。
マイケルベンジャミン

11
IE11の問題を修正するalign-items: flex-startには:フレックスコンテナーに追加し、margin: autoフレックスアイテムを保持します。
Eugene Fidelin 2017

2
flex-direction:columnを使用している場合、これは機能しません。
Stefan

22

まあ、マーフィーの法則がそうであるように、この質問を投稿した後に私が読んだ結果はいくつかの結果をもたらしました-完全に解決されていませんが、それでもいくらか有用です。

投稿する前にmin-heightで少し遊んでみましたが、仕様にかなり新しい固有のサイズ制限がありませんでした。

http://caniuse.com/#feat=intrinsic-width

min-height: min-contentフレックスボックス領域にを追加すると、Chromeの問題は解決します。ベンダープレフィックスを使用すると、OperaとSafariも修正されますが、Firefoxは未解決のままです。

min-height: -moz-min-content; // not implemented
min-height: -webkit-min-content // works for opera and safari
min-height: min-content // works for chrome

Firefoxやその他の潜在的なソリューションに関するアイデアをまだ探しています。


私はそれがFirefoxで既に私のために動作することを言いたかっただけです。したがって、min-contentのソリューションは完璧でした。
pudgereyem

@pudgereyem彼らはそれを実装したと思います。この答えは両方の問題を解決しましたが、私のために働くのをmargin: autoやめる他の解決策flex-basis
Martin Dawson

確かに素晴らしいソリューションです。EdgeやIEは気にしないので、これは完璧に機能します!
Ohgodwhy

18

たった3つのコンテナでなんとかこれを実現できました。トリックは、スクロールを制御するコンテナーからflexboxコンテナーを分離することです。最後に、すべてをルートコンテナーに入れて、すべてを中央に配置します。効果を作成するために不可欠なスタイルは次のとおりです。

CSS:

.root {
  display: flex;
  justify-content: center;
  align-items: center;
}

.scroll-container {
  margin: auto;
  max-height: 100%;
  overflow: auto;
}

.flex-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

HTML:

<div class="root">
  <div class="scroll-container">
    <div class="flex-container">
      <p>Lorem ipsum dolor sit amet.</p>
    </div>
  </div>
</div>

ここでデモを作成しました:https : //jsfiddle.net/r5jxtgba/14/


スクロールコンテナーのヒントはthxです。*****スクロールコンテンツを修正するために2日以来検索しました!!!
artSx

覚えておいflex: 1 1 autoてくださいscroll-container。私はこれを癖にして問題を抱えていました。
AmirHossein

1
jsfiddleは、コンテナー内にさらにコンテンツを追加すると機能しないことを示しています。
bplittle

4

私は解決策を見つけたと思います。たくさんのテキスト少しのテキスト動作します。幅を指定する必要はなく、IE8で動作するはずです。

.wrap1 {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
  overflow-y: auto;
}
.wrap2 {
  display: table;
  width: 100%;
  height: 100%;
  text-align: center;
}
.wrap3 {
  vertical-align: middle;
  display: table-cell;
}
.wrap4 {
  margin: 10px;
}
.dialog {
  text-align: left;
  background-color: white;
  padding: 5px;
  border-radius: 3px;
  margin: auto;
  display: inline-block;
  box-shadow: 2px 2px 4px rgba(0, 0, 0, .5);
}
<div class="wrap1">
  <div class="wrap2">
    <div class="wrap3">
      <div class="wrap4">
        <div class="dialog">
          <p>Lorem ipsum dolor sit amet.</p>
        </div>
      </div>
    </div>
  </div>
</div>


これは、レガシーブラウザに最適なソリューションです。どうもありがとうございました!
Daniel

5
うわー、それはたくさんのラップです。
Nathan Arthur

1
うわー、これを達成するために何時間も費やしてきました。(他のすべてのメソッドは、アニメーションを追加するときにモバイルクロムで失敗します。これは失敗しません)ありがとうございます。
falsePockets 2018

1

MDNによると、safe値はalign-itemsおよびなどのプロパティに提供できるようになりましたjustify-content。次のように説明されています。

アイテムのサイズが配置コンテナーをオーバーフローする場合、アイテムは配置モードと同じように配置されますstart

したがって、次のように使用できます。

.rule
{
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: safe center;
}

しかし、それがどの程度のブラウザをサポートしているかは不明であり、その使用例を見つけることができず、私自身もいくつか問題を抱えています。注目を集めるためにここで言及します。


2018年6月7日、まだChromeでは実装されていません。
AmirHossein

(現在の)MDNページによると、現時点では「安全」と「安全でない」はFirefoxのみです(まあ、Safariとほとんどのモバイルブラウザはサポートが不明です-安全にプレイでき、サポートはないと仮定します)。
JaMiT

MDNはFirefoxのサポートを報告していますが、Firefoxでテストしたところ、動作していないようです。jsbin.com/pimoqof/1/edit?html,css,output
Oliver Joseph Ash

caniuseによると、2020年6月で、ほとんどのブラウザーではない
den232

0

また、追加のコンテナを使用してそれを行うことができました

HTML

<div class="modal-container">
  <div class="modal">
    <div class="content-container">
       <div class="content">
         <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
        </div>
      </div>
  </div>  
</div>

CSS

.modal-container {
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: black;
}

.modal {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #aaa;
  height: 80%;
  width: 90%;
}

.content-container {
  background-color: blue;
  max-height: 100%;
  overflow: auto;
  padding:0;
}

.content {
  display: flex;
  background-color: red;
  padding: 5px;
  width: 900px;
  height: 300px;
}

jsfiddleで> https://jsfiddle.net/Nash171/cpf4weq5/

.contentの幅/高さの値を変更して確認する


0

2コンテナFlexメソッドとテーブルフォールバックテスト済みIE8-9、FlexはIE10、11で動作します。編集:最小限のコンテンツ時に垂直方向の中央揃えを確実にするために編集され、レガシーサポートが追加されました。

問題は、マイケルが答えたように、高さがビューポートサイズから継承され、子供がオーバーフローすることに起因します。https://stackoverflow.com/a/33455342/3500688

よりシンプルなもので、flexを使用してポップアップコンテナー(コンテンツ)内のレイアウトを維持します。

#popup {
position: fixed;
top: 0;
left: 0;
right: 0;
min-height: 100vh;
background-color: rgba(0,0,0,.25);
margin: auto;
overflow: auto;
height: 100%;
bottom: 0;
display: flex;
align-items: flex-start;
box-sizing:border-box;
padding:2em 20px;
}
.container {
background-color: #fff;
margin: auto;
border: 1px solid #ccc;
border-radius: 4px;
background: #fff;
/* width: 100%; */
max-width: 500px;
padding: 10px;
    /* display: flex; */
    /* flex-wrap: wrap; */
}
		<!--[if lt IE 10]>
<style>
	  #popup {
			display: table;
			width:100%;
		}
		.iewrapper {
			display: table-cell;
			vertical-align: middle;
		}
	</style>
	<![endif]-->
<div id="popup">
	<!--[if lt IE 10]>
<div class="iewrapper">
<![endif]-->
    <div class="container">
        <p class="p3">Test</p>
    <p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
    <p class="p3">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
    </div>
	<!--[if lt IE 10]>
<div class="iewrapper">
<![endif]-->
</div>

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