it-swarm.com.de

Der Flex-Artikel, der den Container überläuft, kann nicht zum oberen Bildlauf verschoben werden

Beim Versuch, mithilfe von Flexbox einen nützlichen Modal zu erstellen, habe ich ein Problem gefunden, das anscheinend ein Problem mit dem Browser darstellt, und frage mich, ob es ein bekanntes Problem oder eine Problemumgehung gibt - oder Ideen, wie das Problem gelöst werden kann.

Was ich zu lösen versuche, hat zwei Aspekte. Zuerst wird das modale Fenster vertikal zentriert, was wie erwartet funktioniert. Die zweite Möglichkeit ist, das modale Fenster nach außen zu scrollen, um das gesamte modale Fenster zu scrollen, nicht den Inhalt (dh Sie können Dropdowns und andere Elemente der Benutzeroberfläche haben, die sich außerhalb der Grenzen des modalen Bereichs befinden.) wie eine benutzerdefinierte Datumsauswahl usw.)

Wenn Sie die vertikale Zentrierung mit Bildlaufleisten kombinieren, kann auf die Oberseite des Modals möglicherweise nicht mehr zugegriffen werden, wenn er überläuft. Im obigen Beispiel können Sie die Größe ändern, um den Überlauf zu erzwingen. Dadurch können Sie zum unteren Rand des Modals scrollen, jedoch nicht zum oberen Rand (erster Absatz wird abgeschnitten).

Hier ist der Link zum Beispielcode (stark vereinfacht)

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
}

Dies bewirkt (aktuelle) Firefox, Safari, Chrome und Opera. Interessanterweise verhält es sich korrekt im IE10, wenn Sie im IE10-Vender das Präfix css angeben .

Irgendwelche Ideen wären gut. Links zu bekannten Problemen oder eine Begründung für dieses Verhalten wäre ebenfalls hilfreich.

155
jejacks0n

Das Problem

Flexbox macht das Zentrieren sehr einfach.

Durch einfaches Anwenden von align-items: center und justify-content: center auf den Flex-Container werden Ihre Flex-Artikel vertikal und horizontal zentriert.

Es gibt jedoch ein Problem bei dieser Methode, wenn der Flexartikel größer als der Flexbehälter ist.

Wie in der Frage erwähnt, ist der Deckel unzugänglich, wenn der Flexartikel den Behälter überläuft.

 enter image description here

Bei horizontalem Überlauf kann auf den linken Abschnitt (oder den rechten Abschnitt in RTL-Sprachen) nicht zugegriffen werden.

Hier ein Beispiel mit einem LTR-Container mit justify-content: center und drei Flex-Elementen:

 enter image description here

Eine Erläuterung dieses Verhaltens finden Sie am Ende dieser Antwort.


Lösung Nr. 1

Um dieses Problem zu beheben, verwenden Sie flexbox automatische Ränder anstelle von justify-content.

Mit auto-Rändern kann ein überlaufendes Flex-Element vertikal und horizontal zentriert werden, ohne dass der Zugriff auf Teile davon verloren geht.

Also anstelle dieses Codes auf dem Flex-Container:

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

Verwenden Sie diesen Code für den Flex-Artikel:

.flex-item {
    margin: auto;
}

 enter image description here

Überarbeitete Demo


Lösung Nr. 2 (in den meisten Browsern noch nicht implementiert)

Fügen Sie der Keyword-Ausrichtungsregel den Wert safe hinzu:

justify-content: safe center

oder

align-self: safe center

Aus der CSS Box Alignment Module Spezifikation :

4.4. Überlaufausrichtung: Die Schlüsselwörter safe und unsafe und Scroll-Sicherheit Grenzen

Wenn der [Flexartikel] größer als der [Flexcontainer] ist, wird Überlauf. Wenn einige Ausrichtungsmodi in dieser Situation berücksichtigt werden, kann Datenverlust verursachen: Zum Beispiel, wenn der Inhalt einer Seitenleiste .__ ist. zentriert, wenn sie überlaufen, schicken sie möglicherweise einen Teil ihrer Boxen an Startbereich des Ansichtsfensters, zu dem kein Bildlauf möglich ist.

Um diese Situation zu steuern, kann der Modus Überlaufausrichtung der Modus .__ sein. explizit angegeben. Die Unsafe-Ausrichtung berücksichtigt die angegebene Ausrichtungsmodus in Überlaufsituationen, auch wenn dies zu Datenverlust führt, Während safe Ausrichtung den Ausrichtungsmodus im Überlauf ändert Situationen, in denen versucht wird, Datenverlust zu vermeiden.

Das Standardverhalten besteht darin, das Ausrichtungssubjekt innerhalb von .__ zu enthalten. scrollbarer Bereich, zum Zeitpunkt des Schreibens ist dieses Sicherheitsmerkmal jedoch noch nicht implementiert.

safe

Wenn die Größe des [Flex-Elements] den [Flex-Container] überläuft, wird der [flex item] wird stattdessen so ausgerichtet, als wäre der Ausrichtungsmodus [flex-start]. 

unsafe

Unabhängig von den relativen Größen von [flex item] und [flex Container] wird der angegebene Ausrichtungswert berücksichtigt.

