Bố cục div 2 cột: cột bên phải có chiều rộng cố định, chất lỏng bên trái


158

Yêu cầu của tôi rất đơn giản: 2 cột trong đó cột bên phải có kích thước cố định . Thật không may, tôi không thể tìm thấy một giải pháp hoạt động, không phải trên stackoverflow cũng như trong Google. Mỗi giải pháp được mô tả ở đó đều thất bại nếu tôi thực hiện trong bối cảnh của riêng mình. Giải pháp hiện tại là:

div.container {
    position: fixed;
    float: left;
    top: 100px;
    width: 100%;
    clear: both;
}

#content {
    margin-right: 265px;
}

#right {
    float: right;
    width: 225px;
    margin-left: -225px;
}

#right, #content {
    height: 1%; /* fixed for IE, although doesn't seem to work */
    padding: 20px;
}
<div class="container">
    <div id="content">
        fooburg content
    </div>
    <div id="right">
        test right
    </div>
</div>

Tôi nhận được những điều sau đây với đoạn mã trên:

|----------------------- -------|
| fooburg content  |            |
|-------------------------------|
|                  | test right | 
|----------------------- -------|

Xin tư vấn. Cảm ơn nhiều!

Câu trả lời:


268

Loại bỏ phao trên cột bên trái.

Tại mã HTML, cột bên phải cần đến trước cột bên trái.

Nếu bên phải có một số float (và chiều rộng) và nếu cột bên trái không có chiều rộng và không có float, nó sẽ linh hoạt :)

Cũng áp dụng một overflow: hidden và một số chiều cao (có thể là tự động) cho div bên ngoài, để nó bao quanh cả div bên trong.

Cuối cùng, ở cột bên trái, thêm một width: autooverflow: hidden , điều này làm cho cột bên trái độc lập với cột bên phải (ví dụ: nếu bạn thay đổi kích thước cửa sổ trình duyệt và cột bên phải chạm vào bên trái, không có các thuộc tính này, cột bên trái sẽ chạy nằm bên phải, với thuộc tính này, nó vẫn nằm trong không gian của nó).

Ví dụ HTML:

<div class="container">
    <div class="right">
        right content fixed width
    </div>
    <div class="left">
        left content flexible width
    </div>
</div>

CSS:

.container {
   height: auto;
   overflow: hidden;
}

.right {
    width: 180px;
    float: right;
    background: #aafed6;
}

.left {
    float: none; /* not needed, just for clarification */
    background: #e8f6fe;
    /* the next props are meant to keep this block independent from the other floated one */
    width: auto;
    overflow: hidden;
}​​

Ví dụ ở đây: http://jsfiddle.net/jackJoe/fxWg7/


2
@Mir A clear: both bên trong bất kỳ cột nào sẽ không ảnh hưởng đến các phao bên ngoài. Đây không phải là "dễ vỡ" trừ khi bạn đặt rõ ràng ở cùng cấp độ của các cột giữa các cột, nếu bạn đặt nó ở cuối, không có tác hại nào được thực hiện.
jackJoe

6
Tôi sẽ xem xét sử dụng ví dụ của Adam. Tôi không nghĩ nên đặt cột bên phải trước cột bên trái trong đánh dấu html của bạn.
Daniel_Joris

1
@Danny_Joris Tôi đồng ý. Ngoài ra, nếu bạn sử dụng truy vấn phương tiện, giờ đây rất khó để đẩy cột bên phải xuống dưới cột bên trái
andrewtweber

2
Đối với những người tò mò về cách thức hoạt động của nó, có thể tìm thấy lời giải thích tại đây: stackoverflow.com/questions/25475822/
Kẻ

1
Tôi tự hỏi liệu có cách nào để có cột bên phải SAU bên trái, để nó được xếp đúng cách (không sử dụng flexbox)
Dominic

71

Xem http://www.alistapart.com/articles/negativemargins/ , đây chính xác là những gì bạn cần ( ví dụ 4 ở đó).

<div id="container">
    <div id="content">
        <h1>content</h1>
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.  Phasellus varius eleifend tellus. Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nulla facilisi. Sed wisi lectus, placerat nec, mollis quis, posuere eget, arcu.</p>
        <p class="last">Donec euismod. Praesent mauris mi, adipiscing non, mollis eget, adipiscing ac, erat. Integer nonummy mauris sit amet metus. In adipiscing, ligula ultrices dictum vehicula, eros turpis lacinia libero, sed aliquet urna diam sed tellus. Etiam semper sapien eget metus.</p>
    </div>
</div>

