Jak mogę ustawić div na dnie jego pojemnika?


741

Biorąc pod uwagę następujący kod HTML:

<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
</div>

Chciałbym #copyrighttrzymać się dna #container.

Czy mogę to osiągnąć bez bezwzględnego pozycjonowania? Jeśli właściwość float obsługuje wartość „bottom”, wydaje się, że to by zadziałało, ale niestety tak nie jest.


211
Ta sytuacja jest jednym z powodów, dla których tabele układu nie zostały jeszcze usunięte. Robienie tego przy stole jest śmiertelnie proste i działa wszędzie. Robienie tego w CSS jest zabawnie trudne, a obsługa różnych przeglądarek jest taka sobie. Nie mówiąc już o tym, że nie można pamiętać, jak zrobić to dobrze.
Tomalak

Nie rozumiem pytania. Dlaczego w ogóle potrzebujesz bezwzględnego pozycjonowania? Czy kontener ma ustawioną wysokość, niezależnie od zawartości, którą zawiera?
HartleySan

Odpowiedzi:


921

Prawdopodobnie nie.

Przypisz position:relativedo #container, a następnie position:absolute; bottom:0;do #copyright.


#container {
    position: relative;
}
#copyright {
    position: absolute;
    bottom: 0;
}
<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
</div>


10
Jeśli pozycja: krewny na twoim kontenerze psuje projekt, pamiętaj, że możesz po prostu dołączyć otulacz div do kontenera o 100% wysokości i zamiast tego dodać pozycję: względem niego.
Jack Shepherd,

a jeśli chodzi o powtarzające się elementy, które w innym przypadku zostałyby umieszczone na sobie?
CRice

6
Element pozycjonowany absolutnie szuka najbliższego elementu nadrzędnego, który jest pozycją absolutną lub względną w celu ustalenia jego pozycji. Jeśli wszystko zawiedzie, ucieknie się do ciała (okna). Stąd potrzeba, aby rodzic był względny.
user17753

1
dodaj margines u dołu do #container, aby zapobiec prawu autorskiemu do treści strony
Doc Kodam

1
Podejście do Flexbox poniżej jest znacznie lepsze.
woohoo,

345

W rzeczywistości zaakceptowana odpowiedź @User zadziała tylko wtedy, gdy okno jest wysokie, a treść krótka. Ale jeśli zawartość jest wysoka, a okno jest krótkie, spowoduje to umieszczenie informacji o prawach autorskich nad treścią strony, a następnie przewinięcie w dół, aby zobaczyć, że treść pozostawi Ci swobodną informację o prawach autorskich. To sprawia, że ​​to rozwiązanie jest bezużyteczne na większości stron (tak jak ta strona).

Najczęstszym sposobem osiągnięcia tego jest wykazane podejście „lepka stopka CSS” lub nieco cieńsza odmiana. To podejście działa świetnie - JEŚLI masz stopkę o stałej wysokości.

Jeśli potrzebujesz stopki o zmiennej wysokości, która pojawi się na dole okna, jeśli zawartość jest zbyt krótka, a na dole zawartości, jeśli okno jest zbyt krótkie, co robisz?

Połknij swoją dumę i skorzystaj ze stołu.

Na przykład:

* {
    padding: 0;
    margin: 0;
}

html, body {
    height: 100%;
}

#container {
    height: 100%;
    border-collapse: collapse;
}
<!DOCTYPE html>
<html>
<body>
    <table id="container">
        <tr>
            <td valign="top">
                <div id="main">Lorem ipsum, etc.</div>
            </td>
        </tr>
        <tr>
            <td valign="bottom">
                <div id="footer">Copyright some evil company...</div>
            </td>
        </tr>
    </table>
</body>
</html>

Wypróbuj to. Będzie to działać dla każdego rozmiaru okna, dla dowolnej ilości treści, dla dowolnej wielkości stopki, w każdej przeglądarce ... nawet IE6.