Hinweis: Das Box-Alignment-Modul ist nicht nur für Flex-Modelle, sondern für mehrere Box-Layout-Modelle geeignet. In den oben angegebenen Ausschnitten für die Spezifikation stehen die Begriffe in Klammern eigentlich für "Ausrichtungsobjekt", "Ausrichtungscontainer" und "start" Flex-spezifische Begriffe verwendet, um den Fokus auf dieses spezielle Problem zu halten.


Erklärung für die Scrolleinschränkung von MDN:

Flex-Element Überlegungen

Die Ausrichtungseigenschaften von Flexbox führen im Gegensatz zu anderen .__ zu einer "echten" Zentrierung. Zentriermethoden in CSS. Dies bedeutet, dass die Flex-Elemente bleiben zentriert, auch wenn der Flexbehälter überläuft.

Dies kann jedoch manchmal problematisch sein, wenn sie an der .__ vorbei überlaufen. oberer Rand der Seite oder der linke Rand [...] als Sie können nicht zu diesem Bereich scrollen, auch wenn dort Inhalte vorhanden sind!

In einer zukünftigen Version werden die Ausrichtungseigenschaften um .__ erweitert. eine "sichere" Option.

Wenn dies ein Problem ist, können Sie stattdessen Ränder verwenden, um .__ zu erzielen. zentrieren, da sie auf "sichere" Weise reagieren und die Zentrierung aufhören, wenn Sie überlaufen. 

Anstelle der align--Eigenschaften setzen Sie einfach auto-Ränder auf die Flex-Elemente, die Sie zentrieren möchten.

Setzen Sie anstelle der justify--Eigenschaften die äußeren Randbereiche Kanten der ersten und letzten Flex-Artikel im Flex-Container.

Die auto-Ränder "biegen" und nehmen den verbleibenden Raum .__ an. Zentrieren der Flex-Elemente, wenn noch Platz übrig ist, und Wechseln von zur normalen Ausrichtung, wenn nicht.

Wenn Sie jedoch versuchen, justify-content durch .__ zu ersetzen. Margin-basierte Zentrierung in einer mehrzeiligen Flexbox, Sie sind wahrscheinlich nicht in Glück, da Sie die Ränder auf den ersten und letzten Flex-Artikel setzen müssen in jeder Zeile. Es sei denn, Sie können im Voraus vorhersagen, welche Elemente Wenn Sie in einer Zeile enden, können Sie die randbasierte Zentrierung in .__ nicht zuverlässig verwenden. die Hauptachse, um die justify-content-Eigenschaft zu ersetzen.

291
Michael_B

Nun, so wie es das Gesetz von Murphy vorsieht, ergab die Lektüre, die ich nach der Veröffentlichung dieser Frage machte, einige Ergebnisse - nicht vollständig gelöst, aber dennoch nützlich.

Ich habe vor dem Posten etwas mit Min-Height herumgespielt, wusste aber nicht, dass die Größenbeschränkungen, die für die Spezifikation recht neu sind, inhärent sind.

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

Durch Hinzufügen eines min-height: min-content zum Flexbox-Bereich wird das Problem in Chrome behoben. Außerdem werden mit Opera-Präfixen Opera und Safari behoben, obwohl Firefox weiterhin nicht gelöst ist.

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

Suchen Sie immer noch nach Ideen zu Firefox und anderen möglichen Lösungen.

18
jejacks0n

Ich habe es mit nur 3 Containern geschafft. Der Trick besteht darin, den Flexbox-Container von dem Container zu trennen, der den Bildlauf steuert. Zum Schluss legen Sie alles in einen Root-Container, um alles zu zentrieren. Hier sind die wesentlichen Stile, um den Effekt zu erzeugen:

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>

Ich habe hier eine Demo erstellt: https://jsfiddle.net/r5jxtgba/14/

12
colinbr96

Ich glaube, ich habe eine Lösung gefunden. Es funktioniert mit viel Text und ein wenig Text . Sie müssen nicht die Breite von irgendetwas angeben, und sollte in IE8 funktionieren.

.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

Laut MDN kann der safe-Wert jetzt Eigenschaften wie align-items und justify-content zur Verfügung gestellt werden. Es wird wie folgt beschrieben:

Wenn die Größe des Elements den Ausrichtungscontainer überläuft, wird das Element stattdessen so ausgerichtet, als wäre der Ausrichtungsmodus start.

Es kann also wie folgt verwendet werden.

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

Es ist jedoch unklar, wie viel Unterstützung der Browser hat, ich konnte keine Beispiele für seine Verwendung finden und hatte selbst Probleme damit. Erwähnen Sie es hier, um mehr Aufmerksamkeit auf sich zu ziehen.

1
Chris Talman

Ich habe es auch geschafft, zusätzliche Container zu verwenden

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;
}

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

Ändern Sie .content Breite/Höhe und sehen Sie

0
Nadeesh Peiris

2 Container Flex Methode mit Table Fallback IE8-9 getestet, flex funktioniert in IE10,11. Bearbeiten: Bearbeitet, um vertikale Zentrierung bei minimalem Inhalt zu gewährleisten. Unterstützung für ältere Versionen wurde hinzugefügt.

Das Problem rührt von der Höhe her, die von der Größe des Ansichtsfensters geerbt wird, wodurch Kinder überlaufen, wie Michael antwortete. https://stackoverflow.com/a/33455342/3500688

etwas einfacher und verwende flex, um das Layout im Popup-Container (Inhalt) beizubehalten:

#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