<div id="sidebar">
    <h1>sidebar</h1>
    <ul>
        <li>link one</li>
        <li>link two</li>
    </ul>
</div>

#container {
    width: 100%;
    background: #f1f2ea url(background.gif) repeat-y right;
    float: left;
    margin-right: -200px;
}
#content {
    background: #f1f2ea;
    margin-right: 200px;
}
#sidebar {
    width: 200px;
    float: right;

1
Giải pháp tuyệt vời, đơn giản và giữ đúng thứ tự HTML!
dùng1794295

3
Điều này tốt hơn giải pháp được chấp nhận vì đánh dấu theo đúng thứ tự.
Petri Lehtinen

Tôi không biết về điều này. Làm thế nào tôi không biết về điều này. Hoàn hảo! Tôi đã cố gắng thực hiện toàn bộ 'đầu vào chất lỏng, nút tìm kiếm độ rộng cố định' và rõ ràng thứ tự nguồn thực sự quan trọng ở đây. Cái đinh này nó. Cảm ơn!
Mặt trận Malabar

Tôi thích giải pháp này vì đến thời điểm dừng di động, các cột / thanh bên phải sẽ xuất hiện bên dưới không bên trên nội dung cột bên trái.
dougtesting.net

tôi không thể lấy đúng cột để lên đỉnh với phương pháp này.
mulllhausen

29

Tốt nhất để tránh đặt cột bên phải trước bên trái, chỉ cần sử dụng lề phải âm.

Và hãy "phản hồi" bằng cách bao gồm cài đặt @media để cột bên phải nằm bên trái trên màn hình hẹp.

<div style="background: #f1f2ea;">
  <div id="container">
    <div id="content">
        <strong>Column 1 - content</strong>
    </div>
  </div>
  <div id="sidebar">
    <strong>Column 2 - sidebar</strong>
  </div>
<div style="clear:both"></div>

<style type="text/css">
#container {
    margin-right: -300px;
    float:left;
    width:100%;
}
#content {
    margin-right: 320px; /* 20px added for center margin */
}
#sidebar {
    width:300px;
    float:left
}
@media (max-width: 480px) {
    #container {
        margin-right:0px;
        margin-bottom:20px;
    }
    #content {
        margin-right:0px;
        width:100%;
    }
    #sidebar {
        clear:left;
    }
}
</style>

1
Giải pháp tuyệt vời. Giữ bên phải bên dưới bên trái trong HTML là rất quan trọng đối với các bố cục như blog, nơi bên trái có nội dung quan trọng hơn.
Jake

3
Câu trả lời tuyệt vời! Đây là một ví dụ hoạt động trên Codepen: codepen.io/martinkrulltott/pen/yNxezM
Martin

11

Giải pháp đơn giản và linh hoạt nhất cho đến nay để sử dụng table display:

HTML, div bên trái đứng trước, div bên phải đứng thứ hai ... chúng tôi đọc và viết từ trái sang phải, vì vậy sẽ không có ý nghĩa gì khi đặt div bên phải sang trái

<div class="container">
    <div class="left">
        left content flexible width
    </div>
    <div class="right">
        right content fixed width
    </div>
</div>

CSS:

.container {
  display: table;
  width: 100%;
}

.left {
  display: table-cell;
  width: (whatever you want: 100%, 150px, auto)
}​​

.right {
  display: table-cell;
  width: (whatever you want: 100%, 150px, auto)
}

Ví dụ trường hợp:

// One div is 150px fixed width ; the other takes the rest of the width
.left {width: 150px} .right {width: 100%}

// One div is auto to its inner width ; the other takes the rest of the width
.left {width: 100%} .right {width: auto}

Đẹp, làm việc tốt cảm ơn. Đôi khi có một thời gian và địa điểm cho các bảng khi flexbox không phải là một sự thay thế khả thi. Thay vì đặt đúng nội dung trước trong DOM mà không xếp chồng đúng cách ..
Dominic

1
Tôi thích rằng đây là một giải pháp 'sạch'. Tuy nhiên, vấn đề duy nhất khi đưa div của bạn vào chế độ ô bảng là bạn cũng có thể sử dụng Bảng & Tds. Và bạn sẽ mất các tính năng như cuộn tràn, v.v.
MarzSocks

Đó là không công bằng, bởi vì giải pháp này là ít nhất ngữ nghĩa chính xác và thân thiện với kỹ thuật đơn giản RWD, trong khi sử dụng một tablevới tds chắc chắn nhất là không!
ianp

Phương pháp này dễ dàng cho phép truy vấn phương tiện thả Bảng cho một div thông thường nếu các cột bị thu hẹp. Đẹp và sạch sẽ. Tôi thích.
AnthonyVO

