Zentrieren Sie einen DIV ungleich mit CSS

23

Ich zentriere einen DIV mithilfe einer Flexbox in einem anderen DIV. Stellen Sie sich ein Dialogfenster vor, das bei Bedarf in der Mitte des Bildschirms angezeigt wird.

Es funktioniert gut, aber es würde viel besser aussehen, wenn der Platz über und unter dem Dialogfeld nicht genau gleich wäre, da 40% des verbleibenden Platzes über und 60% unter dem Dialogfeld liegen. Es wird schwierig, da die Höhe des Dialogfelds von der Textmenge abhängt.

Wenn die Browserhöhe beispielsweise 1000 Pixel und die Höhe des Dialogfensters 400 Pixel beträgt, soll der verbleibende vertikale Raum (600 Pixel) 240 Pixel über und 360 Pixel unter dem Dialogfeld liegen. Ich könnte es mit Javascript machen, aber ich bin gespannt, ob es mit CSS einen cleveren Weg gibt. Ich habe versucht, der #dialogBox DIV einen unteren Rand hinzuzufügen, aber das funktioniert nicht, wenn sich die Dialoghöhe der Browserhöhe nähert.

#dialogBoxPanel
  {
  position:absolute;
  display:flex;
  align-items:center;
  justify-content:center;
  left:0px;
  top:0px;
  width:100%;
  height:100%;
}
#dialogBox
  {
  width:350px;
}
<div id="dialogBoxPanel">
  <div id="dialogBox">Text</div>
</div>

Björn Morén
quelle
Benötigen Sie die äußere Abdeckung, um das gesamte Ansichtsfenster abzudecken? Wenn nicht, würde ich die Lösung von css-tricks.com/centering-css-complete-guide , Abschnitt "Sowohl horizontal als auch vertikal / Ist das Element unbekannter Breite und Höhe?" Verwenden und die Übersetzungsprozentsatzwerte ändern. (Und selbst wenn Sie die volle Größe des übergeordneten Ansichtsfensters [Hintergrund?]
Benötigen
Ja, ich habe einen Dimm-Effekt auf das äußere Bedienfeld, sodass es das gesamte Ansichtsfenster abdecken muss. Aber ich könnte noch einen DIV hinzufügen, und Ihre Lösung würde gut funktionieren. Danke 04FS!
Björn Morén
Aus Gründen der Genauigkeit sprechen Sie von vertikaler Ausrichtung, nicht von Zentrierung.
Michael Benjamin

Antworten:

11

Verwenden Sie Pseudoelement- und Spaltenrichtung, um den Leerraum zu simulieren. Passen Sie einfach flex-growdas Pseudoelement an, um zu steuern, wie viel freien Speicherplatz jedes einzelne belegen soll. Gleiches Flex-Grow bietet den gleichen Raum:

Sie können auch 2und verwenden 3. Wir müssen einfach das gleiche Verhältnis beibehalten:

Eine andere Idee ist es, einen Spitzenwert zu verwenden, der gleich ist, 40%und die Position mit translate zu korrigieren (gleiche Logik wie 50%beim Zentrieren).

#dialogBoxPanel {
  position: absolute;;
  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
  /* the center */
  background:linear-gradient(red,red) center/100% 1px no-repeat;
}

#dialogBox {
  position:relative;
  top:40%;
  width: 350px;
  transform:translateY(-40%);
  margin:auto;
  border:1px solid;
}
<div id="dialogBoxPanel">
  <div id="dialogBox">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc hendrerit diam eu nisl fringilla ornare. Pellentesque aliquam quam et tellus egestas sodales. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin bibendum,</div>
</div>

Temani Afif
quelle
Vielen Dank Temani! Beide Lösungen funktionieren einwandfrei und scheinen identisch zu sein, mit Ausnahme des Sonderfalls, in dem der Dialog größer als der Browser ist. Bei der ersten Lösung wird der obere Rand des Dialogfelds am oberen Rand des Browsers ausgerichtet und unten abgeschnitten. Die zweite Ernte sowohl unten als auch oben. Nur eine Frage der Präferenz.
Björn Morén
5

Diese Lösung verwendet display: grid, es ist eine neue Funktion. Überprüfen Sie daher unbedingt die Browserunterstützung und klicken Sie hier , um weitere Informationen zu erhalten.