Jeśli skradasz się na myśl o użyciu stołu do układania, poświęć chwilę, aby zadać sobie pytanie, dlaczego. CSS miał ułatwić nam życie - i ogólnie tak jest - ale faktem jest, że nawet po tylu latach wciąż jest to zepsuty, sprzeczny z intuicją bałagan. Nie może rozwiązać każdego problemu. To jest niekompletne.

Tabele nie są fajne, ale przynajmniej na razie są czasem najlepszym sposobem rozwiązania problemu projektowego.


80
To dla mnie najlepsza odpowiedź. Ponadto zawsze możesz używać „tabel css” (display: table [-row / -cell]) zamiast tabel html. Zapewnia to ten sam układ bez semantyki.
chiccodoro,

1
Jeśli masz skrypt PHP / inny skrypt, który generuje stronę, możesz zduplikować stopkę, używając jednego jako ukrytego „elementu dystansowego” i drugiego umieszczonego absolutnie. Stopka odstępu zapewnia, że ​​bez względu na to, ile treści masz w stopce, nie przejdzie ona w górę strony.
Tyzoid 18.04.13

20
Dla innych czytających te komentarze: nie ma to nic wspólnego z „dumą” ani „spokojem”. Używanie tabel do układu jest pragmatycznie jeszcze bardziej bolesne, szczególnie w przypadku dużych ilości treści. Upewnij się, że nie przegapisz td i przesiewaj tak mało nieistotne znaczniki, gdy dodawanie zawartości jest piekłem. Jest to uciążliwe, ponieważ tworzymy dokumenty HTML, a nie tylko układy, a jeśli większość zawartości naszego dokumentu nie jest danymi tabelarycznymi, to dlaczego umieszczamy go w tabelach? Jeśli nie lubimy korzystać z technologii sieciowych w sposób, w jaki były przeznaczone, to po co ich używać? Zamiast tego
używaj

1
@ chiccodoro Wdrożyłem ekwiwalent bez tabel, który jest zaskakująco minimalny, sprawdź moją odpowiedź poniżej
Hashbrown

59
Duma nie ma znaczenia. Ze względu na dostępność nie należy używać tabel w układzie. Jeśli kiedykolwiek korzystałeś z czytnika ekranu, będziesz wiedział, dlaczego tabele powinny być używane tylko dla danych tabelarycznych. Użyj tabel css jako stanów @chiccodoro.
Matt Fellows,

170

Podejście Flexbox!

W obsługiwanych przeglądarkach możesz użyć:

Przykład tutaj

.parent {
  display: flex;
  flex-direction: column;
}
.child {
  margin-top: auto;
}


Powyższe rozwiązanie jest prawdopodobnie bardziej elastyczne, jednak oto alternatywne rozwiązanie:

Przykład tutaj

.parent {
  display: flex;
}
.child {
  align-self: flex-end;
}


Na marginesie warto dodać prefiksy dostawcy, aby uzyskać dodatkowe wsparcie.


3
co powiesz column-reversena rodzica, więc nie musisz nic dodawać do dziecka?
Max Waterman,

1
To prawdopodobnie powinna być zaakceptowana odpowiedź - bez hacków, bez absolutnego pozycjonowania, przepełnienie działa czysto w razie potrzeby (to było dla mnie).
Adverbly

114

Tak, możesz to zrobić bez absolutepozycjonowania i bez użycia tables (które wkręcają znaczniki i tym podobne).

DEMO
To przetestowane do pracy na IE> 7, chrome, FF i jest bardzo łatwe do dodania do istniejącego układu.

<div id="container">
    Some content you don't want affected by the "bottom floating" div
    <div>supports not just text</div>

    <div class="foot">
        Some other content you want kept to the bottom
        <div>this is in a div</div>
    </div>
</div>
#container {
    height:100%;
    border-collapse:collapse;
    display : table;
}

.foot {
    display : table-row;
    vertical-align : bottom;
    height : 1px;
}

Skutecznie robi to float:bottom, co zrobiłby, nawet uwzględniając problem wskazany w odpowiedzi @Rick Reilly!


