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 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: stretch
Kommen des Elternteils ignoriert . Damit die stretch
Standardeinstellung 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 height
Eigenschaft
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-inner
sagt Chrome: gib mirheight: 100%
. Chrome sucht als .item
Referenz beim übergeordneten Element ( ) und antwortet: 100% von was? Ich sehe nichts (ignoriere die flex: 1
Regel, 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-grow
als angemessene übergeordnete Referenz, wenn es in Verbindung mit verwendet wirdflex-basis
(jeder numerische Wert funktioniert ( auto
wird 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-height
und max-height
nicht akzeptabel sind. Es muss das height
Eigentum sein.
Weitere Details hier: Arbeiten mit der CSS- height
Eigenschaft und Prozentwerten
2. Relative und absolute CSS-Positionierung
Bewerben Sie position: relative
sich beim Elternteil und position: absolute
beim 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 .item
oder .item-inner
oder beides? Obwohl button
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:
.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: flex
das 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: stretch
Kommen des Elternteils ignoriert . Damit die stretch
Standardeinstellung 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>