Chân trang ở cuối trang hoặc nội dung, tùy theo giá trị nào thấp hơn


92

Tôi có cấu trúc sau:

<body>
    <div id="main-wrapper">
        <header>
        </header>
        <nav>
        </nav>
        <article>
        </article>
        <footer>
        </footer>
    </div>
</body>

Tôi tự động tải nội dung <article>bằng javascript. Do đó, chiều cao của <article>khối có thể thay đổi.

Tôi muốn <footer>khối ở cuối trang khi có nhiều nội dung hoặc ở cuối cửa sổ trình duyệt khi chỉ tồn tại một vài dòng nội dung.

Hiện tại tôi có thể làm cách này hay cách khác ... nhưng không phải cả hai.

Vì vậy, có ai biết làm thế nào tôi có thể làm điều này - nhận được <footer>để dính vào cuối trang / nội dung hoặc cuối màn hình, tùy thuộc vào cái nào thấp hơn.


Mọi người có muốn bình luận về lý do tại sao họ bỏ phiếu từ chối câu hỏi 2 tuổi không?
Will

Cố lên, đã gần 6 năm ...
Sẽ

Câu trả lời:


99

Chân trang dính của Ryan Fait rất đẹp, tuy nhiên tôi thấy cấu trúc cơ bản của nó còn thiếu *.


Phiên bản Flexbox

Nếu bạn đủ may mắn để có thể sử dụng flexbox mà không cần hỗ trợ các trình duyệt cũ hơn, các chân trang dính trở nên dễ dàng một cách đáng kể hỗ trợ chân trang có kích thước động.

Mẹo để làm cho chân trang dính vào phía dưới với flexbox là để các phần tử khác trong cùng một container uốn cong theo chiều dọc. Tất cả những gì cần là một phần tử bao bọc có chiều cao đầy đủ với display: flexvà ít nhất một anh chị em có flexgiá trị lớn hơn 0:

CSS:
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#main-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

article {
  flex: 1;
}


Nếu bạn không thể sử dụng flexbox, cấu trúc cơ bản mà tôi lựa chọn là:

<div class="page">
  <div class="page__inner">
    <header class="header">
      <div class="header__inner">
      </div>
    </header>
    <nav class="nav">
      <div class="nav__inner">
      </div>
    </nav>
    <main class="wrapper">
      <div class="wrapper__inner">
        <div class="content">
          <div class="content__inner">
          </div>
        </div>
        <div class="sidebar">
          <div class="sidebar__inner">
          </div>
        </div>
      </div>
    </main>
    <footer class="footer">
      <div class="footer__inner">
      </div>
    </footer>
  </div>
</div>

Đó không phải là tất cả xa so với:

<div id="main-wrapper">
    <header>
    </header>
    <nav>
    </nav>
    <article>
    </article>
    <footer>
    </footer>
</div>

Mẹo để giữ chân trang là giữ cho chân trang được neo vào phần đệm dưới cùng của phần tử chứa nó. Điều này yêu cầu chiều cao của chân trang là tĩnh, nhưng tôi nhận thấy rằng chân trang thường có chiều cao tĩnh.

HTML:
<div id="main-wrapper">
    ...
    <footer>
    </footer>
</div>
CSS:
#main-wrapper {
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

Với chân trang được neo vào #main-wrapper, bây giờ bạn cần #main-wrapperphải có chiều cao ít nhất của trang, trừ khi phần con của nó dài hơn. Này được thực hiện bằng cách làm cho #main-wrappercó một min-heightsố 100%. Bạn cũng phải nhớ rằng cha mẹ của nó, htmlbodycần phải cao như trang.

CSS:
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#main-wrapper {
    min-height: 100%;
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

Tất nhiên, bạn nên đặt câu hỏi về nhận định của tôi, vì đoạn mã này buộc phần chân trang nằm ở cuối trang, ngay cả khi không có nội dung. Bí quyết cuối cùng là thay đổi mô hình hộp được sử dụng bởi các #main-wrappersao cho min-heightcủa 100%bao gồm 100pxpadding.

CSS:
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#main-wrapper {
    box-sizing: border-box;
    min-height: 100%;
    padding: 0 0 100px;
    position: relative;
}

footer {
    bottom: 0;
    height: 100px;
    left: 0;
    position: absolute;
    width: 100%;
}

Và bạn đã có nó, một footer dính với cấu trúc HTML ban đầu của bạn. Chỉ cần đảm bảo rằng footer's heightbằng với #main-wrapper' padding-bottomvà bạn sẽ được đặt.


