Wyrównaj element do dołu za pomocą Flexbox

374

Mam divz kilkoma dziećmi:

<div class="content">
  <h1>heading 1</h1>
  <h2>heading 2</h2>
  <p>Some more or less text</p>
  <a href="/" class="button">Click me</a>
</div>

i chcę następujący układ:

 -------------------
|heading 1          |
|heading 2          | 
|paragraph text     |
|can have many      |
|rows               |
|                   |
|                   |
|                   | 
|link-button        |
 -------------------

Niezależnie od tego, ile tekstu jest w p, chcę trzymać .buttonzawsze na dole, nie usuwając go z obiegu. Słyszałem, że można to osiągnąć dzięki Flexbox, ale nie mogę tego uruchomić.

duży rozmiar
źródło
7
Po prostu to daj postition: absolute; bottom 0;?
Jonathan
12
@Jonathan owijarka nie ma stałej wysokości. Jeśli wyciągnę go z
obiegu,
2
@supersize old Q, ale mógłbyś podać opakowanie position:relative- jest głupie, ponieważ myślę, że domyślnie jest względne, ale masz SET, aby zawrzeć absolutne położenie dziecka. Wtedy bottom:0będzie pasować do koloru.
Jacksonkr,
Jacksonkr ma rację, jest to NAJLEPSZE rozwiązanie, inne są za długie, zbyt skomplikowane lub nie działają we właściwy sposób
Barbz_YHOOL
2
@Jacksonkr domyślna pozycja div staticnie jest relative.
supersize

Odpowiedzi:

641

Możesz użyć auto marginesów

Przed wyrównaniem za pomocą justify-contenti align-self, dowolna dodatnia wolna przestrzeń jest rozdzielana na automatyczne marginesy w tym wymiarze.

Możesz więc użyć jednego z tych (lub obu):

p { margin-bottom: auto; } /* Push following elements to the bottom */
a { margin-top: auto; } /* Push it and following elements to the bottom */

Alternatywnie możesz wykonać element przed apowiększeniem, aby wypełnić dostępną przestrzeń:

p { flex-grow: 1; } /* Grow to fill available space */

Oriol
źródło
2
Dla mnie działa to w Chrome, ale nie w Safari na iOS 10.2. Czy ktoś może potwierdzić?
Matthew
@Oriol Podoba mi się to podejście, ale nie efekt uboczny utraty marży, co byś z tym zrobił?
Neil
11
Flex-Grow pracował dla mnie. Oto jak to zrobiłemhtml { height: 100%; } body { min-height: 100%; display: flex; flex-direction: column; } #site-content { flex: 1; }
Proto Evangelion
2
Na marginesie, pamiętaj, aby height: 100%na elemencie nadrzędnym, którego próbujesz zepchnąć coś na dnomargin-top: auto;
skolind
1
„każda dodatnia wolna przestrzeń jest rozdzielana na automatyczne marginesy w tym wymiarze”. takie małe rzeczy są tak eleganckie, dla mnie rozwiązaniem były 2 linie kodu oparte na twojej odpowiedzi. dziękuję :)
Danjah
146

Możesz użyć display: flex, aby ustawić element na dole, ale nie sądzę, abyś chciał użyć flex w tym przypadku, ponieważ wpłynie to na wszystkie twoje elementy.

Aby ustawić element na dole za pomocą flex, spróbuj:

.container {
  display: flex;
}

.button {
  align-self: flex-end;
}

Najlepiej jest ustawić pozycję: absolutnie na przycisk i ustawić go na bottom: 0, lub możesz umieścić przycisk na zewnątrz pojemnika i użyć ujemnego, transform: translateY(-100%)aby wprowadzić go do pojemnika w następujący sposób:

.content {
    height: 400px;
    background: #000;
    color: #fff;
}
.button {
    transform: translateY(-100%);
    display: inline-block;
}

Sprawdź to JSFiddle

Roumelis George
źródło
6
jeśli chcesz na dole, ustaw kierunek wygięcia na kolumnę.
Viliami
3
Co jeśli nie mogę podać wysokości?
Mark
Dla mnie zadziałało tylko: ``. content {display: flex; kierunek zgięcia: kolumna; justify-content: flex-end; } <div class = "content"> <a class="bottom"> Coś </a> </div> ``
gsalgadotoledo
84

Rozwiązanie z align-self: flex-end; nie działało dla mnie, ale to zadziałało w przypadku, gdy chcesz użyć Flex:

Wynik

 -------------------
|heading 1          |
|heading 2          | 
|paragraph text     |
|                   |
|                   |
|                   | 
|link button        |
 -------------------

Kod

Uwaga: podczas „uruchamiania fragmentu kodu” należy przewinąć w dół, aby zobaczyć link na dole.

