Chiều rộng chất lỏng với DIVs cách đều nhau


328

Tôi có một DIV chiều rộng chất lỏng.

Trong phạm vi này, tôi có 4 DIV tất cả 300px x 250px ...

<div id="container">
   <div class="box1"> </div>
   <div class="box2"> </div>
   <div class="box3"> </div>
   <div class="box4"> </div>
</div>

Điều tôi muốn xảy ra là hộp 1 được thả sang trái, hộp 4 được thả phải và hộp 2 và 3 được đặt cách đều nhau giữa chúng. Tôi muốn khoảng cách cũng trôi chảy để trình duyệt được làm nhỏ hơn, không gian cũng trở nên nhỏ hơn.

nhập mô tả hình ảnh ở đây


2
Tại sao không làm display:inline-block;thay vì nổi?
ayyp

1
bởi vì IE6 / IE7 chỉ hỗ trợ inline-blockcho inlinecác yếu tố
Lee Price

Được rồi, không chắc chắn bạn sẽ dùng trình duyệt nào.
ayyp

1
Giải pháp gần nhất tôi có thể nghĩ đến là bọc mỗi đứa trẻ .box div trong một div khác có chiều rộng 25%. Sau đó, căn giữa div .box con vào trình bao bọc. Các div .box sẽ được đặt cách đều nhau, nhưng div bên trái và bên phải sẽ không đúng với cạnh.
Paul Sham

5
Tôi đã biến ý tưởng của @Paul Sham thành một JSFiddle .
Sparky

Câu trả lời:


439

Xem: http://jsfiddle.net/thentydot/EDp8R/

  • Điều này hoạt động trong IE6 + và tất cả các trình duyệt hiện đại!
  • Tôi đã giảm một nửa kích thước yêu cầu của bạn chỉ để làm việc dễ dàng hơn.
  • text-align: justifykết hợp với .stretchnhững gì xử lý định vị.
  • display:inline-block; *display:inline; zoom:1sửa lỗi inline-blockcho IE6 / 7, xem tại đây .
  • font-size: 0; line-height: 0 khắc phục một sự cố nhỏ trong IE6.

#container {
  border: 2px dashed #444;
  height: 125px;
  text-align: justify;
  -ms-text-justify: distribute-all-lines;
  text-justify: distribute-all-lines;
  /* just for demo */
  min-width: 612px;
}

.box1,
.box2,
.box3,
.box4 {
  width: 150px;
  height: 125px;
  vertical-align: top;
  display: inline-block;
  *display: inline;
  zoom: 1
}

.stretch {
  width: 100%;
  display: inline-block;
  font-size: 0;
  line-height: 0
}

.box1,
.box3 {
  background: #ccc
}

.box2,
.box4 {
  background: #0ff
}
<div id="container">
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="box3"></div>
  <div class="box4"></div>
  <span class="stretch"></span>
</div>

Phần phụ span( .stretch) có thể được thay thế bằng :after.

Điều này vẫn hoạt động trong tất cả các trình duyệt giống như giải pháp trên. :afterkhông hoạt động trong IE6 / 7, nhưng distribute-all-linesdù sao họ cũng đang sử dụng , vì vậy nó không thành vấn đề.

Xem: http://jsfiddle.net/thentydot/EDp8R/3/

Có một nhược điểm nhỏ :after: để làm cho hàng cuối cùng hoạt động hoàn hảo trong Safari, bạn phải cẩn thận với khoảng trắng trong HTML.

Cụ thể, điều này không hoạt động:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div>
</div>

Và điều này không:

<div id="container">
    ..
    <div class="box3"></div>
    <div class="box4"></div></div>

Bạn có thể sử dụng điều này cho bất kỳ số lượng con tùy ý divmà không cần thêm một boxNlớp cho mỗi lớp bằng cách thay đổi

