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: flexdas Flex-Element ( .item) auftragen und es zu einem Flex-Behälter machen. Dies wird automatisch festgelegt align-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 das align-items: stretchKommen des Elternteils ignoriert . Damit die stretchStandardeinstellung funktioniert, muss die Größe des Kindes berechnet werden auto (vollständige Erklärung ).
Versuchen Sie dies (keine Änderungen an HTML):
.container {
display: flex;
flex-direction: column;
height: 20em;
border: 5px solid black
}
.item {
display: flex; /* new; nested flex container */
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
display: flex; /* new; nested flex container */
flex: 1; /* new */
/* height: 100%; <-- remove; unnecessary */
/* width: 100%; <-- remove; unnecessary */
/* display: table; <-- remove; unnecessary */
}
a {
display: flex; /* new; nested flex container */
flex: 1; /* new */
align-items: center; /* new; vertically center text */
background: orange;
/* display: table-cell; <-- remove; unnecessary */
/* vertical-align: middle; <-- remove; unnecessary */
}
<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>
jsFiddle-Demo
Erläuterung
Mein Problem ist, dass .item-inner { height: 100% }es im Webkit (Chrome) nicht funktioniert.
Es funktioniert nicht, weil Sie die prozentuale Höhe auf eine Weise verwenden, die nicht der herkömmlichen Implementierung der Spezifikation entspricht.
10.5 Inhaltshöhe: die heightEigenschaft
Prozent
Gibt eine prozentuale Höhe an. Der Prozentsatz wird in Bezug auf die Höhe des Blocks der generierten Box berechnet. Wenn die Höhe des enthaltenden Blocks nicht explizit angegeben wird und dieses Element nicht absolut positioniert ist, berechnet der Wert zu auto.
auto
Die Höhe hängt von den Werten anderer Eigenschaften ab.
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-innersagt Chrome: gib mirheight: 100% . Chrome sucht als .itemReferenz beim übergeordneten Element ( ) und antwortet: 100% von was? Ich sehe nichts (ignoriere die flex: 1Regel, die es gibt). Infolgedessen gilt es height: 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-growals angemessene übergeordnete Referenz, wenn es in Verbindung mit verwendet wirdflex-basis (jeder numerische Wert funktioniert ( autowird nicht funktionieren ), einschließlich flex-basis: 0). Zum jetzigen Zeitpunkt schlägt diese Lösung in Safari jedoch fehl.
#outer {
display: flex;
flex-direction: column;
height: 300px;
background-color: white;
border: 1px solid red;
}
#middle {
flex-grow: 1;
flex-basis: 1px;
background-color: yellow;
}
#inner {
height: 100%;
background-color: lightgreen;
}
<div id="outer">
<div id="middle">
<div id="inner">
INNER
</div>
</div>
</div>
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-heightund max-heightnicht akzeptabel sind. Es muss das heightEigentum sein.
Weitere Details hier: Arbeiten mit der CSS- heightEigenschaft und Prozentwerten
2. Relative und absolute CSS-Positionierung
Bewerben Sie position: relativesich beim Elternteil und position: absolutebeim Kind.
Größe des Kind mit height: 100%und width: 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 .itemoder .item-inneroder beides? Obwohl buttonElemente manchmal als Flex-Container versagen , können sie Flex-Elemente sein. Erwägen Sie, buttonaus .containeroder ein Kind zu machen .itemund unbegründete Markierungen zu entfernen.
Hier ist ein Beispiel:
.container {
height: 20em;
display: flex;
flex-direction: column;
border: 5px solid black
}
a {
flex: 1;
background: orange;
border-bottom: 1px solid white;
display: flex; /* nested flex container (for aligning text) */
align-items: center; /* center text vertically */
justify-content: center; /* center text horizontally */
}
<div class="container">
<a>Button</a>
<a>Button</a>
<a>Button</a>
</div>
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: flexdas Flex-Element ( .item) auftragen und es zu einem Flex-Behälter machen. Dies wird automatisch festgelegt align-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 das align-items: stretchKommen des Elternteils ignoriert . Damit die stretchStandardeinstellung funktioniert, muss die Größe des Kindes berechnet werden auto (vollständige Erklärung ).
Versuchen Sie dies (keine Änderungen an HTML):
.container {
display: flex;
flex-direction: column;
height: 20em;
border: 5px solid black
}
.item {
display: flex; /* new; nested flex container */
flex: 1;
border-bottom: 1px solid white;
}
.item-inner {
display: flex; /* new; nested flex container */
flex: 1; /* new */
/* height: 100%; <-- remove; unnecessary */
/* width: 100%; <-- remove; unnecessary */
/* display: table; <-- remove; unnecessary */
}
a {
display: flex; /* new; nested flex container */
flex: 1; /* new */
align-items: center; /* new; vertically center text */
background: orange;
/* display: table-cell; <-- remove; unnecessary */
/* vertical-align: middle; <-- remove; unnecessary */
}
<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>