Câu hỏi Làm cho một div lấp đầy chiều cao của không gian màn hình còn lại


Tôi hiện đang làm việc trên một ứng dụng web, nơi tôi muốn nội dung để lấp đầy chiều cao của toàn bộ màn hình.

Trang có tiêu đề chứa biểu trưng và thông tin tài khoản. Đây có thể là chiều cao tùy ý. Tôi muốn div nội dung điền vào phần còn lại của trang ở phía dưới cùng.

Tôi có một tiêu đề div và một nội dung div. Hiện tại tôi đang sử dụng một bảng cho bố cục như sau:

CSS và HTML

#page {
    height: 100%; width: 100%
}

#tdcontent {
    height: 100%;
}

#content {
    overflow: auto; /* or overflow: hidden; */
}
<table id="page">
    <tr>
        <td id="tdheader">
            <div id="header">...</div>
        </td>
    </tr>
    <tr>
        <td id="tdcontent">
            <div id="content">...</div>
        </td>
    </tr>
</table>

Toàn bộ chiều cao của trang được lấp đầy và không cần phải cuộn.

Đối với bất kỳ nội dung nào trong div nội dung, cài đặt top: 0; sẽ đặt nó ngay bên dưới tiêu đề. Đôi khi nội dung sẽ là một bảng thực, với chiều cao được đặt là 100%. Đặt header phía trong content sẽ không cho phép điều này hoạt động.

Có cách nào để đạt được hiệu quả tương tự mà không sử dụng table?

Cập nhật:

Các yếu tố bên trong nội dung div cũng sẽ có chiều cao được đặt thành phần trăm. Vì vậy, một cái gì đó ở mức 100% bên trong div sẽ điền vào đáy. Như sẽ có hai yếu tố ở mức 50%.

Cập nhật 2:

Ví dụ: nếu tiêu đề chiếm 20% chiều cao của màn hình, bảng được chỉ định ở mức 50% bên trong #content sẽ chiếm 40% không gian màn hình. Cho đến nay, gói toàn bộ thứ trong một cái bàn là thứ duy nhất hoạt động.


1337
2017-09-18 05:06


gốc


Đối với bất kỳ ai vấp ngã ở đây trong tương lai, bạn có thể nhận được bố cục bảng mong muốn trong hầu hết các trình duyệt, mà không cần đánh dấu bảng, bằng cách sử dụng display:table và các thuộc tính liên quan, xem câu trả lời này cho một câu hỏi rất giống nhau. - AmeliaBR
Tôi đã cố gắng tái thiết lập lại của bạn - jsfiddle.net/ceELs - nhưng nó không hoạt động, tôi nhớ gì? - Gill Bates
@Ông. Câu trả lời của người nước ngoài rất đơn giản và hữu ích, hãy khám phá http://stackoverflow.com/a/23323175/188784 - Gohan
Trên thực tế, những gì bạn mô tả không hoạt động, ngay cả với bảng: nếu nội dung mất nhiều không gian dọc hơn chiều cao màn hình, ô bảng và toàn bộ bảng sẽ mở rộng ra phía dưới màn hình. Tràn nội dung của bạn: tự động sẽ không làm cho một thanh cuộn xuất hiện. - Damien
@GillBates nó sẽ hoạt động sau khi bạn chỉ định chiều cao của phần tử cha xem xét jsfiddle.net/ceELs/5 - Michal Vašut


Các câu trả lời:


Cập nhật 2015: cách tiếp cận flexbox

Có hai câu trả lời khác đề cập ngắn gọn flexbox; tuy nhiên, đó là cách đây hơn hai năm, và họ không cung cấp bất kỳ ví dụ nào. Các đặc điểm kỹ thuật cho flexbox đã chắc chắn giải quyết ngay bây giờ.

Lưu ý: Mặc dù CSS Flexible Boxes Layout đặc điểm kỹ thuật ở giai đoạn Đề xuất ứng viên, không phải tất cả các trình duyệt đều đã triển khai nó. Triển khai WebKit phải được bắt đầu bằng -webkit-; Internet Explorer triển khai phiên bản cũ của spec, bắt đầu bằng -ms-; Opera 12.10 triển khai phiên bản mới nhất của thông số kỹ thuật, chưa được sửa lỗi. Xem bảng tương thích trên mỗi thuộc tính để biết trạng thái tương thích cập nhật.

