web-dev-qa-db-ja.com

コンテナをオーバーフローしているフレックスアイテムの一番上までスクロールできない

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

私が解決しようとしているものには、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 。

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

181
jejacks0n

問題

Flexboxを使用すると、センタリングが非常に簡単になります。

align-items: centerjustify-content: centerをflexコンテナに適用するだけで、flexアイテムは垂直方向と水平方向の中央に配置されます。

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

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

enter image description here

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

以下に、justify-content: centerと3つのflexアイテムを持つLTRコンテナの例を示します。

enter image description here

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


解決策#1

この問題を修正するには、justify-contentの代わりに flexbox auto margins を使用します。

autoname__マージンを使用すると、オーバーフローしているflexアイテムを、その一部にアクセスすることなく、垂直および水平方向に中央揃えできます。

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

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

フレックスアイテムで次のコードを使用します。

.flex-item {
    margin: auto;
}

enter image description here

改訂版デモ


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

次のように、safename__値をキーワードアライメントルールに追加します。

justify-content: safe center

または

align-self: safe center

CSS Box Alignment Module specification から:

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

[flex item]が[flex container]よりも大きい場合、オーバーフローします。いくつかの位置合わせモードは、この状況で尊重される場合、データの損失を引き起こす可能性があります:たとえば、サイドバーのコンテンツが中央にある場合、オーバーフローすると、ビューポートの開始エッジを超えてボックスの一部を送信し、スクロールできません。

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

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

safeNAME _

[flex item]のサイズが[flex container]を超える場合、代わりに[flex item]は、整列モードが[flex-start]であるかのように整列されます。

unsafeNAME _

[フレックスアイテム]と[フレックスコンテナ]の相対的なサイズに関係なく、指定されたアライメント値が尊重されます。

注:Box Alignment Moduleは、フレックスだけでなく、複数のボックスレイアウトモデルで使用できます。したがって、上記の仕様の抜粋では、括弧内の用語は実際には「アライメントサブジェクト」、「アライメントコンテナ」、および「startname__」と言います。この特定の問題に焦点を当て続けるために、フレックス固有の用語を使用しました。


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

Flexアイテムの考慮事項

Flexboxの配置プロパティは、CSSの他のセンタリング方法とは異なり、「真の」センタリングを行います。これは、フレックスコンテナーがオーバーフローした場合でも、フレックスアイテムが中央にとどまることを意味します。

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

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

今のところ、これが懸念される場合は、代わりにマージンを使用してセンタリングを実現できます。「安全な」方法で応答し、オーバーフローするとセンタリングを停止するからです。

align-プロパティを使用する代わりに、autoname__マージンを中央に配置するflexアイテムに配置します。

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

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

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

330
Michael_B

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

投稿する前に、min-heightを少し試してみましたが、仕様にかなり新しい組み込みのサイズ制限はありませんでした。

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

min-height: min-contentをflexbox領域に追加すると、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やその他の潜在的なソリューションに関するアイデアを探しています。

18
jejacks0n

私はたった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/

13
colinbr96

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

.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>
4
mpen

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

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

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

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

しかし、どのくらいのブラウザがサポートされているかは不明であり、その使用例は見当たらず、自分で問題を抱えています。ここに言及して、より注目を集めます。

1
Chris Talman

また、余分なコンテナを使用してそれを行うことができました

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
Nadeesh Peiris

2 IE8-9でテストされたテーブルフォールバックを使用したコンテナフレックスメソッド。IE10,11でフレックスが動作します。編集:最小限のコンテンツで垂直方向のセンタリングを確保するように編集され、レガシーサポートが追加されました。

この問題は、Michaelが答えたように、子供があふれる原因となるビューポートサイズから高さが継承されることに起因しています。 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>
0
Silverandrew