1
Miły! Tylko uwaga, IIRC potrzebujesz <!DOCTYPE>zestawu, aby działał na IE (przynajmniej <= 8); te starsze wersje obsługują tylko display:table-XXXw trybie „standardów”. Ale tryb standardów zepsuje również wiele stron, które zostały zaprojektowane, powiedzmy, dla IE6.
David

3
Możesz także użyć Flexbox - stackoverflow.com/questions/526035/...
Josh Crozier

2
Znalazłem więcej szczęścia .foot{display: table-footer-group}. Nie trzeba vertical-align, heightalbo border-collapse.
Jacob Valenta

Czy to zadziałałoby, gdyby #containertylko zawierało #footi nie zawierało żadnej innej treści?
Solace

Wygląda na to, że przynajmniej potrzebowałaby niezniszczalnej przestrzeni , @Solace
Hashbrown

20

To stare pytanie, ale jest to unikalne podejście, które może pomóc w kilku przypadkach.

Czysty CSS, bez absolutnego pozycjonowania, bez ustalania jakiejkolwiek wysokości, przeglądarka (IE9 +)

sprawdź to Working Fiddle

Ponieważ normalny przepływ przebiega „od góry do dołu”, nie możemy po prostu poprosić #copyrightdiv, aby przylgnął do dna swojego rodzica bez absolutnego ustawienia, ale jeśli chcielibyśmy, aby #copyrightdiv przylgnął do górnej części jego rodzica, będzie bardzo proste - ponieważ jest to normalny sposób przepływu.

Wykorzystamy to na naszą korzyść. zmienimy kolejność divs w HTML, teraz #copyrightdiv jest na górze, a treść podąża za nim od razu. sprawiamy, że div treści jest rozciągnięty do końca (przy użyciu pseudoelementów i technik czyszczenia)

teraz wystarczy odwrócić tę kolejność z powrotem w widoku. można to łatwo zrobić za pomocą transformacji CSS.

Obracamy pojemnik o 180 stopni, a teraz: góra-dół-dół. (i odwracamy treść, aby znów wyglądała normalnie)

Jeśli chcemy mieć pasek przewijania w obszarze zawartości, musimy zastosować nieco więcej magii CSS. jak można pokazać tutaj [w tym przykładzie treść znajduje się pod nagłówkiem - ale to ten sam pomysł]

* {
  margin: 0;
  padding: 0;
}

html,
body,
#Container {
  height: 100%;
  color: white;
}

#Container:before {
  content: '';
  height: 100%;
  float: left;
}

#Copyright {
  background-color: green;
}

#Stretch {
  background-color: blue;
}

#Stretch:after {
  content: '';
  display: block;
  clear: both;
}

#Container,
#Container>div {
  -moz-transform: rotateX(180deg);
  -ms-transform: rotateX(180deg);
  -o-transform: rotate(180deg);
  -webkit-transform: rotateX(180deg);
  transform: rotateX(180deg);
}
<div id="Container">
  <div id="Copyright">
    Copyright Foo web designs
  </div>
  <div id="Stretch">
    <!-- Other elements here -->
    <div>Element 1</div>
    <div>Element 2</div>
  </div>
</div>


2
Proszę nie, spójrz jak okropne jest teraz renderowanie i.stack.imgur.com/ZP9Hw.png
grg

7

Utwórz kolejny pojemnik divdla powyższych elementów #copyright. Tuż nad autorskim dodać nowy div: <div style="clear:both;"></div> Będzie zmusić stopkę być pod wszystkiego innego, podobnie jak w przypadku korzystania z względną pozycję ( bottom:0px;).


7

Spróbuj tego;

<div id="container">
  <div style="height: 100%; border:1px solid #ff0000;">
  <!-- Other elements here -->
  </div>
</div>
<div id="copyright" style="position:relative;border:1px solid #00ff00;top:-25px">
   Copyright Foo web designs
</div>


1
@Feelsbadman Proszę nie zmieniać kodu innych osób w takich odpowiedziach. Jeśli chciałeś po prostu oddzielić CSS od HTML, pamiętaj, że przypadkowo zmieniłeś kod na inny, prawdopodobnie unieważniając odpowiedź i na pewno zmieniając intencje autora.
TylerH

