Ich möchte ein vertikales Menü mit einer bestimmten Höhe haben.
Jedes Kind muss die Höhe des Elternteils ausfüllen und mittig ausgerichteten Text haben.
Die Anzahl der Kinder ist zufällig, daher muss ich mit dynamischen Werten arbeiten.
Div .container
enthält eine zufällige Anzahl von Kindern ( .item
), die immer die Größe des Elternteils ausfüllen müssen. Um das zu erreichen, habe ich Flexbox verwendet.
Um Links mit Text zu erstellen, der auf die Mitte ausgerichtet ist, verwende ich display: table-cell
Technik. Für die Verwendung von Tabellenanzeigen muss jedoch eine Höhe von 100% verwendet werden.
Mein Problem ist, dass .item-inner { height: 100% }
es im Webkit (Chrome) nicht funktioniert.
- Gibt es eine Lösung für dieses Problem?
- Oder gibt es eine andere Technik, mit der alle
.item
die Höhe des übergeordneten Elements mit vertikal zur Mitte ausgerichtetem Text füllen?
Beispiel hier jsFiddle, sollte in Firefox und Chrome angezeigt werden
.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>
quelle
top:0
undleft:0
es wie erwartet anzeigen lassen.Antworten:
Lösung
Verwenden Sie verschachtelte Flex-Container.
Prozentuale Höhen loswerden. Tabelleneigenschaften entfernen. Werde los
vertical-align
. Vermeiden Sie eine absolute Positionierung. Bleib einfach bis zum Ende bei der Flexbox.Auf
display: flex
das Flex-Element (.item
) auftragen und es zu einem Flex-Behälter machen. Dies wird automatisch festgelegtalign-items: stretch
, wodurch das Kind (.item-inner
) angewiesen wird, die volle Größe des Elternteils zu erweitern.Wichtig: Entfernen Sie die angegebenen Höhen von den Flex-Elementen, damit diese Methode funktioniert. Wenn für ein Kind eine bestimmte Größe angegeben ist (z. B.
height: 100%
), wird dasalign-items: stretch
Kommen des Elternteils ignoriert . Damit diestretch
Standardeinstellung funktioniert, muss die Größe des Kindes berechnet werdenauto
(vollständige Erklärung ).Versuchen Sie dies (keine Änderungen an HTML):
Code-Snippet anzeigen
jsFiddle-Demo
Erläuterung
Es funktioniert nicht, weil Sie die prozentuale Höhe auf eine Weise verwenden, die nicht der herkömmlichen Implementierung der Spezifikation entspricht.
Mit anderen Worten, damit die prozentuale Höhe für ein untergeordnetes Element funktioniert, muss das übergeordnete Element eine festgelegte Höhe haben.
In Ihrem Code hat der Container der obersten Ebene eine definierte Höhe:
.container { height: 20em; }
Der Container der dritten Ebene hat eine definierte Höhe:
.item-inner { height: 100%; }
Der Container der zweiten Ebene -
.item
- hat jedoch keine definierte Höhe. Webkit sieht dies als fehlendes Glied..item-inner
sagt Chrome: gib mirheight: 100%
. Chrome sucht als.item
Referenz beim übergeordneten Element ( ) und antwortet: 100% von was? Ich sehe nichts (ignoriere dieflex: 1
Regel, die es gibt). Infolgedessen gilt esheight: auto
(Inhaltshöhe) gemäß Spezifikation.Firefox hingegen akzeptiert jetzt die Flexhöhe eines Elternteils als Referenz für die prozentuale Größe des Kindes. IE11 und Edge akzeptieren ebenfalls Flexhöhen.
Außerdem akzeptiert Chrome
flex-grow
als angemessene übergeordnete Referenz, wenn es in Verbindung mit verwendet wirdflex-basis
(jeder numerische Wert funktioniert (auto
wird nicht funktionieren ), einschließlichflex-basis: 0
). Zum jetzigen Zeitpunkt schlägt diese Lösung in Safari jedoch fehl.Code-Snippet anzeigen
Vier Lösungen
1. Geben Sie für alle übergeordneten Elemente eine Höhe an
Eine zuverlässige browserübergreifende Lösung besteht darin, für alle übergeordneten Elemente eine Höhe anzugeben. Dies verhindert fehlende Links, die von Webkit-basierten Browsern als Verstoß gegen die Spezifikation angesehen werden.
Beachten Sie, dass
min-height
undmax-height
nicht akzeptabel sind. Es muss dasheight
Eigentum sein.Weitere Details hier: Arbeiten mit der CSS-
height
Eigenschaft und Prozentwerten2. Relative und absolute CSS-Positionierung
Bewerben Sie
position: relative
sich beim Elternteil undposition: absolute
beim Kind.Größe des Kind mit
height: 100%
undwidth: 100%
oder verwenden Sie die Offset - Eigenschaften:top: 0
,right: 0
,bottom: 0
,left: 0
.Bei der absoluten Positionierung funktioniert die prozentuale Höhe ohne eine bestimmte Höhe auf dem übergeordneten Element.
3. Entfernen Sie unnötige HTML-Container (empfohlen)
Benötigen zwei Container
button
? Warum nicht entfernen.item
oder.item-inner
oder beides? Obwohlbutton
Elemente manchmal als Flex-Container versagen , können sie Flex-Elemente sein. Erwägen Sie,button
aus.container
oder ein Kind zu machen.item
und unbegründete Markierungen zu entfernen.Hier ist ein Beispiel:
Code-Snippet anzeigen
4. Verschachtelte Flex-Container (empfohlen)
Prozentuale Höhen loswerden. Tabelleneigenschaften entfernen. Werde los
vertical-align
. Vermeiden Sie eine absolute Positionierung. Bleib einfach bis zum Ende bei der Flexbox.Auf
display: flex
das Flex-Element (.item
) auftragen und es zu einem Flex-Behälter machen. Dies wird automatisch festgelegtalign-items: stretch
, wodurch das Kind (.item-inner
) angewiesen wird, die volle Größe des Elternteils zu erweitern.Wichtig: Entfernen Sie die angegebenen Höhen von den Flex-Elementen, damit diese Methode funktioniert. Wenn für ein Kind eine bestimmte Größe angegeben ist (z. B.
height: 100%
), wird dasalign-items: stretch
Kommen des Elternteils ignoriert . Damit diestretch
Standardeinstellung funktioniert, muss die Größe des Kindes berechnet werdenauto
(vollständige Erklärung ).Versuchen Sie dies (keine Änderungen an HTML):
Code-Snippet anzeigen
jsFiddle
quelle
Lösung: Entfernen Sie
height: 100%
in .item-Innen und fügen Siedisplay: flex
in .itemDemo: https://codepen.io/tronghiep92/pen/NvzVoo
quelle
Das Angeben eines Flex-Attributs für den Container hat bei mir funktioniert:
Dies stellt sicher, dass die Höhe eingestellt ist und auch nicht wächst.
quelle
Für Mobile Safari gibt es einen Browser-Fix. Sie müssen -webkit-box hinzufügen für iOS-Geräte .
Ex.
Wenn Sie die
align-items: stretch;
Eigenschaft für das übergeordnete Element verwenden, entfernen Sie dasheight : 100%
aus dem untergeordneten Element.quelle
Ich hatte ein ähnliches Problem in iOS 8, 9 und 10 und die obigen Informationen konnten es nicht beheben, aber ich habe nach einem Tag Arbeit daran eine Lösung gefunden. Zugegeben, es wird nicht für alle funktionieren, aber in meinem Fall wurden meine Elemente in einer Spalte gestapelt und hatten eine Höhe von 0, wenn es sich um eine Inhaltshöhe handeln sollte. Das Problem wurde behoben, indem das CSS auf Zeile und Zeilenumbruch umgestellt wurde. Dies funktioniert nur, wenn Sie einen einzelnen Artikel haben und dieser gestapelt ist. Da ich jedoch einen Tag gebraucht habe, um dies herauszufinden, dachte ich, ich sollte meinen Fix teilen!
quelle
Ich hatte einen ähnlichen Fehler, aber während ich eine feste Zahl für die Höhe und keinen Prozentsatz verwendete. Es war auch ein flexibler Behälter innerhalb des Körpers (der keine spezifizierte Höhe hat). Auf Safari schien mein Flex-Container aus irgendeinem Grund eine Höhe von 9 Pixel zu haben, aber in allen anderen Browsern wurde die im Stylesheet angegebene korrekte Höhe von 100 Pixel angezeigt.
Ich habe es geschafft, es zum Laufen zu bringen, indem ich der CSS-Klasse sowohl die
height
als auch diemin-height
Eigenschaften hinzugefügt habe .Folgendes hat für mich sowohl in Safari 13.0.4 als auch in Chrome 79.0.3945.130 funktioniert:
Hoffe das hilft!
quelle