Padding-dół/góra w układzie flexbox

Mam układ flexbox zawierający dwa elementy. Jeden z nich używa padding-bottom :

#flexBox {
  border: 1px solid red;
  width: 50%;
  margin: 0 auto;
  padding: 1em;
  display: flex;
  flex-direction: column;
}
#text {
  border: 1px solid green;
  padding: .5em;
}
#padding {
  margin: 1em 0;
  border: 1px solid blue;
  padding-bottom: 56.25%; /* intrinsic aspect ratio */
  height: 0;
}
<div id='flexBox'>
  <div id='padding'></div>
  <div id='text'>Some text</div>
</div>

Niebieski element zachowuje swój współczynnik proporcji zgodnie z jego szerokością po zmianie rozmiaru strony. to działa z Chrome i IE i wygląda następująco:

padding-dno w chrome i IE na układzie flexbox

Jednak w Firefox i Edge dostaję następujące (ignoruje wypełnienie na niebieskim polu, czyli to, co utrzymuje proporcje):

padding-dno w Firefoksie na układzie flexbox

Jestem zbyt nowy dla flexbox, aby naprawdę zrozumieć, czy to powinno, czy nie powinno działać. Celem flexbox jest zmiana rozmiaru rzeczy, ale nie jestem pewien, dlaczego ignoruje wewnętrzną wyściółkę i stawia absolutne rozmiary na niebieskim elemencie.

Myślę, że ostatecznie nie jestem nawet pewien, czy Firefox lub Chrome robi poprawne rzeczy! Czy eksperci Firefox flexbox mogą pomóc?

Author: Community, 2014-05-18

4 answers

Aktualizacja Luty 2018

Firefox i edge zgodziły się zmienić swoje zachowanie na górnym, dolnym marginesie i paddingu dla elementów flex (I grid):]}

[...] np. wartości procentowe lewo/prawo/góra/dół rozwiązują się względem szerokości bloku zawierającego je w trybach pisania poziomego. [source ]

To nie jest jeszcze zaimplementowane (testowane na FF 58.0.2).

Aktualizacja kwiecień 2016

(nadal ważne w maju 2017)

Specyfikacja została zaktualizowana do:

Marginesy procentowe i paddingi na elementach flex mogą być rozwiązane w następujący sposób:

  • ich własna oś (lewy / prawy procent rozwiązuje się w stosunku do szerokości, góra/dół rozwiązuje się w stosunku do wysokości), lub
  • oś inline (lewy/prawy/górny / dolny procent rozwiąże się względem szerokości)

źródło: CSS Elastyczny poziom modułu układu pudełek 1

Oznacza to, że chrome IE FF i Edge (nawet jeśli nie mają takiego samego zachowania) postępują zgodnie z zaleceniami specyfikacji.

Specs również mówią:

Autorzy powinni unikać stosowania procentów w paddingach lub marginesach na flexie przedmiotów całkowicie, ponieważ będą one miały różne zachowania w różnych przeglądarki. [źródło]


Obejść:

Możesz zawinąć pierwszy element potomny kontenera flex w inny element i umieścić padding-bottom o drugim dziecku:

#flexBox {
  border: 1px solid red;
  width: 50%;
  margin: 0 auto;
  padding: 1em;
  display: flex;
  flex-direction: column;
}
#text {
  border: 1px solid green;
  padding: .5em;
}
#padding {
  margin: 1em 0;
  border: 1px solid blue;
}
#padding > div {
  padding-bottom: 56.25%; /* intrinsic aspect ratio */
}
<div id='flexBox'>
  <div id='padding'><div></div></div>
  <div id='text'>Some text</div>
</div>

Testowałem to w nowoczesnych przeglądarkach (IE, chrome, FF i Edge) i wszystkie mają takie samo zachowanie. Ponieważ konfiguracja drugiego dziecka jest "taka sama jak zwykle", przypuszczam, że starsze przeglądarki (które aslo obsługują moduł flexbox layout) renderują ten sam układ.


poprzednia odpowiedź:

Firefox jest jednym z najpopularniejszych przeglądarek Firefoksa.]}

Wyjaśnienie:

W przeciwieństwie do elementów blokowych, które obliczają swój % margines / wyściółkę zgodnie z szerokością kontenerów, na elementach flex:

Marginesy procentowe i paddingi na elementach flex są zawsze rozwiązane względem swoich wymiarów; w przeciwieństwie do bloków, nie zawsze rozwiązuje w stosunku do wymiaru wbudowanego bloku zawierającego je.

Źródło dev.w3.org

Oznacza to, że padding-bottom / top i margin-bottom / top są obliczana na podstawie wysokości kontenera , a nie szerokości, jak w układach innych niż flexbox.

Ponieważ nie podałeś żadnej wysokości na elemencie nadrzędnym flex, dolna wyściółka elementu podrzędnego powinna wynosić 0px.
Oto fiddle {[11] } ze stałą wysokością na rodzicu, która pokazuje, że dno wypełnienia jest obliczane zgodnie z wysokością kontenera display:flex;.


 98
Author: web-tiki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-27 16:56:01

Zaakceptowana odpowiedź jest poprawna, ale poprawiłem rozwiązanie używając pseudo-elementu zamiast dodawania nowego elementu do HTML.

Przykład: http://jsfiddle.net/4q5c4ept/

HTML:

<div id='mainFlexbox'>
  <div id='videoPlaceholder'>
    <iframe id='catsVideo' src="//www.youtube.com/embed/tntOCGkgt98?showinfo=0" frameborder="0" allowfullscreen></iframe>
  </div>
  <div id='pnlText'>That's cool! This text is underneath the video in the HTML but above the video because of 'column-reverse' flex-direction.    </div>
</div>

CSS:

#mainFlexbox {
  border: 1px solid red;
  width: 50%;
  margin: 0 auto;
  padding: 1em;
  display: flex;
  flex-direction: column-reverse;
}
#pnlText {
  border: 1px solid green;
  padding: .5em;
}
#videoPlaceholder {
  position: relative;
  margin: 1em 0;
  border: 1px solid blue;
}
#videoPlaceholder::after {
  content: '';
  display: block;
  /* intrinsic aspect ratio */
  padding-bottom: 56.25%;
  height: 0;
}
#catsVideo {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
 34
Author: OrganicPanda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-21 20:42:21

Użyłem vh zamiast % działa idealnie w Safari, Firefox & Edge

 -2
Author: hans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-20 20:28:22
    <div class="flex-parent">
      <div class="flexchild">
        <div class="pad"></div>
      </div>
    </div>  

.flex-child{
   height:100%;
}
.padd{
   padding-top:100% /* write 100%, or instead your value*/;
}
 -2
Author: Evgeny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-15 01:40:29