6

Chociaż żadna z podanych tutaj odpowiedzi nie zdawała się mieć zastosowania lub zadziałać w moim konkretnym przypadku, natknąłem się na ten artykuł, który zapewnia to schludne rozwiązanie:

#container {
  display: table;
}

#copyright {
  display: table-footer-group;
}

Uważam, że jest to bardzo przydatne przy stosowaniu responsywnego projektu do wyświetlania na urządzeniach mobilnych bez konieczności zmiany kolejności całego kodu HTML witryny, ustawienie body się jako tabela.

Zauważ, że tylko pierwszy table-footer-grouplub table-header-groupbędzie renderowany jako taki: jeśli jest więcej niż jeden, pozostałe będą renderowane jako table-row-group.


6

Siatka CSS

Ponieważ użycie CSS Grid rośnie, chciałbym zasugerować align-selfelementowi, który znajduje się w kontenerze siatki.

align-selfmoże zawierać dowolną z wartości: end, self-end, flex-endw następującym przykładzie.

#parent {
  display: grid;
}

#child1 {
  align-self: end;
}

/* Extra Styling for Snippet */

#parent {
  height: 150px;
  background: #5548B0;
  color: #fff;
  padding: 10px;
  font-family: sans-serif;
}

#child1 {
  height: 50px;
  width: 50px;
  background: #6A67CE;
  text-align: center;
  vertical-align: middle;
  line-height: 50px;
}
<div id="parent">
  <!-- Other elements here -->
  <div id="child1">
    1
  </div>

</div>


5

Można wprawdzie alignpole do bottombez użycia position:absolutejeśli wiesz, że heightz #containerpomocą wyrównania tekstu cechę inline-blockelementów.

Tutaj możesz zobaczyć to w akcji.

To jest kod:

#container {
    /* So the #container most have a fixed height */
    height: 300px;
    line-height: 300px;
    background:Red;
}

#container > * {
    /* Restore Line height to Normal */
    line-height: 1.2em;
}

#copyright {
    display:inline-block;
    vertical-align:bottom;
    width:100%; /* Let it be a block */
    background:green;
}

5

Korzystanie z translateY i top właściwości

Wystarczy ustawić element potomny na pozycję: względną, a następnie przesunąć go do góry: 100% (to jest 100% wysokość rodzica) i przykleić się do dna rodzica przez przekształcenie: translateY (-100%) (to -100% wysokości dziecko).

Korzyści

  • ty nie ma elementu ze strumienia widoku
  • jest dynamiczny