.content {
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  height: 300px;
}

.content .upper {
  justify-content: normal;
}

/* Just to show container boundaries */
.content .upper, .content .bottom, .content .upper > * {
  border: 1px solid #ccc;
}
<div class="content">
  <div class="upper">
	  <h1>heading 1</h1>
	  <h2>heading 2</h2>
	  <p>paragraph text</p>
  </div>

  <div class="bottom">
	  <a href="/" class="button">link button</a>
  </div>
</div>

Timo
źródło
1
content to kontener kolumny zawierający 2 inne kontenery z justify-content: space-between; mówisz flexboxowi, aby odsunął pojemnik od siebie tak bardzo, jak to możliwe (w tym przypadku ograniczone wysokością kontenera zawartości)
ConquerorsHaki
to nie jest prawdziwy wynik, będzie miał miejsce między każdym przedmiotem (stąd nazwa)
Barbz_YHOOL
1
@Barbz_YHOOL Nie, to działa, jeśli zwiększysz wysokość pojemnika (patrz zaktualizowany przykład)
Timo
1
Po wielu poszukiwaniach jest to po prostu idealne! Dziękuję Ci.
Rudy
1
Po niewielkiej modyfikacji odpowiedź ta zadziałała dla mnie idealnie, dziękuję
RealMJDev,
2

Nie jestem pewien co do Flexboksa, ale możesz to zrobić za pomocą właściwości position.

zestaw rodzic div position: relative i dziecko elementem, który może być <p>albo <h1>etc .. zestaw position: absolutei bottom: 0.

Przykład:

index.html

<div class="parent">
  <p>Child</p>
</div>

style.css

.parent {
  background: gray;
  width: 10%;
  height: 100px;    
  position: relative;
}
p {
  position: absolute;
  bottom: 0;
}

Pióro do kodu tutaj.

Sanjay Shr
źródło
1
position:fixednie działałby, ponieważ wtedy nie byłby związany z pojemnikiem, w którym się znajduje. Być może miałeś na myśli position:absolute?
Sensoray
1
Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, dlaczego i / lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość.
rollstuhlfahrer
1
Zaktualizowana odpowiedź.
Sanjay Shr
0

wprowadź opis zdjęcia tutaj

<section style="display:flex; flex-wrap:wrap;">
    <div style="display:flex; flex-direction:column; flex:1;">
        <button style="margin-top: auto;"/>
    </div>
    <div style="display:flex; flex-direction:column; flex:1;">
        <button style="margin-top: auto;"/>
    </div>
</section>

Demo: https://codepen.io/ferittuncer/pen/YzygpWX

ferit
źródło
0

Ustawiając ekran tak, aby był elastyczny , możesz po prostu użyć flexwłaściwości, aby zaznaczyć, która zawartość może rosnąć, a która nie.

Właściwość Flex

div.content {
 height: 300px;
 display: flex;
 flex-direction: column;
}

div.up {
  flex: 1;
}

div.down {
  flex: none;
}
<div class="content">
  <div class="up">
    <h1>heading 1</h1>
    <h2>heading 2</h2>
    <p>Some more or less text</p>
  </div>

  <div class="down">
    <a href="/" class="button">Click me</a>
  </div>
</div>

Tomas Vancoillie
źródło
-1

Spróbuj tego

.content {
      display: flex;
      flex-direction: column;
      height: 250px;
      width: 200px;
      border: solid;
      word-wrap: break-word;
    }

   .content h1 , .content h2 {
     margin-bottom: 0px;
    }

   .content p {
     flex: 1;
    }
   <div class="content">
  <h1>heading 1</h1>
  <h2>heading 2</h2>
  <p>Some more or less text</p>
  <a href="/" class="button">Click me</a>
</div>

mohxn ayaz
źródło
-1

Właśnie znalazłem rozwiązanie tego problemu.

dla tych, którzy nie są zadowoleni z podanych odpowiedzi, można wypróbować to podejście z Flexbox

CSS

    .myFlexContainer {
        display: flex;
        width: 100%;
    }

    .myFlexChild {
        width: 100%;
        display: flex;

        /* 
         * set this property if this is set to column by other css class 
         *  that is used by your target element 
         */
        flex-direction: row;

        /* 
         * necessary for our goal 
         */
        flex-wrap: wrap;
        height: 500px;
    }

    /* the element you want to put at the bottom */
    .myTargetElement {
        /*
         * will not work unless flex-wrap is set to wrap and 
         * flex-direction is set to row
         */
        align-self: flex-end;
    }

HTML

    <div class="myFlexContainer">
        <div class="myFlexChild">
            <p>this is just sample</p>
            <a class="myTargetElement" href="#">set this to bottom</a>
        </div>
    </div>
aj idź
źródło