Cách tốt hơn để đặt khoảng cách giữa các mục flexbox


781

Để đặt khoảng cách tối thiểu giữa các mục flexbox tôi đang sử dụng margin: 0 5pxtrên .itemmargin: 0 -5pxtrên container. Đối với tôi nó có vẻ như là một hack, nhưng tôi không thể tìm ra cách nào tốt hơn để làm điều này.

Thí dụ

#box {
  display: flex;
  width: 100px;
  margin: 0 -5px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
  margin: 0 5px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>


29
Đây không phải là hack - đó là một trong những phương pháp dự định để sắp xếp các mục. Có những tính chất khác mặc dù. Xem w3.org/TR/css3-flexbox/#alocation
BoltClock

4
Vâng, tôi hiểu. Nhưng ví dụ, có thuộc tính khoảng cách cột cho phép chúng ta kiểm soát khoảng cách từ container: w3.org/TR/css3-multicol/#column-gap
Sasha Koss 17/12/13

Bởi vì đó là sự sụp đổ lề của flexbox. Câu hỏi khác có sự nhận thức đúng về [Làm cách nào tôi có thể ngăn chặn sự sụp đổ lề cuối cùng trong flexbox? ] ( stackoverflow.com/questions/38993170/
Jack Yang

6
Các CSS Hộp Alignment Mô-đun Level 3 bao gồm một phần về khoảng cách giữa hộp - áp dụng cho các yếu tố đa cột, container flex , và container lưới. Vì vậy, cuối cùng điều này sẽ đơn giản như: row-gap: 5px- thực hiện.
Danield

2
@JohnCarrell firefox thực sự đã hỗ trợ gaptài sản trên các thùng chứa flex ( caniuse )
Danield

Câu trả lời:


428
  • Flexbox không có lợi nhuận sụp đổ.
  • Flexbox không có gì giống border-spacingvới bảng (ngoại trừ thuộc tính CSS gapkhông được hỗ trợ tốt trong hầu hết các trình duyệt, caniuse )

Do đó, việc đạt được những gì bạn đang yêu cầu khó khăn hơn một chút.

Theo kinh nghiệm của tôi, cách "sạch nhất" không sử dụng :first-child/ :last-childvà hoạt động mà không có bất kỳ sửa đổi nào flex-wrap:wraplà đặt padding:5pxtrên hộp đựng và margin:5pxtrên trẻ em. Điều đó sẽ tạo ra một 10pxkhoảng cách giữa mỗi đứa trẻ và giữa mỗi đứa trẻ và cha mẹ của chúng.

Bản giới thiệu

.upper
{
  margin:30px;
  display:flex;
  flex-direction:row;
  width:300px;
  height:80px;
  border:1px red solid;

  padding:5px; /* this */
}

.upper > div
{
  flex:1 1 auto;
  border:1px red solid;
  text-align:center;

  margin:5px;  /* and that, will result in a 10px gap */
}

.upper.mc /* multicol test */
{flex-direction:column;flex-wrap:wrap;width:200px;height:200px;}
<div class="upper">
  <div>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa<br/>aaa</div>
  <div>aaa<br/>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa</div>
</div>

<div class="upper mc">
  <div>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa<br/>aaa</div>
  <div>aaa<br/>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa</div>
</div>


220
Điều này không thực hiện được điều tương tự như câu hỏi, bạn sẽ có một vết lõm 10px ở bên trái và bên phải, mà tôi cho rằng họ không có ý định. Do đó, lợi nhuận âm trong câu hỏi ban đầu.
Chris Nicola

17
Nếu ordertài sản được đặt thì sao? :first-child/:last-childsẽ không hoạt động như mong đợi.
Guria

4
Flex Flexbox không có lợi nhuận sụp đổ. Rất sâu sắc, và rõ ràng là đúng, nhưng tôi có thể yêu cầu trích dẫn không?
chharvey

2
Đây không phải là một câu trả lời tồi tệ hơn câu hỏi ban đầu sao? Phương pháp này yêu cầu bạn có không gian xung quanh container và máng xối phải luôn là số chẵn.
Unlimitedlessloop

7
@chharvey, từ thông số w3.org/TR/css-flexbox-1/#item-margins , "Các lề của các mục flex liền kề không bị sụp đổ."
romellem

197

Đây không phải là một hack. Kỹ thuật tương tự cũng được bootstrap và lưới của nó sử dụng, thay vì lề, bootstrap sử dụng phần đệm cho cols của nó.

.row {
  margin:0 -15px;
}
.col-xx-xx {
  padding:0 15px;
}

1
Vấn đề duy nhất với phương pháp này là duy trì các mục có chiều cao bằng nhau với màu nền. Định vị tuyệt đối mà height:100%; width:100%bỏ qua phần đệm của vật phẩm.
Steven Vachon

3
Vấn đề ở đây là với IE10 và 11. flex-basiscác giá trị không được tính đến box-sizing: border-box, vì vậy một đứa trẻ với bất kỳ phần đệm hoặc đường viền nào sẽ tràn cha mẹ (hoặc bao bọc trong trường hợp này). Nguồn
Carson

18
Có một vấn đề khác với cách tiếp cận này: điều chỉnh lề như thế này có thể mở rộng chiều rộng trang. Bản trình diễn: jsfiddle.net/a97tatf6/1
Nathan Osman

4
Mặc dù tôi đồng ý rằng đây không phải là hack, nhưng thực tế là thứ gì đó được sử dụng rộng rãi không có nghĩa nó không phải là hack. Xem polyfill, bản vá bảo mật tạm thời, chỉnh sửa hex, v.v.
William

15
Tất nhiên đây là một hack. Bởi vì Bootstrap sử dụng phương pháp này không có nghĩa là nó không phải là hack. Nó chỉ có nghĩa là Bootstrap sử dụng hack.
Michael Benjamin

108

Flexbox và css calc với nhiều hàng hỗ trợ

Xin chào, dưới đây là giải pháp làm việc của tôi cho tất cả các trình duyệt hỗ trợ flexbox. Không có lợi nhuận âm.

Trình diễn Fiddle

   
.flexbox {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
}

.flexbox > div {
  /*
    1/3  - 3 columns per row
    10px - spacing between columns 
  */
  box-sizing: border-box;
  margin: 10px 10px 0 0;
  outline: 1px dotted red;
  width: calc(1/3*100% - (1 - 1/3)*10px);
}

/*
  align last row columns to the left
  3n - 3 columns per row
*/
.flexbox > div:nth-child(3n) {
  margin-right: 0;
}

.flexbox::after {
  content: '';
  flex: auto;
}

/*
  remove top margin from first row
  -n+3 - 3 columns per row 
*/
.flexbox > div:nth-child(-n+3) {
  margin-top: 0;
}
<div class="flexbox">
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
</div>

Lưu ý rằng mã này có thể ngắn hơn bằng SASS

Cập nhật 2020.II.11 Các cột được căn chỉnh ở hàng cuối cùng bên trái

Cập nhật 2020.II.14 Đã xóa lề dưới ở hàng cuối cùng


13
Tôi thích giải pháp này nhưng thất bại nếu chỉ có 2 mục ở hàng cuối cùng. Các mặt hàng không được xếp chồng lên nhau do justify-content.
James Brantly

4
để khắc phục sự cố hai mục chỉ cần thay đổi thành justify-content: space-evenly;hoặc justify-content: space-around;.
Paul Rooney

6
@PaulRooney Trên trang web có nhiều danh sách, bạn có thể không phải lúc nào cũng biết số lượng mục, nếu danh sách được tạo bởi một CMS.
NinjaFart

1
@ 1.21gigawts Vui lòng không thực hiện thay đổi tùy ý đối với mã / câu trả lời của người khác; viết câu trả lời của riêng bạn thay vào đó.
TylerH

2
@TylerH Nó không độc đoán. Câu hỏi hỏi làm thế nào, "... để đặt khoảng cách giữa các mục flexbox". Câu trả lời này không cho thấy kích thước của máng xối. Đặt màu nền cho thấy máng xối. Thêm một đường viền cho thấy có lề dưới hàng cuối cùng.
1,21 gigawatt

93

Bạn có thể sử dụng đường viền trong suốt.

Tôi đã suy nghĩ về vấn đề này trong khi cố gắng xây dựng một mô hình lưới flex có thể dự phòng cho một mô hình bảng + ô cho các trình duyệt cũ hơn. Và Biên giới cho máng xối cột dường như là sự lựa chọn phù hợp nhất với tôi. tức là các ô bảng không có lề.

ví dụ

.column{
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 10px solid transparent;
}

Cũng lưu ý rằng bạn cần min-width: 50px;cho flexbox. Mô hình flex sẽ không xử lý các kích thước cố định trừ khi bạn thực hiện flex: none;trên phần tử con cụ thể mà bạn muốn là cố định và do đó loại trừ khỏi "flexi". http://jsfiddle.net/GLpUp/4/ Nhưng tất cả các cột cùng với flex:none;không còn là mô hình flex. Đây là một cái gì đó gần hơn với một mô hình flex: http://jsfiddle.net/GLpUp/5/

Vì vậy, bạn thực sự có thể sử dụng lề bình thường nếu bạn không cần dự phòng ô cho các trình duyệt cũ hơn. http://jsfiddle.net/GLpUp/3/

Cài đặt background-clip: padding-box;sẽ là cần thiết khi sử dụng nền, vì nếu không, nền sẽ chảy vào khu vực viền trong suốt.


5
câu trả lời chính xác. lề được sử dụng khác nhau trong flexbox (như để hấp thụ thêm không gian) vì vậy các đường viền trong suốt cung cấp một giải pháp tuyệt vời cho các yếu tố cách đều nhau có thể bao bọc với hành vi giống như lề
Eolis

4
ngoại trừ khi bạn sử dụng màu nền, nền của bạn vượt quá giới hạn mong muốn của bạn.
ahnbizcad

2
@ahnbizcad Vâng với các màu nền khác nhau, bạn có thể sử dụng màu trắng hoặc màu phù hợp tùy thuộc vào cách nào là nền.
hexalys

27
@ahnbizcad: Nếu bạn không cần hỗ trợ IE8, đây là một giải pháp tốt hơn:background-clip: padding-box
Albin

5
Bình luận của Albin ở đây cần nhiều phiếu hơn! Đây là giải pháp tốt nhất. Đường viền trong suốt, kết hợp với clip nền: hộp đệm (và lề âm trên hộp chứa, nếu cần, để căn chỉnh cạnh thích hợp) là một giải pháp hoàn hảo. IE8 dù sao cũng không hỗ trợ flexbox nên việc thiếu hỗ trợ cho clip nền không quan trọng.
Brian

74

Giải pháp này sẽ hoạt động cho tất cả các trường hợp ngay cả khi có nhiều hàng hoặc bất kỳ số lượng phần tử nào. Nhưng số lượng của phần nên giống như bạn muốn 4 ở hàng đầu tiên và 3 là hàng thứ hai, nó sẽ không hoạt động theo cách đó, không gian cho nội dung thứ 4 sẽ trống, container sẽ không điền.

Chúng tôi đang sử dụng display: grid; và tính chất của nó.

#box {
  display: grid;
  width: 100px;
  grid-gap: 5px;
  /* Space between items */
  grid-template-columns: 1fr 1fr 1fr 1fr;
  /* Decide the number of columns and size */
}