Ale nadal tylko obejście :(

.copyright{
   position: relative;
   top: 100%;
   transform: translateY(-100%);
}

Nie zapomnij prefiksów dla starszej przeglądarki.


4

Link CodePen tutaj .

html, body {
    width: 100%;
    height: 100%;
}

.overlay {
    min-height: 100%;
    position: relative;
}

.container {
    width: 900px;
    position: relative;
    padding-bottom: 50px;
}

.height {
    width: 900px;
    height: 50px;
}

.footer {
    width: 900px;
    height: 50px;
    position: absolute;
    bottom: 0;
}
<div class="overlay">
    <div class="container">
        <div class="height">
            content
        </div>
    </div>

    <div class="footer">
        footer
    </div>
</div>


3

Jeśli chcesz, aby „przyklejał się” do dna, niezależnie od wysokości pojemnika, bezwzględne pozycjonowanie jest najlepszym rozwiązaniem. Oczywiście, jeśli element copyright jest ostatnim w kontenerze, i tak zawsze będzie na dole.

Czy potrafisz rozwinąć swoje pytanie? Wyjaśnij dokładnie, co próbujesz zrobić (i dlaczego nie chcesz używać absolutnego pozycjonowania)?


2

Ponadto, jeśli istnieją zastrzeżenia dotyczące używania position:absolute;lub position:relative;, zawsze możesz spróbować padding nadrzędnego div lub umieścić margin-top:x;. W większości przypadków niezbyt dobra metoda, ale w niektórych przypadkach może się przydać.


1

Może to komuś pomaga: zawsze możesz umieścić div poza drugim div, a następnie pchnąć go w górę, używając ujemnego marginesu:

<div id="container" style="background-color: #ccc; padding-bottom: 30px;">
  Hello!
</div>
<div id="copyright" style="margin-top: -20px;">
  Copyright Foo web designs
</div>

1

 #container{width:100%; float:left; position:relative;}
#copyright{position:absolute; bottom:0px; left:0px; background:#F00; width:100%;}
#container{background:gray; height:100px;}
<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
</div>

<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
</div>


1

Nie chcę używać „pozycja: absolutna” dla lepkiej stopki na dole. Następnie możesz zrobić w ten sposób:

 html,
        body {
            height: 100%;
            margin: 0;
        }
        .wrapper {
            min-height: 100%;
            /* Equal to height of footer */
            /* But also accounting for potential margin-bottom of last child */
            margin-bottom: -50px;
        }
        .footer{
            background: #000;
            text-align: center;
            color: #fff;
        }
        .footer,
        .push {
            height: 50px;
        }
<html>
<body>
    <!--HTML Code-->
    <div class="wrapper">
        <div class="content">content</div>
        <div class="push"></div>
    </div>
    <footer class="footer">test</footer>
</body>
</html>


Cześć Nilesh; to rozwiązanie jest już dostępne w wielu odpowiedziach. Przed udzieleniem nowego przeczytaj wszystkie istniejące odpowiedzi na pytanie, aby uniknąć powielania treści!
TylerH

1

Jeśli nie znasz wysokości bloku potomnego:

#parent {
    background:green;
    width:200px;
    height:200px;
    display:table-cell;
    vertical-align:bottom;
}
.child {
    background:red;
    vertical-align:bottom;
}
<div id="parent">
    <div class="child">child
    </div> 
</div>

http://jsbin.com/ULUXIFon/3/edit

Jeśli znasz wysokość bloku potomnego, dodaj blok potomny, a następnie dodaj padding-top / margin-top:

#parent {
    background:green;
    width:200px;
    height:130px;
    padding-top:70px;
}
.child {
    background:red;
    vertical-align:
    bottom;
    height:130px;
}
<div id="parent">
    <div class="child">child
    </div> 
</div>  


0

Tylko dlatego, że w ogóle o tym nie wspomniano, co zwykle działa dobrze w sytuacjach takich jak Twoja:

Umieszczanie div-praw autorskich po div-kontenera

Musisz tylko sformatować div praw autorskich w podobny sposób, jak w innym kontenerze (ta sama szerokość całkowita, centrowanie itp.), I wszystko jest w porządku.

CSS:

#container, #copyright {
    width: 1000px;
    margin:0 auto;
}

HTML:

<div id="container">
    <!-- Other elements here -->
</div>

<div id="copyright">
    Copyright Foo web designs
</div>

Jedyny raz może to nie być idealne, gdy deklarujesz div kontenera height:100%, a użytkownik musiałby przewinąć w dół, aby zobaczyć prawa autorskie. Ale nawet mimo to możesz się obejść (np. margin-top:-20pxGdy wysokość twojego elementu autorskiego wynosi 20px).

  • Bez absolutnego pozycjonowania
  • Brak układu tabeli
  • Brak szalonego css, który wygląda inaczej w każdej innej przeglądarce (przynajmniej IE, wiesz)
  • Proste i przejrzyste formatowanie

Poza tym: wiem, że OP poprosił o rozwiązanie, które „... przykleja się do dna„ pojemnika ”div ...” , a nie coś pod nim, ale daj spokój, ludzie szukają tutaj dobrych rozwiązań, a to jest jeden!


W przypadku OP to rozwiązanie jest dobre tylko wtedy, gdy #copyright ma stałą wysokość (wtedy można ustawić margin-top: -{element height}.
Gajus