.box1, .box2, .box3, .box4 { ...

đến

#container > div { ...

Điều này chọn bất kỳ div nào là con đầu tiên của #containerdiv và không có div nào khác bên dưới nó. Để khái quát hóa màu nền, bạn có thể sử dụng bộ chọn thứ tự CSS3 , mặc dù nó chỉ được hỗ trợ trong IE9 + và các trình duyệt hiện đại khác:

.box1, .box3 { ...

trở thành:

#container > div:nth-child(odd) { ...

Xem ở đây cho một ví dụ jsfiddle.


123
Tôi mất 3h để thấy rằng bạn nên có khoảng trắng giữa mỗi hộp trong html. "Justify" mở rộng không gian giữa các yếu tố và nếu nội dung của bạn là <div/><div/><div/>nó không hoạt động. Bạn cần phải có <div/> <div/> <div/>.
venimus

5
chỉ muốn lưu ý rằng :) vì thật khó để lưu ý nếu bạn làm việc với một nội dung được tạo (đó là trường hợp phổ biến). Tôi đã suy nghĩ để sử dụng justifycho trường hợp như vậy, nhưng cảm ơn bạn để cung cấp một giải pháp làm việc. đã lưu cho tôi rất nhiều thử nghiệm (mặc dù đã gỡ lỗi 3h: D). Ngoài ra, tôi có thể thêm một lưu ý rằng nếu bạn muốn hàng cuối cùng của mình được căn trái, bạn nên thêm một số hộp vô hình bổ sung (để hoàn thành hàng)
venimus

4
@venimus: Tôi đã viết một câu trả lời khác bằng kỹ thuật này: stackoverflow.com/questions/10548417/iêu . Bạn đã làm gì để thoát khỏi chiều cao thêm gây ra bằng cách thêm các hộp vô hình?
ba mươi

11
Ai đó có thể giải thích tại sao .stretch là cần thiết?
atp

6
@HartleySan: .stretch/ :afterlà cần thiết bởi vì (thông thường) với văn bản hợp lý, dòng cuối cùng không được chứng minh . Ở đây, chúng tôi muốn dòng cuối cùng được chứng minh, do đó cần phải có :after. Đối với câu hỏi thứ hai của bạn, tôi đã khám phá điều đó một thời gian trước trong một câu trả lời trước đó . Trong câu trả lời đó, JavaScript là bắt buộc. Nếu bạn cần hỗ trợ các trình duyệt cũ hơn (IE8) thì tôi tin rằng bạn cần JavaScript.
ba mươi

140

Cách dễ nhất để làm điều này bây giờ là với một flexbox:

http://css-tricks.com/snippets/css/a-guide-to-flexbox/

CSS sau đó chỉ đơn giản là:

#container {
    display: flex;
    justify-content: space-between;
}

bản demo: http://jsfiddle.net/QPrk3/

Tuy nhiên , điều này hiện chỉ được hỗ trợ bởi các trình duyệt tương đối gần đây ( http://caniuse.com/flexbox ). Ngoài ra, thông số kỹ thuật cho bố cục flexbox đã thay đổi một vài lần, do đó, có thể bao gồm nhiều trình duyệt hơn bằng cách thêm vào một cú pháp cũ hơn:

http://css-tricks.com/old-flexbox-and-new-flexbox/

http://css-tricks.com/USE-flexbox/


1
Cảm ơn bạn vì điều này, thật dễ dàng, tôi đã áp dụng nó cho bốn danh sách cách đều nhau trong phần chân trang được cố định ở cuối trang. Đã xử lý một điều trị trong FF28.0, Chrome 34.0.1847.116 m và IE11.
dùng1063287

1
Flexbox không phải là công cụ được hỗ trợ nhiều nhất trên web và nó không đánh bại cách tiếp cận cổ điển của lề và phần đệm.
TheBlackBenzKid

Đối với tất cả mọi người đang tìm kiếm biện minh cho nhiều div với widht không được xác định: sử dụng tùy chọn flex-quấn với display: flex. Nó sẽ bọc div với chiều rộng động.
Kamil Budziewski

20

Nếu css3 là một tùy chọn, điều này có thể được thực hiện bằng cách sử dụng calc()chức năng css .

Trường hợp 1: Xác minh các hộp trên một dòng ( FIDDLE )

Markup rất đơn giản - một loạt các div với một số phần tử container.

CSS trông như thế này:

div
{
    height: 100px;
    float: left;
    background:pink;
    width: 50px;
    margin-right: calc((100% - 300px) / 5 - 1px); 
}
div:last-child
{
    margin-right:0;
}

Trong đó -1px để sửa lỗi IE9 + calc / làm tròn - xem tại đây

Trường hợp 2: Xác minh các hộp trên nhiều dòng ( FIDDLE )

Ở đây, ngoài calc()chức năng, media querieslà cần thiết.

Ý tưởng cơ bản là thiết lập truy vấn phương tiện cho từng trạng thái #columns, sau đó tôi sử dụng calc () để tìm ra lề phải trên mỗi phần tử (ngoại trừ các phần tử trong cột cuối cùng).

Điều này nghe có vẻ nhiều việc, nhưng nếu bạn đang sử dụng LESS hoặc SASS thì việc này có thể được thực hiện khá dễ dàng

(Nó vẫn có thể được thực hiện với css thông thường, nhưng sau đó bạn sẽ phải thực hiện tất cả các phép tính bằng tay, và sau đó nếu bạn thay đổi độ rộng hộp của mình - bạn phải làm lại mọi thứ một lần nữa)

Dưới đây là một ví dụ sử dụng LESS: (Bạn có thể sao chép / dán mã này vào đây để chơi với nó, [đó cũng là mã tôi đã sử dụng để tạo fiddle đã đề cập ở trên])

@min-margin: 15px;
@div-width: 150px;

@3divs: (@div-width * 3);
@4divs: (@div-width * 4);
@5divs: (@div-width * 5);
@6divs: (@div-width * 6);
@7divs: (@div-width * 7);

@3divs-width: (@3divs + @min-margin * 2);
@4divs-width: (@4divs + @min-margin * 3);
@5divs-width: (@5divs + @min-margin * 4);
@6divs-width: (@6divs + @min-margin * 5);
@7divs-width: (@7divs + @min-margin * 6);


*{margin:0;padding:0;}

.container
{
    overflow: auto;
    display: block;
    min-width: @3divs-width;
}
.container > div
{
    margin-bottom: 20px;
    width: @div-width;
    height: 100px;
    background: blue;
    float:left;
    color: #fff;
    text-align: center;
}

@media (max-width: @3divs-width) {
    .container > div {  
        margin-right: @min-margin;
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @3divs-width) and (max-width: @4divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{3divs})/2 - 1px)";
    }
    .container > div:nth-child(3n) {  
        margin-right: 0;
    }
}