.item {
  background: gray;
  width: 100%;
  /* width is not necessary only added this to understand that width works as 100% to the grid template allocated space **DEFAULT WIDTH WILL BE 100%** */
  height: 50px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Nhược điểm của phương pháp này là trong Mobile Opera Mini sẽ không được hỗ trợ và trong PC, tính năng này chỉ hoạt động sau IE10 .

Lưu ý về khả năng tương thích trình duyệt hoàn chỉnh bao gồm IE11, vui lòng sử dụng Autoprefixer


TRẢ LỜI

Đừng nghĩ đó là một giải pháp cũ, nó vẫn là một trong những giải pháp tốt nhất nếu bạn chỉ muốn một hàng yếu tố duy nhất và nó sẽ hoạt động với tất cả các trình duyệt.

Phương pháp này được sử dụng bởi sự kết hợp anh chị em CSS , vì vậy bạn cũng có thể thao tác nó theo nhiều cách khác, nhưng nếu kết hợp của bạn sai thì cũng có thể gây ra sự cố.

.item+.item{
  margin-left: 5px;
}

Các mã dưới đây sẽ làm thủ thuật. Trong phương pháp này, không có nhu cầu để cung cấp cho margin: 0 -5px;đến #boxwrapper.

Một mẫu làm việc cho bạn:

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 22px;
  height: 50px;
}
.item+.item{
 margin-left: 5px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>


Tôi đã chỉnh sửa câu trả lời dựa trên lưới của bạn để chứng minh rằng nó hoạt động chính xác, ngay cả khi hàng cuối cùng có ít mục hơn. Để chứng minh nó hoạt động trong trường hợp đó. (Vui lòng hoàn nguyên nếu bạn không thích thay đổi này.)
ToolmakerSteve

Theo câu hỏi này, họ chỉ yêu cầu lấp đầy khoảng trống bằng các phần tử con mà không cần hack, rằng những gì tôi đã làm, sử dụng lưới chúng ta có thể quản lý theo như grid-template-columnschúng tôi xác định không phải là động. Vì vậy, nếu bạn đưa ra giá trị 1fr 1fr 1fr 1frthì nó sẽ chia div thành 4fractionsvà cố gắng điền vào các phần tử con trong mỗi phần fractions, theo hiểu biết của tôi đó là cách duy nhất grid. Những gì tôi đã nêu trong câu trả lời là nếu người dùng cần chia div thành 4 và sử dụng chúng với nhiều yếu tố ngay cả đối với nhiều hàng, điều đó gidsẽ giúp ích.
weBBer

69

Bạn có thể sử dụng & > * + *làm công cụ chọn để mô phỏng flex-gap(cho một dòng):

#box { display: flex; width: 230px; outline: 1px solid blue; }
.item { background: gray; width: 50px; height: 100px; }

/* ----- Flexbox gap: ----- */

#box > * + * {
  margin-left: 10px;
}
<div id='box'>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
</div>