5

Tôi muốn đề xuất một giải pháp chưa được đề cập: sử dụng CSS3 calc()để trộn %pxcác đơn vị. calc()sự hỗ trợ tuyệt vời hiện nay và nó cho phép xây dựng nhanh các bố cục khá phức tạp.

Đây là một liên kết JSFiddle cho mã bên dưới.

HTML:

<div class="sidebar">
  sidebar fixed width
</div>
<div class="content">
  content flexible width
</div>

CSS:

.sidebar {
    width: 180px;
    float: right;
    background: green;
}

.content {
    width: calc(100% - 180px);
    background: orange;
}

Và đây là một JSFiddle khác thể hiện khái niệm này được áp dụng cho một bố cục phức tạp hơn. Tôi đã sử dụng SCSS ở đây vì các biến của nó cho phép mã linh hoạt và tự mô tả, nhưng bố cục có thể dễ dàng được tạo lại trong CSS thuần nếu có các giá trị "mã hóa cứng" không phải là vấn đề.


2

Đây là một giải pháp nguồn HTML được đặt hàng chung trong đó:

  • Cột đầu tiên theo thứ tự nguồn là chất lỏng
  • Cột thứ hai theo thứ tự nguồn được cố định
    • Cột này có thể được thả sang trái hoặc phải bằng CSS

Cột cố định / thứ hai ở bên phải

#wrapper {
  margin-right: 200px;
}
#content {
  float: left;
  width: 100%;
  background-color: powderblue;
}
#sidebar {
  float: right;
  width: 200px;
  margin-right: -200px;
  background-color: palevioletred;
}
#cleared {
  clear: both;
}
<div id="wrapper">
  <div id="content">Column 1 (fluid)</div>
  <div id="sidebar">Column 2 (fixed)</div>
  <div id="cleared"></div>
</div>

Cột cố định / thứ hai bên trái

#wrapper {
  margin-left: 200px;
}
#content {
  float: right;
  width: 100%;
  background-color: powderblue;
}
#sidebar {
  float: left;
  width: 200px;
  margin-left: -200px;
  background-color: palevioletred;
}
#cleared {
  clear: both;
}
<div id="wrapper">
  <div id="content">Column 1 (fluid)</div>
  <div id="sidebar">Column 2 (fixed)</div>
  <div id="cleared"></div>
</div>

Giải pháp thay thế là sử dụng màn hình: ô bảng ; dẫn đến các cột có chiều cao bằng nhau.


cột thứ hai bên phải sẽ không hoạt động. nếu cột bên trái có đầy văn bản, cột bên phải của bạn sẽ hiển thị dưới dạng một hàng mới.
TomSawyer

Bạn đã bao giờ thử đặt thêm nội dung và thay đổi kích thước. chỉ kiểm tra mã của bạn và không hoạt động.
TomSawyer

@TomSawyer Tôi không chắc bạn đang nói về cái gì. Đây là tôi đang cố gắng đưa thêm nội dung: jsfiddle.net/salman/mva6cnxLjsfiddle.net/salman/mva6cnxL/1 . Hoạt động hoàn hảo.
Salman A

Chỉ là những gì tôi tìm kiếm. Cảm ơn

0

Này, những gì bạn có thể làm là áp dụng một chiều rộng cố định cho cả hai container và sau đó sử dụng một lớp div khác trong đó rõ ràng: cả hai, như

div#left {

width: 600px;
float: left;
}

div#right {

width: 240px;
float: right;

}

div.clear {

clear:both;

}

đặt một div rõ ràng dưới container bên trái và bên phải.


-3

Tôi đã đơn giản hóa nó: Tôi đã chỉnh sửa câu trả lời của jackjoe. Tôi nghĩ rằng chiều cao tự động không cần thiết.

CSS:

#container {
position: relative;
margin:0 auto;
width: 1000px;
background: #C63;
padding: 10px;
}

#leftCol {
background: #e8f6fe;
width: auto;
}

#rightCol {
float:right;
width:30%;
background: #aafed6;
}

.box {
position:relative;
clear:both;
background:#F39;
 }
</style>

HTML:

<div id="container">

  <div id="rightCol"> 
   <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
 </div>

 <div id="leftCol">

   <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

Lorem ipsum dolor ngồi amet, consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor ngồi amet, consectetuer adipiscing elit.Phasellus varius eleifend.

</div>

</div>

<div class="box">
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
</div>

Câu hỏi ban đầu muốn một cột bên phải với kích thước cố định.
Bác sĩ Aaron Dishno
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.