Mở rộng một div để điền vào chiều rộng còn lại


552

Tôi muốn bố trí div hai cột, trong đó mỗi cái có thể có chiều rộng thay đổi, vd

div {
  float: left;
}

.second {
  background: #ccc;
}
<div>Tree</div>
<div class="second">View</div>

Tôi muốn div 'view' mở rộng ra toàn bộ chiều rộng có sẵn sau khi div 'cây' đã lấp đầy không gian cần thiết.

Hiện tại, div 'view' của tôi được thay đổi kích thước thành nội dung có chứa Nó cũng sẽ tốt nếu cả hai div chiếm toàn bộ chiều cao.


Không từ chối trách nhiệm:



1
Hoặc tôi không hiểu câu hỏi hoặc tôi không hiểu cách bạn chọn câu trả lời được chấp nhận, bởi vì cả chiều rộng và chiều cao đều được khắc phục với sự bất tiện củaoverflow hidden
user10089632

Câu trả lời:


1013

Các giải pháp này thực sự là rất dễ dàng, nhưng không phải ở tất cả rõ ràng. Bạn phải kích hoạt một thứ gọi là "bối cảnh định dạng khối" (BFC), tương tác với các float theo một cách cụ thể.

Chỉ cần lấy div thứ hai, loại bỏ float và overflow:hiddenthay vào đó. Bất kỳ giá trị tràn nào khác ngoài khả năng hiển thị sẽ khiến khối được đặt trở thành BFC. BFC không cho phép phao con cháu thoát khỏi chúng, chúng cũng không cho phép phao anh chị em / tổ tiên xâm nhập vào chúng. Hiệu ứng ròng ở đây là div nổi sẽ làm việc của nó, sau đó div thứ hai sẽ là một khối bình thường, chiếm tất cả chiều rộng có sẵn ngoại trừ chiếm chỗ của float .

Điều này sẽ hoạt động trên tất cả các trình duyệt hiện tại, mặc dù bạn có thể phải kích hoạt hasLayout trong IE6 và 7. Tôi không thể nhớ lại.

Bản trình diễn:


28
Câu trả lời tuyệt vời! Nhưng bạn đã sai khi bạn nói "bất kỳ giá trị tràn nào khác ngoài tự động" sẽ biến nó thành BFC. Ý bạn là bất kỳ giá trị tràn nào khác ngoài giá trị mặc định (hiển thị) sẽ biến nó thành BFC. Trên thực tế, tự động tràn cũng hoạt động hoàn hảo - đó là những gì tôi khuyên dùng (chỉ trong trường hợp bạn có các yếu tố tương đối có vị trí có thể ló ra khỏi div đó).
BT

52
Bài viết này có một lời giải thích hay: colinaarts.com/articles/the-magic-of-overflow-hidden
Max Cantor

1
Điều gì nếu nội dung đủ lớn để tràn div?
gianni christofakis

11
Điều quan trọng cần lưu ý là thứ tự của trẻ em có vấn đề. Phần tử nổi có chiều rộng cố định phải ở trên phần tử kia. Mất quá nhiều thời gian để tìm ra lý do tại sao nó không hoạt động với tôi với thứ tự chuyển đổi.
Riplexus

2
Tôi đã viết một câu trả lời giải thích tại sao một dòng chảy không thể nhìn thấy của tất cả mọi thứ kích hoạt BFC, dựa trên các phản hồi được đưa ra bởi David và Boris, có thể tìm thấy ở đây: stackoverflow.com/questions/9943503/ .
BoltClock

104

Tôi mới phát hiện ra sự kỳ diệu của hộp flex (display: flex). Thử cái này:

<style>
  #box {
    display: flex;
  }
  #b {
    flex-grow: 100;
    border: 1px solid green;
  }
</style>
<div id='box'>
 <div id='a'>Tree</div>
 <div id='b'>View</div>
</div>