Nếu bạn cần hỗ trợ gói flex , bạn có thể sử dụng phần tử trình bao bọc:

.flex { display: flex; flex-wrap: wrap;  }
.box { background: gray; height: 100px; min-width: 100px; flex: auto; }
.flex-wrapper {outline: 1px solid red; }

/* ----- Flex gap 10px: ----- */

.flex > * {
  margin: 5px;
}
.flex {
  margin: -5px;
}
.flex-wrapper {
  width: 400px; /* optional */
  overflow: hidden; /* optional */
}
<div class='flex-wrapper'>
  <div class='flex'>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
  </div>
</div>


3
Dung dịch sạch. Hoạt động cho bất kỳ số lượng các yếu tố con flex.
Konrad Gałęzowski

1
Đây là những gì tôi đang tìm kiếm và làm việc tuyệt vời cho tôi
Paul Odeon

Một điểm cần lưu ý là *toán tử không tăng tính đặc hiệu như bạn mong đợi. Vì vậy, tùy thuộc vào css hiện tại của bạn, bạn có thể cần tăng độ đặc hiệu trên .flex > *bộ chọn hoặc thêm !importantvào quy tắc nếu có các bộ chọn khác áp dụng lề cho phần tử đó.
Paul Odeon

Giải pháp tốt nhất
o01