@media (min-width: @4divs-width) and (max-width: @5divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{4divs})/3 - 1px)";
    }
    .container > div:nth-child(4n) {  
        margin-right: 0;
    }
}

@media (min-width: @5divs-width) and (max-width: @6divs-width) {
    .container > div {  
        margin-right: ~"calc((100% - @{5divs})/4 - 1px)";
    }
    .container > div:nth-child(5n) {  
        margin-right: 0;
    }
}

@media (min-width: @6divs-width){
    .container > div {  
        margin-right: ~"calc((100% - @{6divs})/5 - 1px)";
    }
    .container > div:nth-child(6n) {  
        margin-right: 0;
    }
}

Vì vậy, về cơ bản, trước tiên bạn cần quyết định chiều rộng hộp và lề tối thiểu mà bạn muốn giữa các hộp.

Cùng với đó, bạn có thể tìm ra bao nhiêu không gian bạn cần cho mỗi tiểu bang.

Sau đó, sử dụng calc () để vôi hóa lề phải và con thứ n để loại bỏ lề phải khỏi các hộp trong cột cuối cùng.

Các lợi thế của câu trả lời này so với câu trả lời được chấp nhận trong đó sử dụng text-align:justifylà khi bạn có nhiều hơn một dãy hộp - các ô trên dòng cuối cùng không có được 'chứng minh' ví dụ: Nếu có 2 hộp còn lại trên hàng cuối cùng - Tôi không muốn hộp đầu tiên ở bên trái và hộp tiếp theo ở bên phải - mà là các hộp theo nhau theo thứ tự.

Về hỗ trợ trình duyệt : Điều này sẽ hoạt động trên IE9 +, Firefox, Chrome, Safari6.0 + - (xem tại đây để biết thêm chi tiết) Tuy nhiên tôi nhận thấy rằng trên IE9 + có một chút trục trặc giữa các trạng thái truy vấn phương tiện. [nếu ai đó biết cách khắc phục điều này tôi thực sự muốn biết :)] <- CỐ ĐỊNH TẠI ĐÂY


13

Bài viết khác có đề cập flexbox , nhưng nếu nhiều hơn một hàng các mặt hàng là cần thiết , flexbox của space-betweentài sản thất bại (xem phần cuối của bưu điện)

Cho đến nay, giải pháp sạch duy nhất cho việc này là với

Mô-đun bố trí lưới CSS ( bản demo Codepen )

Về cơ bản các mã liên quan cần thiết nắm bắt được điều này:

ul {
  display: grid; /* (1) */
  grid-template-columns: repeat(auto-fit, 120px); /* (2) */
  grid-gap: 1rem; /* (3) */
  justify-content: space-between; /* (4) */
  align-content: flex-start; /* (5) */
}

1) Làm cho phần tử container thành một thùng chứa lưới

2) Đặt lưới với số lượng cột 'tự động' - nếu cần. Điều này được thực hiện cho bố trí đáp ứng. Chiều rộng của mỗi cột sẽ là 120px. (Lưu ý việc sử dụng auto-fit(như được gắn với auto-fill) mà (đối với bố cục 1 hàng) thu gọn các rãnh trống thành 0 - cho phép các mục mở rộng để chiếm dung lượng còn lại. (Hãy xem bản demo này để xem tôi đang nói về điều gì )).

3) Đặt các khoảng trống / máng xối cho các hàng và cột lưới - ở đây, vì muốn bố trí 'khoảng cách giữa' - khoảng cách thực sự sẽ là một khoảng cách tối thiểu vì nó sẽ tăng lên khi cần thiết.