(được lấy từ https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes)

Tất cả các trình duyệt chính và IE11 + đều hỗ trợ Flexbox. Đối với IE 10 trở lên, bạn có thể sử dụng FlexieJS shim.

Để kiểm tra hỗ trợ hiện tại, bạn cũng có thể xem tại đây: http://caniuse.com/#feat=flexbox

Ví dụ làm việc

Với flexbox, bạn có thể dễ dàng chuyển đổi giữa bất kỳ hàng hoặc cột nào có kích thước cố định, kích thước nội dung hoặc kích thước không gian còn lại. Trong ví dụ của tôi, tôi đã đặt tiêu đề để chụp nội dung của nó (theo câu hỏi OP), tôi đã thêm chân trang để hiển thị cách thêm vùng chiều cao cố định và sau đó đặt khu vực nội dung để lấp đầy không gian còn lại.

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

.box {
  display: flex;
  flex-flow: column;
  height: 100%;
}

.box .row {
  border: 1px dotted grey;
}

.box .row.header {
  flex: 0 1 auto;
  /* The above is shorthand for:
  flex-grow: 0,
  flex-shrink: 1,
  flex-basis: auto
  */
}

.box .row.content {
  flex: 1 1 auto;
}

.box .row.footer {
  flex: 0 1 40px;
}
<!-- Obviously, you could use HTML5 tags like `header`, `footer` and `section` -->

<div class="box">
  <div class="row header">
    <p><b>header</b>
      <br />
      <br />(sized to content)</p>
  </div>
  <div class="row content">
    <p>
      <b>content</b>
      (fills remaining space)
    </p>
  </div>
  <div class="row footer">
    <p><b>footer</b> (fixed height)</p>
  </div>
</div>

Trong CSS ở trên, uốn cong tài sản viết tắt uốn cong, uốn congcơ sở flex tài sản để thiết lập sự linh hoạt của các mặt hàng flex. Mozilla có một giới thiệu tốt về mô hình hộp linh hoạt.


668
2017-07-27 08:14



Tại sao flex: 0 1 30px; thuộc tính trong box .row vì nó ghi đè lên mỗi div? - Erdal G.
Dưới đây là trình duyệt hỗ trợ cho flexbox - tốt đẹp để xem tất cả những màu xanh lá cây - caniuse.com/#feat=flexbox - Brian Burns
Chắc chắn nó là một cách tiếp cận rất tốt và nó gần như làm việc;) Có một vấn đề nhỏ khi một nội dung của div.content vượt quá chiều cao flex-ed ban đầu. Trong thực hiện hiện tại, "footer" sẽ được đẩy thấp hơn và đây không phải là những gì các nhà phát triển mong đợi;) Vì vậy, tôi đã thực hiện một sửa chữa rất dễ dàng. jsfiddle.net/przemcio/xLhLuzf9/3 Tôi thêm flex bổ sung vào container và cuộn tràn. - przemcio
@przemcio điểm tốt đẹp, nhưng tôi không nghĩ rằng có nội dung cuộn là những gì mọi nhà phát triển mong đợi;) - bạn chỉ nên thêm overflow-y: auto đến .row.content để đạt được những gì bạn cần. - Pebbl
Dường như làm việc nếu bạn đặt 100vh trên .box. - Steve Bennett


Có thực sự không phải là một âm thanh, qua trình duyệt cách để làm điều này trong CSS. Giả sử bố cục của bạn có độ phức tạp, bạn cần sử dụng JavaScript để đặt chiều cao của phần tử. Bản chất của những gì bạn cần làm là:

Element Height = Viewport height - element.offset.top - desired bottom margin

Một khi bạn có thể nhận được giá trị này và thiết lập chiều cao của phần tử, bạn cần phải gắn trình xử lý sự kiện cho cả tải cửa sổ và onresize để bạn có thể kích hoạt chức năng thay đổi kích thước của bạn.

