Rozwiązanie
Użyj zagnieżdżonych kontenerów elastycznych.
Pozbądź się wysokości procentowych. Pozbądź się właściwości tabeli. Pozbyć się vertical-align
. Unikaj absolutnego pozycjonowania. Po prostu trzymaj się Flexboksa do końca.
Zastosuj display: flex
do elementu flex ( .item
), dzięki czemu będzie to elastyczny pojemnik. To automatycznie ustawia align-items: stretch
, co każe child ( .item-inner
) rozwinąć pełną wysokość rodzica.
Ważne: Usuń określone wysokości z elementów elastycznych, aby ta metoda działała. Jeśli dziecko ma określoną wysokość (np. height: 100%
), Wówczas zignoruje align-items: stretch
pochodzenie od rodzica. Aby stretch
domyślny działał, wzrost dziecka musi być obliczony na auto
(pełne wyjaśnienie ).
Spróbuj tego (bez zmian w 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>
Demo jsFiddle
Wyjaśnienie
Mój problem polega na tym, że .item-inner { height: 100% }
nie działa w pakiecie internetowym (Chrome).
To nie działa, ponieważ używasz wysokości procentowej w sposób niezgodny z tradycyjną implementacją specyfikacji.
10.5 Wysokość treści: height
właściwość
procent
Określa procentową wysokość. Procent jest obliczany w odniesieniu do wysokości wygenerowanego bloku zawierającego blok. Jeśli wysokość zawierającego blok nie jest wyraźnie określona, a ten element nie jest pozycjonowany bezwzględnie, wartość zostanie obliczona na auto
.
auto
Wysokość zależy od wartości innych właściwości.
Innymi słowy, aby procentowa wysokość działała na potomku w przepływie, rodzic musi mieć ustawioną wysokość.
W kodzie kontener najwyższego poziomu ma zdefiniowaną wysokość: .container { height: 20em; }
Kontener trzeciego poziomu ma określoną wysokość: .item-inner { height: 100%; }
Ale między nimi kontener drugiego poziomu - .item
- nie ma określonej wysokości. Webkit uważa to za brakujący link.
.item-inner
mówi Chrome: daj miheight: 100%
. Chrome szuka informacji o obiekcie nadrzędnym ( .item
) i odpowiada: 100% czego? Nic nie widzę (ignorując istniejącą flex: 1
regułę). W rezultacie ma zastosowanie height: auto
(wysokość zawartości), zgodnie ze specyfikacją.
Z drugiej strony Firefox akceptuje teraz wysokość flex rodzica jako odniesienie do procentowej wysokości dziecka. IE11 i Edge również akceptują wysokości elastyczności.
Ponadto Chrome zaakceptuje flex-grow
jako odpowiednie odniesienie nadrzędne, jeśli zostanie użyte w połączeniu zflex-basis
(każda wartość liczbowa działa ( auto
nie będzie), w tym flex-basis: 0
). Jednak w chwili pisania tego tekstu to rozwiązanie nie działa w przeglądarce Safari.
#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>
Cztery rozwiązania
1. Określ wysokość wszystkich elementów nadrzędnych
Niezawodnym rozwiązaniem dla wielu przeglądarek jest określenie wysokości wszystkich elementów nadrzędnych. Zapobiega to brakującym linkom, które przeglądarki oparte na Webkit uznają za naruszenie specyfikacji.
Pamiętaj, że min-height
i max-height
nie są akceptowane. To musi być height
własność.
Więcej informacji tutaj: Praca z height
właściwością CSS i wartościami procentowymi
2. Pozycjonowanie względne i absolutne CSS
Zastosuj position: relative
do rodzica i position: absolute
dziecka.
Rozmiar dziecko z height: 100%
i width: 100%
lub użyj offsetowych właściwości: top: 0
, right: 0
, bottom: 0
,left: 0
.
W przypadku pozycjonowania bezwzględnego wysokość procentowa działa bez określonej wysokości nadrzędnej.
3. Usuń niepotrzebne pojemniki HTML (zalecane)
Czy w pobliżu są potrzebne dwa pojemniki button
? Dlaczego nie usunąć .item
lub .item-inner
, albo jedno i drugie? Chociaż button
elementy czasami zawodzą jako elastyczne kontenery , mogą być elastycznymi przedmiotami. Rozważyć button
dzieckiem .container
albo .item
i usuwanie nieodpłatne Mark-up.
Oto przykład:
.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. Zagnieżdżone pojemniki Flex (zalecane)
Pozbądź się wysokości procentowych. Pozbądź się właściwości tabeli. Pozbyć się vertical-align
. Unikaj absolutnego pozycjonowania. Po prostu trzymaj się Flexboksa do końca.
Zastosuj display: flex
do elementu flex ( .item
), dzięki czemu będzie to elastyczny pojemnik. To automatycznie ustawia align-items: stretch
, co każe child ( .item-inner
) rozwinąć pełną wysokość rodzica.
Ważne: Usuń określone wysokości z elementów elastycznych, aby ta metoda działała. Jeśli dziecko ma określoną wysokość (np. height: 100%
), Wówczas zignoruje align-items: stretch
pochodzenie od rodzica. Aby stretch
domyślny działał, wzrost dziecka musi być obliczony na auto
(pełne wyjaśnienie ).
Spróbuj tego (bez zmian w 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>