* Lý do tôi thấy lỗi với cấu trúc của Fait là vì nó đặt các phần tử .footer.headerở các mức phân cấp khác nhau trong khi thêm một .pushphần tử không cần thiết .


Tôi cần phải thêm #main-wrapper *:first-child { margin-top: 0; }, nếu không trang sẽ quá dài so với lề trên của trang đầu tiên (gây ra một thanh cuộn không cần thiết trên các trang ngắn).
Florian Brucker

Cảm ơn bạn, @zzzzBov cho lời giải thích thấu đáo này, và đặc biệt đề cập đến flex-hướng (muốn tôi muốn thấy điều này sớm hơn - có thể đã cứu tôi một vài giờ :)!
ea0723

Phiên bản Flexbox không hoạt động với tôi trong IE11, nhưng cách tiếp cận khác phù hợp với tôi! Cảm ơn và +1!
Matt,

@Matt, bạn cần sử dụng tiền tố trình duyệt để flexbox hoạt động trong IE11. sử dụng một công cụ như autoprefixer và bạn sẽ không bao giờ phải lo lắng về việc thêm chúng theo cách thủ công.
zzzzBov

2
Liên kết chân trang dính dường như bị hỏng do trang web của anh ấy được chuyển đổi thành thông báo Trong bản ghi nhớ cho anh ấy. Bên cạnh đó, không có phiên bản cache do sự thiết lập của robots.txt
tzrlk

13

Chân trang dính của Ryan Fait là một giải pháp đơn giản mà tôi đã sử dụng nhiều lần trong quá khứ.

HTML cơ bản :

<div class="wrapper">
    <div class="header">
        <h1>CSS Sticky Footer</h1>
    </div>
    <div class="content"></div>
    <div class="push"></div>
</div>
<div class="footer"></div>

CSS :

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
.footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

/*

Sticky Footer by Ryan Fait
http://ryanfait.com/

*/

Dịch điều này tương tự với những gì bạn đã có kết quả với một cái gì đó dọc theo những dòng sau:

HTML :

<body>
    <div class="wrapper">
        <header>
        </header>
        <nav>
        </nav>
        <article>
        </article>
        <div class="push"></div>
    </div>
    <footer>
    </footer>
</body>

CSS:

* {
    margin: 0;
}
html, body {
    height: 100%;
}
.wrapper {
    min-height: 100%;
    height: auto !important;
    height: 100%;
    margin: 0 auto -142px; /* the bottom margin is the negative value of the footer's height */
}
footer, .push {
    height: 142px; /* .push must be the same height as .footer */
}

Chỉ cần đừng quên cập nhật âm trên lề của trình bao bọc để khớp với chiều cao của footer và push div. Chúc may mắn!


4
Tôi thích cách ông đặt comment ở phía dưới, thích hợp cho một giải pháp footer: D
ma của Madara

Không cần phải thay đổi đánh dấu cho kiểu cụ thể này.
zzzzBov

@zzzzBov Tôi không có nhiều thời gian để xem xét thêm vấn đề này ngay bây giờ, nhưng chính xác thì ý bạn là gì?
Josh Mein

Tôi đang sử dụng máy ATM di động của mình nên tôi không thể viết câu trả lời đầy đủ nếu không thì tôi đã làm được rồi. Nhận xét nhiều hơn nên tôi nhớ thêm câu trả lời sau.
zzzzBov

@JoshMein, tôi đã thêm một câu trả lời giải thích cách làm cho footer dính mà không làm sai cấu trúc được cung cấp.
zzzzBov

0

Tôi đang tìm cách giải quyết vấn đề này mà không cần thêm bất kỳ đánh dấu bổ sung nào, vì vậy tôi đã sử dụng giải pháp sau:

article {
  min-height: calc(100vh - 150px); /* deduct the height or margins of any other elements within wrapping container*/
}

footer {
  height: 50px;
}

header {
   height: 50px;
}

nav {
  height: 50px;
}
<body>
  <div id="main-wrapper">
    <header>
    </header>
    <nav>
    </nav>
    <article>
    </article>
    <footer>
    </footer>
  </div>
</body>

Bạn phải biết chiều cao của header, nav và footer để có thể đặt chiều cao tối thiểu cho bài viết. Bằng cách này, nếu bài viết chỉ có vài dòng nội dung, footer sẽ nằm ở cuối cửa sổ trình duyệt, nếu không nó sẽ nằm bên dưới tất cả nội dung.

Bạn có thể tìm thấy giải pháp này và các giải pháp khác được đăng ở trên tại đây: https://css-tricks.com/couple-takes-sticky-footer/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.