Dies ist die Zeile, die den oberen und unteren Bereich steuert:

grid-template-rows: 40fr [content-start] auto [content-end] 60fr;

Der Textinhalt des Snippets kann bearbeitet werden, damit Sie überprüfen können, ob das Feld zentriert bleibt, auch wenn sich die Höhe ändert.

#dialogBoxPanel {
    display: grid;
    place-content: center;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    grid-template-rows: 40fr [content-start] auto [content-end] 60fr;
}
#dialogBox {
    border: 1px solid;
    width: 350px;
    grid-area: content;
}
<div id="dialogBoxPanel">
   <div id="dialogBox" contenteditable>Text</div>
</div>

rafaelcastrocouto
quelle
1
Ich würde die Verwendung von in Betracht ziehen 4fr auto 6fr. Was Sie haben, funktioniert, aber mit einem gewissen Überlauf, da 40% + 60% + 1fr immer größer als 100% sind und Sie zentrieren, sodass der Überlauf gleichmäßig von oben und unten aufgeteilt wird: jsfiddle.net/cobutn0e/2 . Sie werden auch feststellen, dass es nicht 100% wie erwartet ist
Temani Afif
Ich habe gerade 1fr in auto geändert. Ich möchte es lieber als% belassen, um den Fragenwerten zu entsprechen. Vielen Dank für den Hinweis auf den Fehler!
Rafaelcastrocouto
auto und 1fr liefern in Ihrem Fall das gleiche Ergebnis. Das Problem ist die Verwendung des Prozentsatzes. 1fr=minmax(auto,1fr)und in Ihrem Fall wird es fallen, autoda es keinen freien Speicherplatz gibt, da 40% + 60% = 100% (deshalb haben Sie immer einen Überlauf)
Temani Afif
1
Hier ist eine weitere Geige, um meinen Standpunkt zu veranschaulichen: jsfiddle.net/cobutn0e/3 Beachten Sie , dass die drei ersten gleich sind, die dritte auf 0 fällt und die letzte das ist, was ich vorgeschlagen habe
Temani Afif
Jetzt verstehe ich, macht Sinn. Ich werde 40fr und 60fr verwenden, da es am Ende des Tages dasselbe ist. Nochmals vielen Dank, dass Sie sich die Zeit genommen haben, mich zu unterrichten!
Rafaelcastrocouto
4

Sie können Spacer Divs hinzufügen und das Flex-Grow mit einem Verhältnis von 4: 6 einstellen.

#dialogBoxPanel {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;

  left: 0px;
  top: 0px;
  width: 100%;
  height: 100%;
}

#dialogBox {
  width: 350px;
  border: 1px solid black;
}

.spacer-top{
  flex-grow: 4;
}
.spacer-bottom{
  flex-grow: 6;
<div id="dialogBoxPanel">
  <div class="spacer-top"></div>
  <div id="dialogBox">Text</div>
  <div class="spacer-bottom"></div>
</div>

Itay Gal
quelle
Erst jetzt sah @Temani Afifs Antwort, aber es funktioniert genauso mit "nach" und "vor"
Itay Gal
0

Auf einfache Weise mit Position und Rand habe ich angenommen, dass Ihre Dialoghöhe immer 40% der Browserhöhe beträgt.

.modal{
            max-height:50%;
            width:400px;
            margin: 10% auto 5% auto;
            position:absolute;
            top:0;
            bottom:0;
            right:0;
            left:0;
            overflow-y: auto
        }
        .modal-body{
            background-color: beige;
            padding: 20px;
            line-height: 21px
        }

HTML

<div class="modal">
 <div class="modal-body">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea </div>
</div>
Anshul Chaurasia
quelle
Hallo, willkommen, wenn Sie das nächste Mal die Frage sorgfältig lesen, heißt es: "Die Höhe des Dialogfelds hängt von der Textmenge ab."
Rafaelcastrocouto
1
@rafaelcastrocouto - jetzt steuern Sie es über die maximale Höhe in Prozent, da das Verlassen ohne Höhe die Fragen der oberen und unteren Raumästhetik nicht löst.
Anshul Chaurasia