Hộp Flex cho tôi quyền kiểm soát mà tôi muốn css có trong 15 năm. Cuối cùng cũng đến rồi! Thông tin thêm: https://css-tricks.com/snippets/css/a-guide-to-flexbox/


Tôi không biết những gì bạn đã khám phá, nhưng mã của bạn không hoạt động trong Chrome mới nhất jsfiddle.net/fjb548kw/3
Yevgeniy Afanasyev

@YevgeniyAfanasyev Tôi đã xóa "float: left;" để khắc phục sự cố. Cảm ơn bạn đã lưu ý!
BT

Cảm ơn bạn. Bạn có thể vui lòng giải thích tại sao bạn có flex-grow: 100;thay vì flex-grow: 1;?
Yevgeniy Afanasyev

2
@YevgeniyAfanasyev Không có lý do cụ thể nào ngoại trừ đó là cách tôi thích làm điều đó. Nó cho phép tôi suy nghĩ theo phần trăm vì vậy nếu tôi có thể làm điều gì đó như đặt #a thành flex-grow:10và sau đó tôi sẽ đặt #b thành flex-grow: 90#a sẽ là 10% chiều rộng của dòng và #b sẽ là 90% chiều rộng của dòng. Nếu không có yếu tố nào khác có kiểu chiều rộng flex, thì về mặt kỹ thuật bạn không đặt vấn đề gì.
BT

điều này làm việc tốt nhất với tôi, cố gắng đặt đầu vào và nút cạnh nhau như thể chúng là một.
Souleste

28

Giải pháp Flexbox

Đây là những gì flex-growtài sản là dành cho.

html, body {
  height: 100%;
}
body {
  display: flex;
}
.second {
  flex-grow: 1;
}
<div style="background: #bef;">Tree</div>
<div class="second" style="background: #ff9;">View</div>

Lưu ý: Thêm tiền tố nhà cung cấp flex nếu các trình duyệt được hỗ trợ của bạn yêu cầu .


27

Đây sẽ là một ví dụ tốt về một cái gì đó tầm thường để làm với các bảng và khó (nếu không phải là không thể, ít nhất là theo nghĩa trình duyệt chéo) để làm với CSS.

Nếu cả hai cột có chiều rộng cố định, điều này sẽ dễ dàng.

Nếu một trong các cột có chiều rộng cố định, điều này sẽ khó hơn một chút nhưng hoàn toàn có thể thực hiện được.

Với cả hai chiều rộng của cột, IMHO bạn chỉ cần sử dụng bảng hai cột.


11
Bảng sẽ không được tốt trong một thiết kế đáp ứng khi bạn muốn cột bên phải trượt bên trái trên các thiết bị nhỏ.
S ..

1
Có một số thủ thuật thiết kế đáp ứng để làm việc với các bảng: css-tricks.com/responsive-data-tables
Rikki

Bây giờ tôi có xu hướng thường thiết kế hoàn toàn hai bố cục riêng biệt và thay đổi trên điện thoại di động bằng các truy vấn phương tiện và trong display:none;khi thực hiện phản hồi 100% nhất có thể trên thang trượt đôi khi thay đổi hoàn toàn thiết kế của bạn để sử dụng cảm ứng trên màn hình cảm ứng và kiểu nút.
Bysander

22

Kiểm tra giải pháp này

.container {
  width: 100%;
  height: 200px;
  background-color: green;
}
.sidebar {
  float: left;
  width: 200px;
  height: 200px;
  background-color: yellow;
}
.content {
  background-color: red;
  height: 200px;
  width: auto;
  margin-left: 200px;
}
.item {
  width: 25%;
  background-color: blue;
  float: left;
  color: white;
}
.clearfix {
  clear: both;
}
<div class="container">
  <div class="clearfix"></div>
  <div class="sidebar">width: 200px</div>

  <div class="content">
    <div class="item">25%</div>
    <div class="item">25%</div>
    <div class="item">25%</div>
    <div class="item">25%</div>
  </div>