Ngoài ra, giả sử nội dung của bạn có thể lớn hơn khung nhìn, bạn sẽ cần phải đặt overflow-y để cuộn.


207
2017-09-18 08:16



Đó là những gì tôi nghi ngờ. Tuy nhiên, ứng dụng cũng sẽ hoạt động với Javascript bị tắt, vì vậy tôi đoán tôi sẽ tiếp tục sử dụng bảng. - Vincent McNabb
Vincent, cách để đứng trên mặt đất của bạn. Tôi đã tìm cách để làm điều tương tự và nó xuất hiện không thể với css? Tôi không chắc chắn nhưng bất kể không có tấn khác của giải pháp làm những gì bạn đã mô tả. Javascript là một trong những chỉ hoạt động chính xác vào thời điểm này. - Travis
nếu thay đổi chiều cao cửa sổ - Techsin
@Techsin sử dụng jquery hoặc thích để liên kết với sự kiện thay đổi kích thước cửa sổ: $ (window) .bind ('resize orientationchange', doResize); - Emeka
Ý tôi là ... tại sao chúng ta không dùng calc vào năm 2013? - kamii


Bài viết gốc cách đây hơn 3 năm. Tôi đoán nhiều người đến bài đăng này như tôi đang tìm kiếm giải pháp bố cục giống ứng dụng, nói nội dung đầu trang, chân trang và nội dung chiều cao đầy đủ cố định chiếm phần còn lại của màn hình. Nếu vậy, bài đăng này có thể hữu ích, nó hoạt động trên IE7 +, v.v.

http://blog.stevensanderson.com/2011/10/05/full-height-app-layouts-a-css-trick-to-make-it-easier/

Và đây là một số đoạn trích từ bài đăng đó:

@media screen { 
  
  /* start of screen rules. */ 
  
  /* Generic pane rules */
  body { margin: 0 }
  .row, .col { overflow: hidden; position: absolute; }
  .row { left: 0; right: 0; }
  .col { top: 0; bottom: 0; }
  .scroll-x { overflow-x: auto; }
  .scroll-y { overflow-y: auto; }

  .header.row { height: 75px; top: 0; }
  .body.row { top: 75px; bottom: 50px; }
  .footer.row { height: 50px; bottom: 0; }
  
  /* end of screen rules. */ 
}
<div class="header row" style="background:yellow;">
    <h2>My header</h2>
</div> 
<div class="body row scroll-y" style="background:lightblue;">
    <p>The body</p>
</div> 
<div class="footer row" style="background:#e9e9e9;">
    My footer
</div>


153
2017-10-21 15:02



Chỉ có một vấn đề với điều này: đầu trang và chân trang không tự động kích thước. Cái đó là khó khăn thực sự, và cái đó là lý do tại sao câu trả lời "không thể thực hiện" này hiện đang ở trên cùng ... - Roman Starkov
Ngay cả khi nó không phải là một giải pháp cho vấn đề ban đầu, điều này đã giúp tôi - vì vậy cảm ơn bạn anyway :) - Luke Sampson
Tôi cần một tiêu đề 55px và một div lấp đầy phần còn lại của chiều cao của tài liệu. đây là giải pháp! - Matías Cánepa
Bạn là bom, tôi đã cố gắng này quá lâu và đây là giải pháp duy nhất tôi tìm thấy. Tôi cần phần tử nav của tôi có chiều cao 60px ở phía trên và phần còn lại là khoảng 100%, điều này đã giải quyết được nó. - Adam Waite
.col không được sử dụng, phải không? - slartidan


Thay vì sử dụng các bảng trong đánh dấu, bạn có thể sử dụng các bảng CSS.

Đánh dấu

<body>    
    <div>hello </div>
    <div>there</div>
</body>

CSS (có liên quan)

body
{
    display:table;
    width:100%;
}
div
{
    display:table-row;
}
div+ div
{
    height:100%;  
}

FIDDLE1 và FIDDLE2

Một số ưu điểm của phương pháp này là:

1) Ít đánh dấu hơn

2) Đánh dấu là ngữ nghĩa hơn bảng, vì đây không phải là dữ liệu dạng bảng.