@ Gajus: To nie jest absolutne ani stałe pozycjonowanie. Robi to dokładnie to, czego chce OP (bez względu na wysokość praw autorskich), z tym wyjątkiem, że div praw autorskich nie znajduje się w pierwszym kontenerze. OP poprosił o umieszczenie praw autorskich na dnie pojemnika, a nie na stronie !!
Lewita

Przepraszam, nie mam na myśli, jeśli # kontener zawiera stałą wysokość.
Gajus

O ile się nie mylę, prawdziwym problemem, który OP próbuje rozwiązać, jest spód elementu, gdy wysokość elementu jest podyktowana przez inny element, np. Z komentarzami jsbin.com/acoVevI/3 . Tutaj nie można po prostu umieścić przycisku poza pojemnikiem . Aby zilustrować problem, zobacz jsbin.com/acoVevI/4 .
Gajus

OP powiedział: „Chciałbym, aby #copyright trzymał się dna #container.”, Więc nie jest to całkowicie jasne z pytania. Ponadto jest to prawidłowy przykład dla każdego przypadku, w którym powinien po prostu „trzymać się dna #container”. To rozwiązanie powinno być pomocne, ma czyste podejście i działa dobrze w przypadku wielu układów. Np. Każda strona z przewijaną zawartością, taka jak stackoverflow.com ;-)
Levite

0

Oto podejście ukierunkowane na to, aby element o znanej wysokości i szerokości (przynajmniej w przybliżeniu) unosił się w prawo i pozostawał na dole, zachowując się jednocześnie jako element wbudowany w inne elementy. Jest on skoncentrowany w prawym dolnym rogu, ponieważ można go łatwo umieścić w dowolnym innym rogu za pomocą innych metod.

Musiałem stworzyć pasek nawigacyjny, który miałby rzeczywiste linki w prawym dolnym rogu i losowe elementy rodzeństwa, jednocześnie upewniając się, że sam pasek rozciągał się prawidłowo, bez zakłócania układu. Użyłem elementu „shadow”, aby zająć przestrzeń linków paska nawigacji i dodałem go na końcu węzłów potomnych kontenera.


<!DOCTYPE html>
<div id="container">
  <!-- Other elements here -->
  <div id="copyright">
    Copyright Foo web designs
  </div>
  <span id="copyright-s">filler</span>
</div>

<style>
  #copyright {
    display:inline-block;
    position:absolute;
    bottom:0;
    right:0;
  }
  #copyright-s {
    float:right;
    visibility:hidden;
    width:20em; /* ~ #copyright.style.width */
    height:3em; /* ~ #copyright.style.height */
  }
</style>

0

W float:bottomCSS nic nie jest wywoływane . Najlepszym sposobem jest użycie pozycjonowania w takich przypadkach:

position:absolute;
bottom:0;

Proszę wyjaśnić swoją odpowiedź.
Mohit Raj Purohit

0

Dla tych, którzy mają tylko jedno dziecko w kontenerze, możesz użyć metody table-celli, vertical-alignktóra działała niezawodnie do pozycjonowania pojedynczego elementu div na dole jego elementu nadrzędnego.

Zauważ, że użycie table-footer-groupjak inne wspomniane odpowiedzi przerwie obliczanie wysokości rodzica table.

#container {
    display: table;
    width: 100%;
    height: 200px;
}
#item {
    display: table-cell;
    vertical-align: bottom;
}
<div id="container">
    <div id="item">Single bottom item</div>
</div>


0

Według: w3schools.com

Element z pozycją: bezwzględny; jest pozycjonowany względem najbliższego pozycjonowanego przodka (zamiast pozycjonowanego względem rzutni, jak naprawiono).

Musisz więc ustawić element nadrzędny na czymś względnym lub bezwzględnym itp. I ustawić żądany element na absolutny, a następnie ustawić najniższy na 0.


Jest to już wspomniane w zaakceptowanej odpowiedzi (między innymi).
TylerH

-1

Div of style, position:absolute;bottom:5px;width:100%;działa, ale wymagało to więcej sytuacji przewijania.

window.onscroll = function() {
    var v = document.getElementById("copyright");
    v.style.position = "fixed";
    v.style.bottom = "5px";
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.