4) và 5) - Tương tự như flexbox.

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, 120px);
  grid-gap: 1rem;
  justify-content: space-between;
  align-content: flex-start;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 90vh;
  margin: 2vh auto;
  border: 5px solid green;
  padding: 0;
  overflow: auto;
}
li {
  background: tomato;
  height: 120px;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Bản demo Codepen (Thay đổi kích thước để xem hiệu ứng)


Hỗ trợ trình duyệt - Caniuse

Hiện được hỗ trợ bởi Chrome (Blink), Firefox, Safari và Edge! ... với sự hỗ trợ một phần từ IE (Xem bài đăng này của Rachel Andrew)


Lưu ý:

Thuộc tính của Flexbox space-betweenhoạt động tuyệt vời cho một hàng vật phẩm, nhưng khi được áp dụng cho hộp chứa flex bao bọc các mặt hàng của nó - (với flex-wrap: wrap) - không thành công, vì bạn không kiểm soát được sự liên kết của hàng cuối cùng của mặt hàng; hàng cuối cùng sẽ luôn được chứng minh (thường không phải là những gì bạn muốn)

Để lam sang tỏ:

Codepen (Thay đổi kích thước để xem những gì tôi đang nói)


Đọc thêm về lưới CSS:


1
Câu trả lời rất bị đánh giá thấp. Đây là cách đơn giản và hiệu quả nhất để đạt được những gì tôi muốn làm. Cảm ơn bạn.
Barnaby Mercer

1
Đây là lượng CSS nhỏ nhất (và không có JS!) Tạo ra chính xác hành vi mà tôi đang tìm kiếm, với một số điều chỉnh về kích thước và không gian.
EKW

1
Tôi đã tìm kiếm điều này trong một thời gian và cuối cùng đã tìm thấy nó!. Cảm ơn @Danield
nareeboy

2

Điều này làm việc cho tôi với 5 hình ảnh ở các kích cỡ khác nhau.

  1. Tạo một div container
  2. Một danh sách không sắp xếp cho các hình ảnh
  3. Trên css, không được sắp xếp phải được hiển thị theo chiều dọc và không có đạn
  4. Nội dung của div div

Điều này hoạt động vì nội dung justify: khoảng giữa, và nó nằm trong danh sách, được hiển thị theo chiều ngang.

Trên CSS

 #container {
            display: flex;
            justify-content: space-between;
 }
    #container ul li{ display:inline; list-style-type:none;
}

Trên html

<div id="container"> 
  <ul>  
        <li><img src="box1.png"><li>
        <li><img src="box2.png"><li>
        <li><img src="box3.png"><li>
        <li><img src="box4.png"><li>
        <li><img src="box5.png"><li>
    </ul>
</div>

Trong khi mã này có thể hoạt động tốt, một câu trả lời tốt sẽ bao gồm một lời giải thích về cách thức hoạt động và tại sao nó là một giải pháp tốt.
Blackwood

Điều đáng chú ý là flexbox không (hoặc chỉ một phần) được hỗ trợ bởi IE caniuse.com/#feat=flexbox
David Salamon

điều này có đáp ứng không?
stackdave

1

trong jQuerybạn có thể nhắm mục tiêu trực tiếp đến Cha mẹ.

ĐIỀU NÀY SỬ DỤNG NẾU BẠN KHÔNG BIẾT CHÍNH XÁC CHÍNH XÁC NHIỀU TRẺ EM S ADD ĐƯỢC THÊM NĂNG ĐỘNG hoặc NẾU BẠN CHỈ CÓ THỂ TÌM HIỂU SỐ NÀY.

var tWidth=0;

$('.children').each(function(i,e){
tWidth += $(e).width();

///Example: If the Children have a padding-left of 10px;..
//You could do instead:
tWidth += ($(e).width()+10);

})
$('#parent').css('width',tWidth);

Điều này sẽ cho phép parentphát triển theo chiều ngang như childrenđược thêm vào.

LƯU Ý: Điều này giả định rằng '.children'có một widthHeightSet

Mong rằng sẽ giúp.


1

Nếu bạn biết số lượng phần tử trên mỗi "hàng" và chiều rộng của vùng chứa, bạn có thể sử dụng bộ chọn để thêm lề cho các thành phần bạn cần để tạo giao diện hợp lý.

Tôi có hàng gồm ba div tôi muốn chứng minh nên đã sử dụng:

.tile:nth-child(3n+2) { margin: 0 10px }

điều này cho phép div trung tâm trong mỗi hàng có lề buộc div thứ 1 và thứ 3 vào các cạnh bên ngoài của container

Cũng tuyệt vời cho những thứ khác như viền màu vv

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.