3) Hỗ trợ trình duyệt là rất tốt: IE8 +, Tất cả các trình duyệt và thiết bị di động hiện đại (caniuse)


Chỉ để hoàn thành, dưới đây là các phần tử Html tương đương với thuộc tính css cho Mô hình bảng CSS

table    { display: table }
tr       { display: table-row }
thead    { display: table-header-group }
tbody    { display: table-row-group }
tfoot    { display: table-footer-group }
col      { display: table-column }
colgroup { display: table-column-group }
td, th   { display: table-cell }
caption  { display: table-caption } 

134
2018-06-06 11:20



tôi đã được chỉ vào kỹ thuật của các bảng css. Hóa ra câu trả lời đã có trong câu hỏi được trả lời này. Đây là các giải pháp tốt nhất; sạch sẽ, thanh lịch và sử dụng công cụ chính xác theo cách chính xác mà nó đã được dự định. Bảng CSS - Ian Boyd
Mã fiddle không hoàn toàn khớp với câu trả lời ở đây. Đang thêm html, body { height: 100%, width: 100% } có vẻ quan trọng trong các bài kiểm tra của tôi. - mlibby
Một tính năng gây phiền nhiễu của các bảng CSS giống hệt với các bảng bình thường: Nếu nội dung quá lớn, chúng sẽ mở rộng ô để vừa. Điều này có nghĩa là bạn vẫn có thể cần giới hạn kích thước (chiều cao tối đa) hoặc đặt chiều cao từ mã nếu trang là động. Tôi thực sự nhớ lưới Silverlight! :( - Gone Coding
Bạn luôn có thể thêm một thùng chứa được định vị hoàn toàn bên trong phần tử hàng tabel sau đó thiết lập chiều rộng và chiều cao của nó thành 100%. Hãy nhớ đặt vị trí tương đối trên thành phần của hàng trong bảng. - Mike Mellor
@MikeMellor không hoạt động trong IE11 dù có vẻ như bỏ qua relative định vị trên table-row yếu tố như vậy có chiều cao của tăng trưởng vị trí đầu tiên không phải là một phần tử bảng. - Dwelle


Cách tiếp cận CSS duy nhất (Nếu chiều cao được biết / cố định)

Khi bạn muốn phần tử ở giữa trải rộng trên toàn bộ trang theo chiều dọc, bạn có thể sử dụng calc() được giới thiệu trong CSS3.

Giả sử chúng ta có một chiều cao cố định  header và footer và chúng tôi muốn section để lấy toàn bộ chiều cao dọc có sẵn ...

Bản giới thiệu

Đánh dấu giả định

<header>100px</header>
<section>Expand me for remaining space</section>
<footer>150px</footer>

Vì vậy, CSS của bạn nên

html, body {
    height: 100%;
}

header {
    height: 100px;
    background: grey;
}

section {
    height: calc(100% - (100px + 150px)); 
    /* Adding 100px of header and 150px of footer */

    background: tomato;
}

footer {
    height: 150px;
    background-color: blue;
}

Vì vậy, ở đây, những gì đang làm là, thêm chiều cao của các phần tử và hơn trừ đi từ 100% sử dụng calc() chức năng.

Chỉ cần đảm bảo rằng bạn sử dụng height: 100%; cho các phần tử cha.


76
2018-04-27 12:05



OP cho biết tiêu đề có thể là chiều cao tùy ý. Vì vậy, nếu bạn không biết chiều cao trước, bạn sẽ không thể sử dụng calc :( - Danield
@Danield Đó là lý do tôi đã đề cập chiều cao cố định :) - Mr. Alien
Đây là giải pháp làm việc cho tôi và không yêu cầu tôi phải thiết kế lại các trang hiện có của mình quanh các hộp flexbox. Nếu bạn đang sử dụng LESS, tức là Bootstrap, hãy chắc chắn và đọc coderwall đăng trên làm thế nào để thoát khỏi hàm calc () để LESS không xử lý nó. - jlyonsmith
Op nói 'Đây có thể là chiều cao tùy ý'. Tùy ý có nghĩa là quyết định của nhà thiết kế, do đó cố định. Giải pháp này là tốt nhất. - jck


Đã sử dụng: height: calc(100vh - 110px);

mã:

  
.header { height: 60px; top: 0; background-color: green}
.body {
    height: calc(100vh - 110px); /*50+60*/
    background-color: gray;
}
.footer { height: 50px; bottom: 0; }
  
<div class="header">
    <h2>My header</h2>
</div> 
<div class="body">
    <p>The body</p>
</div> 
<div class="footer">
    My footer
</div>


37
2018-05-22 03:20





Nó có thể được thực hiện hoàn toàn bằng CSS sử dụng vh:

#page 
{
  display:block; width:100%; height:95vh !important; overflow:hidden;
}
#tdcontent 
{
  float:left; width:100%; display:block;
}
#content 
{      
float:left; width:100%; height:100%; display:block; overflow:scroll;
}

HTML

<div id="page">
   <div id="tdcontent">
   </div>
   <div id="content">
   </div>
</div>

Tôi đã kiểm tra nó, Nó hoạt động trong tất cả các trình duyệt chính: Chrome, IEFireFox


24
2017-09-14 21:09



Wow, chưa bao giờ nghe nói về vh và vw đơn vị trước. Thêm thông tin: snook.ca/archives/html_and_css/vm-vh-units - Steve Bennett
Ahh, mỗi ngày là học tập, Cảm ơn VH và Vw @ormoz - Shekhar Pankaj
Thật không may, điều này không hỗ trợ IE8: ( - Scott
Tôi đã thử cách tiếp cận này, nhưng height: 100% trên #content gây ra chiều cao của nó để phù hợp với chiều cao của #page, bỏ qua #tdcontent's chiều cao hoàn toàn. Với nhiều nội dung, thanh cuộn mở rộng ra phía dưới trang. - Brandon Mintern


Không có giải pháp nào được đăng khi bạn cần div phía dưới để cuộn khi nội dung quá cao. Đây là một giải pháp hoạt động trong trường hợp đó:

HTML:

<div class="table container">
  <div class="table-row header">
    <div>This is the header whose height is unknown</div>
    <div>This is the header whose height is unknown</div>
    <div>This is the header whose height is unknown</div>
  </div>
  <div class="table-row body">
    <div class="table-cell body-content-outer-wrapper">
      <div class="body-content-inner-wrapper">
        <div class="body-content">
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
          <div>This is the scrollable content whose height is unknown</div>
        </div>
      </div>
    </div>
  </div>
</div>

CSS:

.table {
  display: table;
}
.table-row {
  display: table-row;
}
.table-cell {
  display: table-cell;
}
.container {
  width: 400px;
  height: 300px;
}
.header {
  background: cyan;
}
.body {
  background: yellow;
  height: 100%;
}
.body-content-outer-wrapper {
  height: 100%;
}
.body-content-inner-wrapper {
  height: 100%;
  position: relative;
  overflow: auto;
}
.body-content {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

Nguồn gốc: Điền chiều cao còn lại của vùng chứa trong khi xử lý tràn trong CSS

Xem trước trực tiếp JSFiddle


22
2018-02-20 17:12



Cảm ơn bạn!!! Tôi đã thử tất cả các câu trả lời không phải bảng, không có flexbox và đây là câu trả lời chính xác duy nhất 100%. Một câu hỏi: nguồn gốc chỉ có một body-content-wrappervà mọi thứ dường như chỉ hoạt động tốt mà không có trình bao bọc kép (không có bất kỳ table-cellS). Có vấn đề gì với việc làm theo cách đó không? - Brandon Mintern
@BrandonMintern Nếu bạn không có các ô bảng, nó không hoạt động trong IE8 và IE9. (Xem bình luận trong bài viết gốc.) - John Kurlak
Đúng, các tế bào cũng được yêu cầu trong IE10. Thật không may, trong IE10 và dưới, .body chiều cao kết thúc bằng chiều cao tương tự như thiết lập trên .container. Thanh cuộn dọc vẫn ở đúng vị trí, nhưng .container kết thúc lên nhận được kéo dài lớn hơn chúng tôi muốn. Khi toàn màn hình, phần dưới cùng của .body ở dưới cùng của màn hình. - Brandon Mintern