26

Giả sử nếu bạn muốn đặt 10pxkhông gian giữa các mục, bạn chỉ có thể đặt .item {margin-right:10px;}cho tất cả và đặt lại ở mục cuối cùng.item:last-child {margin-right:0;}

Bạn cũng có thể sử dụng bộ chọn anh chị em chung ~hoặc +bộ chọn anh chị em tiếp theo để đặt lề trái cho các mục không bao gồm mục đầu tiên .item ~ .item {margin-left:10px;}hoặc sử dụng.item:not(:last-child) {margin-right: 10px;}

Flexbox thông minh đến mức nó tự động tính toán lại và phân phối đều lưới.

body {
  margin: 0;
}

.container {
  display: flex;
}

.item {
  flex: 1;
  background: gray;
  height: 50px;
}

.item:not(:last-child) {
  margin-right: 10px;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Nếu bạn muốn cho phép quấn flex , xem ví dụ sau.

body {
  margin: 0;
}

.container {
  display: flex;
  flex-wrap: wrap;
  margin-left: -10px;
}

.item {
  flex: 0 0 calc(50% - 10px);
  background: gray;
  height: 50px;
  margin: 0 0 10px 10px;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>


6
Điều này sẽ không hoạt động nếu các mặt hàng được bọc, vì :last-childkhông ảnh hưởng đến mọi đứa trẻ cuối cùng ở cuối dòng, đúng không?
Flimm

2
@Flimm Tôi đã thêm một cách tiếp cận để làm việc với flex quấn, xem phần thứ hai ở trên.
Nhãn dán

Câu trả lời tốt nhất cho tôi ... đơn giản, sạch sẽ, hiệu quả! Hoạt động hoàn hảo với flex flex, cảm ơn bạn
Matthieu Marcé

16

Tôi đã tìm thấy một giải pháp dựa trên bộ chọn anh chị em chung ~và cho phép lồng vô hạn.

Xem bút mã này cho một ví dụ làm việc

Về cơ bản, bên trong các thùng chứa cột, mọi đứa trẻ đi trước một đứa trẻ khác đều có lợi nhuận cao nhất. Tương tự như vậy, bên trong mỗi container hàng, mọi đứa trẻ đi trước người khác đều có lề trái.

.box {
  display: flex;
  flex-grow: 1;
  flex-shrink: 1;
}

.box.columns {
  flex-direction: row;
}

.box.columns>.box~.box {
  margin-left: 5px;
}

.box.rows {
  flex-direction: column;
}

.box.rows>.box~.box {
  margin-top: 5px;
}
<div class="box columns">
  <div class="box" style="background-color: red;"></div>
  <div class="box rows">
    <div class="box rows">
      <div class="box" style="background-color: blue;"></div>
      <div class="box" style="background-color: orange;"></div>
      <div class="box columns">
        <div class="box" style="background-color: yellow;"></div>
        <div class="box" style="background-color: pink;"></div>
      </div>
    </div>
    <div class="box" style="background-color: green;"></div>
  </div>
</div>


Điều này dẫn đến các mặt hàng có kích thước khác nhau do lợi nhuận không được áp dụng trên toàn cầu.
Steven Vachon

Bạn cũng sẽ cần thêm một số CSS bổ sung để xử lý các màn hình nhỏ hơn vì nó trông hơi lạ trên thiết bị di động, tôi sẽ áp dụng quy tắc .box ~ .box cho các màn hình lớn hơn và đối với các màn hình nhỏ hơn, hãy đặt lớp .box có độ rộng tối đa 100% và đáy ký quỹ.
rhysclay

14

Tiếp tục từ câu trả lời của sawa, đây là phiên bản cải tiến một chút cho phép bạn đặt khoảng cách cố định giữa các mục mà không có lề xung quanh.

http://jsfiddle.net/chris00/s52wmgtq/49/

Cũng bao gồm là phiên bản Safari "-webkit-flex".

.outer1 {
    background-color: orange;
    padding: 10px;
}

.outer0 {
    background-color: green;
    overflow: hidden;
}

.container
{
    display: flex;
    display: -webkit-flex;
    flex-wrap: wrap;    
    -webkit-flex-wrap: wrap;
    background-color: rgba(0, 0, 255, 0.5);
    margin-left: -10px;
    margin-top: -10px;
}

.item
{
    flex-grow: 1;
    -webkit-flex-grow: 1;
    background-color: rgba(255, 0, 0, 0.5);
    width: 100px;
    padding: 10px;
    margin-left: 10px;
    margin-top: 10px;
    text-align: center;
    color: white;
}

<div class="outer1">
    <div class="outer0">
        <div class="container">
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
        </div>
    </div>
</div>

2
Đây không phải là về cơ bản giống như ví dụ được đưa ra trong câu hỏi?
ford


9

Tôi đã sử dụng điều này cho các cột chiều rộng bọc và cố định. Chìa khóa ở đây làcalc()

Mẫu SCSS

$gap: 10px;

dl {
  display: flex;
  flex-wrap: wrap;
  padding: $gap/2;

  dt, dd {
    margin: $gap/2;}

  dt { // full width, acts as header
    flex: 0 0 calc(100% - #{$gap});}

  dd { // default grid: four columns 
    flex: 0 0 calc(25% - #{$gap});}

  .half { // hall width columns
    flex: 0 0 calc(50% - #{$gap});}

}

Mẫu Codepen đầy đủ


2
Điều này vẫn thêm một máng xối trước mục đầu tiên và sau mục cuối cùng, mà OP ngăn chặn sử dụng lề âm.
herman

2
Flexbox không hỗ trợ calc () bên trong mục "flex" trong IE 11.
Adam ipický

Không thể luôn luôn được sử dụng. hãy tưởng tượng nếu có biên giới cần thiết cho trẻ em trực tiếp
Andris

9

Một thùng chứa flex với -x (tiêu cực) lợi nhuậnmục flex với x (dương tính) lợi nhuận hoặc đệm đều dẫn đến kết quả hình ảnh mong muốn: Các sản phẩm Flex có một khoảng cách cố định của 2x duy nhất giữa mỗi khác.

Nó dường như chỉ là một vấn đề ưu tiên, cho dù sử dụng lề hay đệm trên các mục flex.

Trong ví dụ này, các mục flex được chia tỷ lệ linh hoạt để duy trì khoảng cách cố định:

.flex-container { 
  margin: 0 -5px;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.flex-item {
  margin: 0 5px; // Alternatively: padding: 0 5px;
  flex: 1 0 auto;
}

3
Xin lỗi, tôi đã không nhận được nó. Câu trả lời nào của bạn giới thiệu mà không được nói trực tiếp trong câu hỏi?
người dùng

Đầu tiên, tôi muốn tổng hợp cả hai, lề và phần đệm trên mục flex dẫn đến kết quả mong muốn, bởi vì các câu trả lời hiện tại chỉ đề cập đến cái này hoặc cái kia. Thứ hai, tôi muốn đưa ra một ví dụ, trong đó các khoảng trống được bảo tồn bằng cách tự nhân rộng các mục flex.
Tim

đây là một ví dụ codepen cho thấy hiệu ứng này. codepen.io/dalgard/pen/Dbnus
pedalpete

8

Cuối cùng, họ sẽ thêm gaptài sản vào flexbox. Cho đến lúc đó bạn có thể sử dụng lưới CSS thay vì đã có thuộc gaptính và chỉ có một hàng. Nicer hơn đối phó với lợi nhuận.


Thảo luận tại đây: github.com/w3c/csswg-dcraft/issues/1696 - họ cũng sẽ hợp lý hóa việc đặt tên, qua CSS Grid, Flexbox và CSS Cột.
Frank Lämmer

6

CSS gapThuộc tính :

Có một gapthuộc tính CSS mới cho bố cục nhiều cột, flexbox và lưới hoạt động trong một số trình duyệt bây giờ! (Xem Tôi có thể sử dụng liên kết 1 ; liên kết 2 ).

#box {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  background-color: red;
  gap: 10px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Khi viết, điều này chỉ hoạt động trong Firefox đáng buồn. Hiện tại nó hoạt động trong Chrome nếu bạn bật "Bật tính năng nền tảng web thử nghiệm" trong about:flags.


5

Sử dụng Flexbox trong giải pháp của tôi Tôi đã sử dụng thuộc justify-contenttính cho phần tử cha (thùng chứa) và tôi đã chỉ định lề bên trong thuộc flex-basistính của các mục. Kiểm tra đoạn mã dưới đây:

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-around;
  margin-bottom: 10px;
}

.item {
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #999;
}

.item-1-4 {
  flex-basis: calc(25% - 10px);
}

.item-1-3 {
  flex-basis: calc(33.33333% - 10px);
}

.item-1-2 {
  flex-basis: calc(50% - 10px);
}
<div class="container">
  <div class="item item-1-4">1</div>
  <div class="item item-1-4">2</div>
  <div class="item item-1-4">3</div>
  <div class="item item-1-4">4</div>
</div>
<div class="container">
  <div class="item item-1-3">1</div>
  <div class="item item-1-3">2</div>
  <div class="item item-1-3">3</div>
</div>
<div class="container">
  <div class="item item-1-2">1</div>
  <div class="item item-1-2">2</div>
</div>


5

Với flexbox, tạo máng xối là một nỗi đau, đặc biệt là khi có sự bao bọc.

Bạn cần sử dụng lề âm ( như trong câu hỏi ):

#box {
  display: flex;
  width: 100px;
  margin: 0 -5px;
}

... hoặc thay đổi HTML ( như thể hiện trong câu trả lời khác ):

<div class='flex-wrapper'>
  <div class='flex'>
    <div class='box'></div>
    <div class='box'></div>
            ...
  </div>
</div>

... Hoặc một cái gì đó khác.

Trong mọi trường hợp, bạn cần một bản hack xấu xí để làm cho nó hoạt động vì flexbox không cung cấp flex-gaptính năng "" ( ít nhất là bây giờ ).

Tuy nhiên, vấn đề về máng xối rất đơn giản và dễ dàng với CSS Grid Layout.

Thông số lưới cung cấp các thuộc tính tạo không gian giữa các mục lưới, trong khi bỏ qua khoảng trắng giữa các mục và vùng chứa. Những tính chất này là:

  • grid-column-gap
  • grid-row-gap
  • grid-gap (tốc ký cho cả hai thuộc tính trên)

Gần đây, thông số kỹ thuật đã được cập nhật để phù hợp với Mô-đun căn chỉnh hộp CSS , cung cấp một tập hợp các thuộc tính căn chỉnh để sử dụng trên tất cả các mô hình hộp. Vì vậy, các thuộc tính bây giờ là:

  • column-gap
  • row-gap
  • gap (tốc ký)

Tuy nhiên, không phải tất cả các trình duyệt hỗ trợ Grid đều hỗ trợ các thuộc tính mới hơn, vì vậy tôi sẽ sử dụng các phiên bản gốc trong bản demo bên dưới.

Ngoài ra, nếu khoảng cách là cần thiết giữa các mục và container, paddingtrên container hoạt động tốt (xem ví dụ thứ ba trong bản demo bên dưới).

Từ thông số kỹ thuật:

10.1. Máng xối: các row-gap, column-gapgap thuộc tính

Các thuộc tính row-gapcolumn-gap(và tốc gapký của chúng ), khi được chỉ định trên một thùng chứa lưới, xác định máng xối giữa các hàng lưới và cột lưới. Cú pháp của chúng được định nghĩa trong Sắp xếp hộp CSS 3 §8 Khoảng cách giữa các hộp .

Ảnh hưởng của các tính chất này như thể các đường lưới bị ảnh hưởng có được độ dày: đường lưới giữa hai đường lưới là khoảng cách giữa các máng xối đại diện cho chúng.

.box {
  display: inline-grid;
  grid-auto-rows: 50px;
  grid-template-columns: repeat(4, 50px);
  border: 1px solid black;
}

.one {
  grid-column-gap: 5px;
}

.two {
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

.three {
  grid-gap: 10px;
  padding: 10px;
}

.item {
  background: lightgray;
}
<div class='box one'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

<hr>

<div class='box two'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

<hr>

<div class='box three'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Thêm thông tin:


4

Tại sao không làm điều đó như thế này:

.item + .item {
    margin-left: 5px;
}

Cái này sử dụng bộ chọn anh chị em liền kề , để đưa ra tất cả các .itemphần tử, ngoại trừ phần tử đầu tiên a margin-left. Nhờ flexbox, điều này thậm chí dẫn đến các yếu tố rộng như nhau. Điều này cũng có thể được thực hiện với các yếu tố định vị theo chiều dọc và margin-top, tất nhiên.


8
Điều này sẽ hoạt động miễn là các mục flex luôn trong một hàng. Nếu gói được cho phép thì có lẽ nó sẽ không đủ.
Nick F

4

Đây là giải pháp của tôi, không yêu cầu thiết lập bất kỳ lớp nào trên các phần tử con:

.flex-inline-row {
    display: inline-flex;
    flex-direction: row;
}

.flex-inline-row.flex-spacing-4px > :not(:last-child) {
    margin-right: 4px;
}

Sử dụng:

<div class="flex-inline-row flex-spacing-4px">
  <span>Testing</span>
  <span>123</span>
</div>

Kỹ thuật tương tự có thể được sử dụng cho các hàng và cột flex thông thường ngoài ví dụ nội tuyến được đưa ra ở trên và được mở rộng với các lớp để cách nhau ngoài 4px.


4

Tôi thường sử dụng toán tử + cho các trường hợp như vậy

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
}
.item + .item {
    margin-left: 5px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>


3

Tôi thấy cách dễ nhất để làm điều này là với tỷ lệ phần trăm và chỉ cho phép lề tăng theo chiều rộng của bạn

Điều này có nghĩa là bạn kết thúc với một cái gì đó như thế này nếu bạn sử dụng ví dụ của mình

#box {
   display: flex;
}

.item {
   flex: 1 1 23%;
   margin: 0 1%;
}

Có nghĩa là giá trị của bạn dựa trên chiều rộng mặc dù có thể không tốt cho tất cả mọi người.


Chỉ cần bắt gặp giải pháp này và vâng, nó rất hay. Hoạt động trong trường hợp của tôi, ít nhất (một cây bút cho những người có thể thấy nó thú vị: codepen.io/rishatmuhametshin/pen/XXjpaV ).
rishat

2

Đây là một lưới các thành phần UI thẻ với khoảng cách hoàn thành bằng hộp linh hoạt:

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

Tôi đã thất vọng với khoảng cách thủ công các thẻ bằng cách thao tác đệm và lề với kết quả iffy. Vì vậy, đây là sự kết hợp của các thuộc tính CSS mà tôi thấy rất hiệu quả:

.card-container {
  width: 100%;
  height: 900px;
  overflow-y: scroll;
  max-width: inherit;
  background-color: #ffffff;
  
  /*Here's the relevant flexbox stuff*/
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap; 
}

/*Supplementary styles for .card element*/
.card {
  width: 120px;
  height: 120px;
  background-color: #ffeb3b;
  border-radius: 3px;
  margin: 20px 10px 20px 10px;
}
<section class="card-container">
        <div class="card">

        </div>
        <div class="card">

        </div>
        <div class="card">

        </div>
        <div class="card">

        </div>
      </section>

Hy vọng điều này sẽ giúp mọi người, hiện tại và tương lai.


Cập nhật: Khoảng cách này có hiệu lực để hiển thị các thành phần HTML di động cần căn chỉnh nhất định (ví dụ: giữa, trái, v.v.). Nếu bạn thấy mình sử dụng hộp flex để phát triển di động, tôi đã thấy nhẹ nhõm khi chuyển sang căn chỉnh hoàn toàn dựa trên lề.
buildpax

2

Cột cột - Một lớp solo cho N cột

Flexbox và SCSS

.columnify {
  display: flex;

  > * {
    flex: 1;

    &:not(:first-child) {
      margin-left: 2rem;
    }
  }
}

Flexbox và CSS

.columnify {
  display: flex;
}

.columnify > * {
  flex: 1;
}

.columnify > *:not(:first-child) {
  margin-left: 2rem;
}
<div class="columnify">
  <div style="display: inline-block; height: 20px; background-color: blue;"></div>
  <div style="display: inline-block; height: 20px; background-color: blue"></div>
  <div style="display: inline-block; height: 20px; background-color: blue"></div>
</div>

Chơi với nó trên JSFiddle .


1

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
}
/* u mean utility */
.u-gap-10 > *:not(:last-child) {
  margin-right: 10px;
}
<div id='box' class="u-gap-10">
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>


1

Chỉ cần sử dụng .item + .itemtrong bộ chọn để khớp từ thứ hai.item

#box {
  display: inline-flex;
  margin: 0 -5px;
}
.item {
  background: gray;
  width: 10px;
  height: 50px;
}

#box .item + .item {
  margin-left: 10px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>


1

Giả định:

  • Bạn muốn bố trí lưới 4 cột với gói
  • Số lượng vật phẩm không nhất thiết là bội số của 4

Đặt lề trái cho mỗi mục ngoại trừ mục 1, 5, 9, v.v. và đặt chiều rộng cố định trên mỗi mục. Nếu lề trái là 10px thì mỗi hàng sẽ có lề 30px giữa 4 mục, chiều rộng phần trăm của mục có thể được tính như sau:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

Đây là một cách giải quyết tốt cho các vấn đề liên quan đến hàng cuối cùng của flexbox.

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0;
  background-color: peachpuff;
}

.item {
  margin-left: 10px;
  border: 1px solid;
  padding: 10px;
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
  background-color: papayawhip;
}

.item:nth-child(4n + 1) {
  margin-left: 0;
}

.item:nth-child(n + 5) {
  margin-top: 10px;
}
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
</div>
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>


1

Thực sự có một cách tốt đẹp, gọn gàng, chỉ CSS để làm điều này (mà người ta có thể xem là "tốt hơn").

Trong tất cả các câu trả lời được đăng ở đây, tôi chỉ tìm thấy một câu sử dụng calc () thành công (bởi Dariusz Sikorski). Nhưng khi được đặt ra với: "nhưng nó thất bại nếu chỉ có 2 mục ở hàng cuối cùng" thì không có giải pháp nào được mở rộng.

Giải pháp này giải quyết câu hỏi của OP bằng một giải pháp thay thế cho tỷ lệ lợi nhuận âm và giải quyết vấn đề đặt ra cho Dariusz.

ghi chú:

  • Ví dụ này chỉ thể hiện bố cục 3 cột
  • Nó sử dụng calc()để cho phép trình duyệt thực hiện toán học theo cách nó muốn - 100%/3 (mặc dù 33.3333% cũng hoạt động tốt)(1em/3)*2 (mặc dù .66em cũng sẽ hoạt động tốt) .
  • Nó sử dụng ::afterđể đệm hàng cuối cùng nếu có ít thành phần hơn cột

.flex-container {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
.flex-container:after {
  content: "";
}
.flex-container > div,
.flex-container:after {
  box-sizing: border-box;
  width: calc((100%/3) - ((1em/3)*2));
}
.flex-container > :nth-child(n + 4) {
  margin-top: 1em;
}

/* the following is just to visualize the items */
.flex-container > div,
.flex-container:after {
  font-size: 2em;
}
.flex-container {
  margin-bottom:4em;
}
.flex-container > div {
  text-align: center;
  background-color: #aaa;
  padding: 1em;
}
.flex-container:after {
  border: 1px dashed red;
}
<h2>Example 1 (2 elements)</h2>
<div class="flex-container">
  <div>1</div>
  <div>2</div>
</div>

<h2>Example 2 (3 elements)</h2>
<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Cũng tại https://codepen.io/anon/pen/rqWagE


1

Bạn có thể sử dụng tài sản mới gap. Tôi sao chép dán giải thích tôi tìm thấy trong bài viết này , cũng như thêm thông tin

Bố cục lưới CSS đã có khoảng cách (khoảng cách lưới trước đây) trong một thời gian. Bằng cách chỉ định khoảng cách bên trong của một phần tử chứa chứ không phải khoảng cách xung quanh các phần tử con, khoảng cách giải quyết nhiều vấn đề bố cục phổ biến. Ví dụ: với khoảng cách, bạn không phải lo lắng về lợi nhuận trên các phần tử con gây ra khoảng trắng không mong muốn xung quanh các cạnh của phần tử có chứa:

Thật không may ngay bây giờ, chỉ có FireFox hỗ trợ khoảng cách trong bố trí flex.

@use postcss-preset-env {
  stage: 0;
  browsers: last 2 versions
}

section {
  width: 30vw;
  
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(12ch, 1fr));
  
  &[flex] {
    display: flex;
    flex-wrap: wrap;
  }
  
  margin-bottom: 3rem;
}

.tag {
  color: white;
  background: hsl(265 100% 47%);
  padding: .5rem 1rem;
  border-radius: 1rem;
}

button {
  display: inline-flex;
  place-items: center;
  gap: .5rem;
  background: hsl(265 100% 47%);
  border: 1px solid hsl(265 100% 67%);
  color: white;
  padding: 1rem 2rem;
  border-radius: 1rem;
  font-size: 1.25rem;
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
<section>
  <h1>Grid</h1> 
  <div class="tag">Awesome</div>
  <div class="tag">Coo</div>
  <div class="tag">Rad</div>
  <div class="tag">Math</div>
</section>
<br>
<section flex>
  <h1>Flex</h1>
  <div class="tag">Awesome</div>
  <div class="tag">Coo</div>
  <div class="tag">Rad</div>
  <div class="tag">Math</div>
</section>


gapđã được đề xuất trong câu trả lời ở đây stackoverflow.com/a/58041749/2756409 Ngoài ra, đây không phải là CSS.
TylerH

0

Nó sẽ không hoạt động trong mọi trường hợp nhưng nếu bạn có độ rộng con linh hoạt (%) và biết số lượng mục trên mỗi hàng, bạn có thể chỉ định rất rõ ràng các lề của các yếu tố cần thiết bằng cách sử dụng nth-child bộ chọn / s.

Nó phụ thuộc phần lớn vào những gì bạn có nghĩa là "tốt hơn". Cách này không yêu cầu đánh dấu trình bao bọc bổ sung cho các phần tử con hoặc phần tử âm - nhưng cả hai phần này đều có vị trí của chúng.

section {
  display: block
  width: 100vw;
}
.container {
  align-content: flex-start;
  align-items: stretch;
  background-color: #ccc;
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  width: 100%;
}

.child-item {
  background-color: #c00;
  margin-bottom: 2%;
  min-height: 5em;
  width: 32%;
}

.child-item:nth-child(3n-1) {
  margin-left: 2%;
  margin-right: 2%;
}
<html>
  <body>
      <div class="container">
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
      </div>
   </body>
</html>


Không đáp ứng. Chỉ hoạt động cho cha mẹ chiều rộng cố định.
Xanh

1
OP không yêu cầu giải pháp đáp ứng và ví dụ của họ sử dụng chiều rộng sửa chữa. Cho rằng điều này sử dụng% giá trị, thật dễ dàng để tranh luận rằng điều này là phản hồi vì các mục sẽ thích ứng với kích thước của cha mẹ được đặt theo tỷ lệ phần trăm.
jnmrobinson

0

Tôi đã gặp vấn đề tương tự trước đó, sau đó tình cờ tìm thấy câu trả lời cho điều này. Hy vọng nó sẽ giúp những người khác để tham khảo trong tương lai.

Câu trả lời dài ngắn, thêm một đường viền cho các mục flex của con bạn. sau đó bạn có thể chỉ định lề giữa các mục flex cho bất cứ thứ gì bạn thích. Trong đoạn trích, tôi sử dụng màu đen cho mục đích minh họa, bạn có thể sử dụng 'trong suốt' nếu bạn muốn.

#box {
  display: flex;
  width: 100px;
  /* margin: 0 -5px; *remove this*/
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
  /* margin: 0 5px; *remove this*/
  border: 1px solid black; /* add this */
}
.item.special{ margin: 0 10px; }
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item special'></div>
</div>


0

Thủ thuật ký quỹ âm trên hộp chứa hoạt động rất tốt. Dưới đây là một ví dụ khác làm việc tuyệt vời với trật tự, gói và những gì không.

.container {
   border: 1px solid green;
   width: 200px;
   display: inline-block;
}

#box {
  display: flex;
  flex-wrap: wrap-reverse;
  margin: -10px;
  border: 1px solid red;
}
.item {
  flex: 1 1 auto;
  order: 1;
  background: gray;
  width: 50px;
  height: 50px;
  margin: 10px;
  border: 1px solid blue;
}
.first {
  order: 0;
}
<div class=container>
<div id='box'>
  <div class='item'>1</div>
  <div class='item'>2</div>
  <div class='item first'>3*</div>
  <div class='item'>4</div>
  <div class='item'>5</div>
</div>
</div>

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.