</div>


2
Đây thường là một giải pháp ưu việt bởi vì ẩn không phải lúc nào cũng mong muốn.
Joseph Lennox

3
Mỗi OP: "Tôi muốn bố trí div hai cột, trong đó mỗi cột có thể có chiều rộng thay đổi". Trong câu trả lời của bạn, bạn phải biết chiều rộng của cột đầu tiên, vì vậy nó không thay đổi. Bạn cũng có thể đặt chiều rộng cố định trên cả hai cột và chỉ nổi chúng.
Jacob Alvarez

17

Sử dụng calc:

.leftSide {
  float: left;
  width: 50px;
  background-color: green;
}
.rightSide {
  float: left;
  width: calc(100% - 50px);
  background-color: red;
}
<div style="width:200px">
  <div class="leftSide">a</div>
  <div class="rightSide">b</div>
</div>

Vấn đề với điều này là tất cả các chiều rộng phải được xác định rõ ràng, như là một giá trị (px và em hoạt động tốt) hoặc là một phần trăm của một cái gì đó được xác định rõ ràng.


15

Ở đây, điều này có thể giúp ...

<html>

<head>
  <style type="text/css">
    div.box {
      background: #EEE;
      height: 100px;
      width: 500px;
    }
    div.left {
      background: #999;
      float: left;
      height: 100%;
      width: auto;
    }
    div.right {
      background: #666;
      height: 100%;
    }
    div.clear {
      clear: both;
      height: 1px;
      overflow: hidden;
      font-size: 0pt;
      margin-top: -1px;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="left">Tree</div>
    <div class="right">View</div>
    <div class="clear" />
  </div>
</body>

</html>


+1 vì ví dụ của bạn có vẻ hoạt động, nhưng trong kịch bản thực tế của tôi, một số nội dung từ 'view' leo vào 'cây', vì div cây không phải là 100%, có thể một số javascript buộc nó phải nhỏ và sau chiều cao của cây Tôi thấy nội dung xem
Anurag Uniyal

Trong trường hợp đó, nếu bạn biết chiều rộng tối đa của cột bên trái, bạn có thể cung cấp cho nó độ rộng tối đa kiểu (không hoạt động trong IE) hoặc nghĩ về lề trái (hãy cẩn thận với lỗi lề kép trên IE) hoặc đệm-trái.
a6hi5h3k

Điều này thật tuyệt! Tôi đang sử dụng nó trực tuyến như một giải pháp một lần:<div class="clear" style="clear: both; height: 1px; overflow: hidden; font-size:0pt; margin-top: -1px;"></div>
ajwest 10/03/2015

5

Tôi không hiểu tại sao mọi người sẵn sàng làm việc chăm chỉ để tìm giải pháp CSS thuần cho bố cục cột đơn giản mà DỄ DÀNG bằng cách sử dụng TABLEthẻ cũ .

Tất cả các Trình duyệt vẫn có logic bố trí bảng ... Có thể gọi tôi là một con khủng long, nhưng tôi nói hãy để nó giúp bạn.

<table WIDTH=100% border=0 cellspacing=0 cellpadding=2>
  <tr>
    <td WIDTH="1" NOWRAP bgcolor="#E0E0E0">Tree</td>
    <td bgcolor="#F0F0F0">View</td>
  </tr>
</table>

Ít rủi ro hơn nhiều về khả năng tương thích trình duyệt chéo.


2
có, nhưng nếu mọi thứ đang được thực hiện bởi css tại sao không phải điều này, ít nhất là một sự tò mò nếu nó là sở hữu?
Anurag Uniyal

2
Đó là bởi vì nếu bạn muốn đặt media-queriesđể đặt cả hai cột lên nhau trong các thiết bị nhỏ, điều đó là không thể đối với tablethẻ cũ . Để làm việc này, bạn cần áp dụng các CSSkiểu bảng. Vì vậy, hiện nay tốt hơn là giải quyết vấn đề này CSSnếu bạn muốn bố trí đáp ứng cho bất kỳ kích thước màn hình nào.
ElChiniNet

5

Nếu chiều rộng của cột khác là cố định, làm thế nào về việc sử dụng calcchức năng CSS hoạt động cho tất cả các trình duyệt phổ biến :

width: calc(100% - 20px) /* 20px being the first column's width */

Bằng cách này, chiều rộng của hàng thứ hai sẽ được tính toán (tức là chiều rộng còn lại) và được áp dụng một cách đáp ứng.


Đây là câu trả lời tốt nhất khi sử dụng bất cứ thứ gì khác ngoài flexbox, chẳng hạn như , css-grid. Cũng làm việc với position: fixednó làm cho tất cả xung quanh sự lựa chọn hoàn hảo! Cảm ơn bạn!
Bartekus

3

<html>

<head>
  <style type="text/css">
    div.box {
      background: #EEE;
      height: 100px;
      width: 500px;
    }
    div.left {
      background: #999;
      float: left;
      height: 100%;
      width: auto;
    }
    div.right {
      background: #666;
      height: 100%;
    }
    div.clear {
      clear: both;
      height: 1px;
      overflow: hidden;
      font-size: 0pt;
      margin-top: -1px;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="left">Tree</div>
    <div class="right">View</div>
    <div class="right">View</div>
    <div style="width: <=100% getTreeWidth()100 %>">Tree</div>
    <div class="clear" />
  </div>
  <div class="ColumnWrapper">
    <div class="Colum­nOne­Half">Tree</div>
    <div class="Colum­nOne­Half">View</div>
  </div>

</body>

</html>


Tôi muốn một cái gì đó giống như một thanh trạng thái với các mục cố định ở bên trái, các mục cố định ở bên phải và một dòng thông báo sử dụng tất cả các không gian bên trái. Tôi đã bắt đầu với câu trả lời này và thêm thông điệp div SAU KHI nổi với: height: 20px; khoảng trắng: nowrap; tràn: ẩn; tràn văn bản: clip
englebart

3

Bạn có thể thử CSS Grid Layout .

dl {
  display: grid;
  grid-template-columns: max-content auto;
}

dt {
  grid-column: 1;
}

dd {
  grid-column: 2;
  margin: 0;
  background-color: #ccc;
}
<dl>
  <dt>lorem ipsum</dt>
  <dd>dolor sit amet</dd>
  <dt>carpe</dt>
  <dd>diem</dd>
</dl>


2

flex-grow - Điều này xác định khả năng cho một vật phẩm flex phát triển nếu cần thiết. Nó chấp nhận một giá trị đơn vị phục vụ như là một tỷ lệ. Nó chỉ ra lượng không gian có sẵn bên trong thùng chứa flex mà vật phẩm sẽ chiếm.

Nếu tất cả các mục có flex-grow được đặt thành 1, không gian còn lại trong thùng chứa sẽ được phân phối đều cho tất cả trẻ em. Nếu một trong những đứa trẻ có giá trị là 2, thì không gian còn lại sẽ chiếm gấp đôi không gian so với những đứa trẻ khác (hoặc ít nhất là nó sẽ cố gắng). Xem thêm tại đây

.parent {
  display: flex;
}

.child {
  flex-grow: 1; // It accepts a unitless value that serves as a proportion
}

.left {
  background: red;
}

.right {
  background: green;
}
<div class="parent"> 
  <div class="child left">
      Left 50%
  </div>
   <div class="child right">
      Right 50%
  </div>
</div>



1

Pat - Bạn nói đúng. Đó là lý do tại sao giải pháp này sẽ làm hài lòng cả "khủng long" và người đương thời. :)

.btnCont {
  display: table-layout;
  width: 500px;
}

.txtCont {
  display: table-cell;
  width: 70%;
  max-width: 80%;
  min-width: 20%;
}

.subCont {
  display: table-cell;
  width: 30%;
  max-width: 80%;
  min-width: 20%;
}
<div class="btnCont">
  <div class="txtCont">
    Long text that will auto adjust as it grows. The best part is that the width of the container would not go beyond 500px!
  </div>
  <div class="subCont">
    This column as well as the entire container works like a table. Isn't Amazing!!!
  </div>
</div>


2
Không có tài liệu tham khảo html nào cho lớp css .ip và nó không hoạt động trong IE7
Keith K

1

Bạn có thể sử dụng thư viện CSS của W3 có chứa một lớp được gọi là rest:

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

<div class="w3-row">
  <div class="w3-col " style="width:150px">
    <p>150px</p>
  </div>
  <div class="w3-rest w3-green">
    <p>w3-rest</p>
  </div>
</div>

Đừng quên liên kết thư viện CSS trong trang header:

<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">

Đây là bản demo chính thức: W3 School Tryit Editor


Có vẻ như chỉ thêm "tràn: ẩn", khiến nó trở thành phiên bản tồi tệ hơn của câu trả lời đã được đưa ra
vpzomtrrfrt

0

Tôi không chắc đây có phải là câu trả lời mà bạn đang mong đợi không, nhưng tại sao bạn không đặt chiều rộng của Cây thành 'tự động' và chiều rộng của 'Xem' thành 100%?


3
Bởi vì điều đó sẽ đặt phao thứ hai xuống dưới phao thứ nhất vì nó quá rộng.
cletus

0

Có một cái nhìn vào các khung bố trí CSS có sẵn. Tôi muốn giới thiệu Đơn giản hoặc, khung Blueprint phức tạp hơn một chút.

Nếu bạn đang sử dụng Simpl (liên quan đến việc nhập chỉ một tệp Simpl.css ), bạn có thể thực hiện việc này:

<div class="Colum­nOne­Half">Tree</div>
<div class="Colum­nOne­Half">View</div>

, cho bố cục 50-50, hoặc:

<div class="Colum­nOne­Quarter">Tree</div>
<div class="Colum­nThreeQuarters">View</div>

, cho một 25-75.

Nó đơn giản mà.


cả hai cột sẽ có chiều rộng thay đổi?
Anurag Uniyal

0

Cảm ơn bạn đã cắm Simpl.css!

nhớ bọc tất cả các cột của bạn ColumnWrappernhư vậy.

<div class="ColumnWrapper">
    <div class="Colum­nOne­Half">Tree</div>
    <div class="Colum­nOne­Half">View</div>
</div>

Tôi sắp phát hành phiên bản 1.0 của Simpl.css để giúp quảng bá!


0

Tôi đã viết một hàm javascript mà tôi gọi từ jQuery $ (tài liệu). Đã (). Điều này sẽ phân tích tất cả con của div cha mẹ và chỉ cập nhật đúng con nhất.

html

...
<div class="stretch">
<div style="padding-left: 5px; padding-right: 5px; display: inline-block;">Some text
</div>
<div class="underline" style="display: inline-block;">Some other text
</div>
</div>
....

javascript

$(document).ready(function(){
    stretchDivs();
});

function stretchDivs() {
    // loop thru each <div> that has class='stretch'
    $("div.stretch").each(function(){
        // get the inner width of this <div> that has class='stretch'
        var totalW = parseInt($(this).css("width"));
        // loop thru each child node
        $(this).children().each(function(){
            // subtract the margins, borders and padding
            totalW -= (parseInt($(this).css("margin-left")) 
                     + parseInt($(this).css("border-left-width")) 
                     + parseInt($(this).css("padding-left"))
                     + parseInt($(this).css("margin-right")) 
                     + parseInt($(this).css("border-right-width")) 
                     + parseInt($(this).css("padding-right")));
            // if this is the last child, we can set its width
            if ($(this).is(":last-child")) {
                $(this).css("width","" + (totalW - 1 /* fudge factor */) + "px");
            } else {
                // this is not the last child, so subtract its width too
                totalW -= parseInt($(this).css("width"));
            }
        });
    });
}

0

Điều này khá dễ dàng bằng cách sử dụng flexbox. Xem đoạn trích dưới đây. Tôi đã thêm một thùng chứa trình bao bọc để kiểm soát lưu lượng và đặt chiều cao toàn cầu. Biên giới đã được thêm vào để xác định các yếu tố. Lưu ý rằng div bây giờ cũng mở rộng đến chiều cao đầy đủ, theo yêu cầu. Tiền tố của nhà cung cấp nên được sử dụng cho flexbox trong kịch bản thế giới thực do chưa được hỗ trợ đầy đủ.

Tôi đã phát triển một công cụ miễn phí để hiểu và thiết kế bố cục bằng flexbox. Kiểm tra nó ở đây: http://acheid.com/Flex-Designer

.container{
    height:180px;
    border:3px solid #00f;
    display:flex;
    align-items:stretch;
}
div {
    display:flex;
    border:3px solid #0f0;
}
.second {
    display:flex;
    flex-grow:1;
    border:3px solid #f00;
}
<div class="container">
    <div>Tree</div>
    <div class="second">View</div>
</div>


bạn đã đọc TẤT CẢ các câu trả lời trước khi thêm câu trả lời của bạn chưa? có vẻ như không ...
Temani Afif

như một lưu ý phụ, bạn không cần phải thêm stretchvì đó là giá trị mặc định và không cần phải làm cho phần tử con flex trở nên display:flexvô dụng đối với các phần tử bên trong
Temani Afif

Tôi tự hỏi tại sao downvote, mà không có bất kỳ bình luận. Đây không phải là câu trả lời trả lời cho câu hỏi? Tại sao? Nếu cố gắng giúp đỡ người khác bị phạt, tôi sẽ suy nghĩ kỹ trước câu trả lời tiếp theo của mình,
Mario Vázquez

1
Bạn có hai bình luận sau khi downvote, nó không đủ?
Temani Afif

Temari, bạn đã kiểm tra công cụ của tôi? Bạn không nghĩ là hữu ích và có thể giúp đỡ người khác? Bạn có nghĩ rằng không liên quan đến câu hỏi? Đâu là câu trả lời của bạn cho câu hỏi này? Tôi không thể nhìn thấy nó. Vai trò của bạn ở đây là gì?
Mario Vázquez

-3

Nếu cả hai chiều rộng đều có chiều dài thay đổi, tại sao bạn không tính chiều rộng với một số kịch bản hoặc phía máy chủ?

<div style="width: <=% getTreeWidth() %>">Tree</div>

<div style="width: <=% getViewWidth() %>">View</div>

3
Làm thế nào để máy chủ biết công cụ bố trí của máy khách sẽ hoạt động như thế nào?
Kev

Đơn giản: phát triển nó cho 90% các trình duyệt ngoài đó :) IE 7+, FF3 + và Safari hỗ trợ CSS 3. Bạn cũng có thể bao gồm phần tử IE6 <! - [if lte IE 6]> tiêu chuẩn. Nhân tiện, trình duyệt nào không hỗ trợ style = "width:%" ??
amischiefr

Tôi không biết làm thế nào nó có thể được thực hiện phía máy chủ, nhưng vâng, một số javscript có thể làm điều đó nhưng tôi muốn tránh nó trừ khi css / html không thể làm điều đó
Anurag Uniyal

Mà nó không thể. Do đó, nếu bạn muốn cả hai phải năng động thì bạn phải thực hiện nó ở phía tập lệnh hoặc phía máy chủ.
amischiefr
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.