Flex-box: Căn chỉnh hàng cuối cùng vào lưới


378

Tôi có một bố trí hộp flex đơn giản với một thùng chứa như:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

Bây giờ tôi muốn các mục trong hàng cuối cùng được liên kết với nhau. justify-content: space-between;nên được sử dụng vì chiều rộng và chiều cao của lưới có thể được điều chỉnh.

Hiện tại có vẻ như

Mục ở dưới cùng bên phải nên ở giữa

Ở đây, tôi muốn mục ở dưới cùng bên phải nằm trong "cột giữa". Cách đơn giản nhất để thực hiện điều đó là gì? Dưới đây là một jsfiddle nhỏ cho thấy hành vi này.

.exposegrid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.exposetab {
  width: 100px;
  height: 66px;
  background-color: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
  margin-bottom: 10px;
}
<div class="exposegrid">
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
</div>



Kiểm tra giải pháp của tôi ở đây Tôi nghĩ rằng nó hoạt động tốt mà không cần hack, chỉ là toán học: stackoverflow.com/questions/18744164/ Kẻ
Sebastien Lorber

5
Ngoài ra, sử dụng có thể sử dụng mô-đun lưới css mới hơn - không có vấn đề này
Danield


1
Tôi đã thêm một giải pháp JS chung cho các trường hợp khi độ rộng của con là biến, làm cho số lượng các mục trên hàng cũng biến.
tao

Câu trả lời:


416

Thêm một ::aftercái mà tự động điền vào không gian. Không cần làm ô nhiễm HTML của bạn. Đây là một codepen hiển thị nó: http://codepen.io/DanAndreasson/pen/ZQXLXj

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid::after {
  content: "";
  flex: auto;
}

17
Có thể làm cho nó hoạt động với không gian xung quanh bằng cách nào đó?
Tom

61
@DanAndreasson Có hai vấn đề, nó không bắt đầu từ bên trái (như khoảng cách giữa) và không gian giữa các mục của hàng cuối cùng khác với hàng trước (mô phỏng một số mục có chiều rộng cố định trong "kích thước bất kỳ" lưới - liên quan đến cả hai) ... codepen.io/anon/pen/gPoYZE Điều tôi muốn là duy trì "chiến lược" (không gian xung quanh hoặc giữa không gian) nhưng bắt đầu từ bên trái như trên các dòng trước ... Tôi muốn biết, nếu có thể khái quát hóa giải pháp tuyệt vời của bạn.
Tom

44
Đây chỉ hoạt động vì mục nào đệm để không gian cho họ và độ rộng tỷ lệ kết hợp bằng 100% cho mỗi bộ 4. Trong codepen này tôi lấy justify-content: space-between;từ .gridvà loại bỏ .grid:aftervà nó hoạt động giống nhau. Bây giờ nếu bạn đã thử một cái gì đó như thế này, nó hoàn toàn phá vỡ. Lưu ý chiều rộng cho mỗi bộ 4 không thêm tới 100%. Trong fiddle của OP, độ rộng được đặt bằng px để giải pháp của bạn không hoạt động trong tình huống này.
Jacob Alvarez

22
Thử giải pháp này, ban đầu, các mục bị thiếu ở hàng cuối cùng không được trải đều space-between. Tuy nhiên, khi tôi đặt flex-basiscủa .grid:afterđến kích thước tương tự như các mặt hàng khác trong lưới (mỗi breakpoint, trọng mã Module default / cơ sở trên), hàng cuối cùng lây lan ra một cách chính xác. Có vẻ như hoạt động trên Safari, iOS, Firefox, Chrome (cần kiểm tra IE) và kích thước hàng lớn nhất của tôi là 3 khi triển khai ban đầu.
webbower

8
Đối với nhu cầu của tôi, điều này đã làm việc với sửa đổi sau: { content: "";flex: 0 0 32%;max-width: 480px;}và tôi đã thay đổi độ rộng tối đa với các thay đổi truy vấn phương tiện để lưới hoàn hảo ở mọi độ rộng.
Colin Wiseman

160

Một kỹ thuật sẽ là chèn một số phần tử bổ sung (nhiều nhất là số phần tử tối đa bạn từng mong muốn có trong một hàng) được cho chiều cao bằng không. Không gian vẫn được phân chia, nhưng các hàng thừa không có gì sụp đổ:

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

Trong tương lai, điều này có thể trở nên khả thi thông qua việc sử dụng nhiều ::after(n).


11
Thật không may, điều này làm ô nhiễm đánh dấu theo một cách phi ngữ nghĩa, nhưng nó hoàn toàn hoạt động. : SI muốn tôi biết bất kỳ cách nào khác để sao chép hành vi này, flexbox hay nói cách khác, điều đó không yêu cầu các yếu tố phi ngữ nghĩa.
Ryan Norbauer

33
Đồng ý, nó bẩn, nhưng nó hoạt động, và ít hack hơn rất nhiều hack. Tìm hiểu kỹ, tôi đang sử dụng nó, cho đến khi :: sau (12) nhận được hỗ trợ hoặc họ thêm một số tùy chọn biện minh bổ sung. Thật đáng xấu hổ khi cách flexbox biện minh cho công việc tại thời điểm này hoàn toàn sai! Nếu bạn đang biện minh cho một đoạn văn bản, bạn sẽ không bao giờ cố gắng biện minh cho dòng cuối cùng. Đáng lẽ phải là một lựa chọn, tôi không thể tin rằng họ đã bỏ lỡ điều này.
Codemonkey

4
Tôi đã đưa ra một giải pháp duy nhất CSS .. hãy cẩn thận vì nó chỉ có thể chiếm hai mục bị thiếu, do đó sẽ chỉ hoạt động an toàn trong lưới flex với tối đa ba mục trên mỗi hàng. Bản trình diễn: codepen.io/lukejacksonn/pen/dozqVq Nguyên tắc ở đây là sử dụng các phần tử giả làm phần tử con và cung cấp cho chúng thuộc tính flex giống như các mục trong vùng chứa.
lukejacksonn

8
@Codemonkey Chúa Giêsu. Tôi mới chỉ bắt đầu sử dụng flexbox với suy nghĩ làm thế nào tôi sẽ thoát khỏi tất cả các hack này nhằm căn chỉnh các khối nội tuyến đó trong một lưới, và bây giờ hóa ra điều đó đơn giản là không thể! Tôi đã đạt được khối đó ngay lập tức, đạt đến giới hạn mà tôi nghĩ rằng tôi sẽ khó có thể đạt được một cách vui vẻ giải quyết tất cả các vấn đề CSS cũ không thể giải quyết này. Không nhanh như vậy, tôi đoán vậy. Chỉ mất 20 năm để có được định tâm thẳng đứng phù hợp - chúng tôi chắc chắn có thể chờ đợi. Chúa ơi, có vẻ như nhiệm vụ rất đơn giản ...
Andrey

3
@dachard Tôi không nghĩ vậy. Xem bình luận của tôi .
Jacob Alvarez

109

Như các áp phích khác đã đề cập - không có cách nào rõ ràng để căn chỉnh hàng cuối cùng với flexbox (ít nhất là theo thông số kỹ thuật hiện tại)

Tuy nhiên, với giá trị của nó: Với Mô-đun Bố cục Lưới CSS, điều này thật dễ dàng để tạo ra:

Về cơ bản các mã có liên quan nắm rõ điều này:

ul {
  display: grid; /* 1 */
  grid-template-columns: repeat(auto-fill, 100px); /* 2 */
  grid-gap: 1rem; /* 3 */
  justify-content: space-between; /* 4 */
}

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

2) Đặt lưới với các cột tự động có chiều rộng 100px. (Lưu ý việc sử dụng tự động điền (đối lập với sự auto-fit- đó (đối với một bố trí 1 hàng) sụp đổ track trống tỉ số 0 -. Gây các mục cần mở rộng để chiếm không gian còn lại này sẽ cho kết quả trong một 'không gian giữa lý 'Bố cục khi lưới chỉ có một hàng mà trong trường hợp của chúng tôi không phải là thứ chúng tôi muốn. (hãy xem bản demo này để thấy sự khác biệt giữa chúng)).

3) Đặt 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) Tương tự như flexbox.

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


4
Giải pháp tốt đẹp. Vấn đề duy nhất là nó không hoạt động với IE10 / 11.
zendu

1
Liên quan đến auto-fit, có một lỗi trong Chrome 57-60 (và các trình duyệt dựa trên công cụ của nó, như Samsung Internet 6.0) vì thông số kỹ thuật lúc đó hơi mơ hồ . Bây giờ thông số kỹ thuật đã được làm rõ và các phiên bản Chrome mới hiển thị auto-fitchính xác, nhưng các trình duyệt có công cụ cũ vẫn đang được sử dụng, vì vậy hãy cẩn thận với giá trị này.
Ilya Streltsyn

4
Trong khả năng hiện tại, đây sẽ là câu trả lời được chấp nhận. Sử dụng :afterphần tử giả có thể dẫn đến kết quả không mong muốn trong các trường hợp cạnh.
Paul

2
@ Danield đề nghị này đã giúp tôi rất nhiều, cảm ơn bạn!
Krys

4
Đây phải là câu trả lời được chấp nhận. Tôi sẽ kết hợp nó với flexbox như một dự phòng, theo tinh thần nâng cao tiến bộ: các trình duyệt không hỗ trợ lưới sẽ hiển thị phiên bản flexbox, đủ gần với tôi.
Palantir

27

Không có bất kỳ đánh dấu bổ sung, chỉ cần thêm ::afterlàm việc cho tôi chỉ định chiều rộng của cột.

.grid {
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
}
.grid::after{
  content: '';
  width: 10em // Same width of .grid__element
}
.grid__element{
  width:10em;
}

Với HTML như thế này:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>

9
Điều này thật thú vị, nhưng không hoàn toàn chính xác. vấn đề xảy ra khi bạn xử lý nhiều hơn hai yếu tố ở hàng dưới cùng - khoảng cách xuất hiện giữa các yếu tố trên các hàng trên không bao giờ xuất hiện ở cuối cùng; các mục được đóng gói cứng với nhau, phủ nhận tiện ích ban đầu của không gian giữa.
John Haugeland

thậm chí tốt hơn nếu bạn sử dụng flex-basis: 10emthay vì chiều rộng.
beyt Swarovski

14

Bạn không thể. Flexbox không phải là một hệ thống lưới. Nó không có cấu trúc ngôn ngữ để làm những gì bạn yêu cầu, ít nhất là không nếu bạn đang sử dụng justify-content: space-between. Cách gần nhất bạn có thể nhận được với Flexbox là sử dụng hướng cột, yêu cầu đặt chiều cao rõ ràng:

http://cssdeck.com/labs/pvsn6t4z (lưu ý: không bao gồm tiền tố)

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}

Tuy nhiên, sẽ đơn giản hơn khi chỉ sử dụng các cột, có hỗ trợ tốt hơn và không yêu cầu đặt chiều cao cụ thể:

http://cssdeck.com/labs/dwq3x6vr (lưu ý: không bao gồm tiền tố)

ul {
  columns: 15em;
}

2
Có một cách; xem câu trả lời của tôi
dunkard

@dacheard, câu trả lời của bạn là một cách giải quyết, không phải là một giải pháp thực sự. Câu trả lời của cimmanon là chính xác.
Giô-na

1
@Jonah Tôi nghĩ "kỹ thuật" là một mô tả công bằng cho câu trả lời của tôi. Nó chắc chắn đã làm việc như một giải pháp cho rất nhiều người, bao gồm cả người hỏi.
dopedard

2
@dalgard Nó không thay đổi thực tế rằng Flexbox không cung cấp cấu trúc ngôn ngữ để làm những gì được yêu cầu. Hơn nữa, tôi sẽ lập luận rằng việc thêm các yếu tố giả là một thực tế cực kỳ bẩn thỉu, ngay trên đó với việc sử dụng các bảng để bố trí.
cimmanon

4
Nó không đẹp, nhưng phát triển front end là nghệ thuật có thể; chủ nghĩa thực dụng là tiền đề cơ bản. Tôi nghĩ rằng từ cực kỳ bị đặt sai chỗ, vì các yếu tố bổ sung đang được sử dụng để tạo kiểu trên 99,9% các trang web trong thế giới thực (xem các yếu tố của Bootstrap container).
dampard

12

Một giải pháp khả thi là sử dụng justify-content: flex-start;trên .gridthùng chứa, hạn chế kích thước đối với con của nó và lề trên các phần tử con thích hợp - tùy thuộc vào số lượng cột mong muốn.

Đối với lưới 3 cột, CSS cơ bản sẽ trông như thế này:

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.grid > * {
    flex: 0 0 32%;
    margin: 1% 0;
}

.grid > :nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
}

Đó là một giải pháp không hoàn hảo, nhưng nó hoạt động.

http://codepen.io/tuxsudo/pen/VYERQJ


11

Tôi biết có nhiều câu trả lời ở đây nhưng .. Cách đơn giản nhất để thực hiện việc này là gridthay vì flexgrid template columnsvới repeatauto fills, nơi bạn phải đặt số pixel mà bạn đã cung cấp cho mỗi thành phần, 100pxtừ mã đoạn trích của bạn.

.exposegrid {
     display: grid;
     grid-template-columns: repeat(auto-fill, 100px);
     justify-content: space-between;
}
 .exposetab {
     width: 100px;
     height: 66px;
     background-color: rgba(255, 255, 255, 0.2);
     border: 1px solid rgba(0, 0, 0, 0.4);
     border-radius: 5px;
     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
     margin-bottom: 10px;
}
<div class="exposegrid">
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
</div>


2
Đây là giải pháp thích hợp để có được các mục hàng cuối cùng được căn trái.
a.barbieri

Tôi đồng ý, cách thích hợp là sử dụng lưới. Nó có thể đạt được với flexbox nhưng sạch hơn nhiều để sử dụng lưới.
nbarth

6

Đúng.! Chúng tôi có thể nhưng với một số truy vấn phương tiện & Tối đa không có cột nào được xác định trước .

Ở đây đang sử dụng 4 cột. Kiểm tra mã của tôi:

.container {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
  -moz-flex-flow: row wrap;
}

.container .item {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  justify-content: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  flex-basis: 25%; //max no of columns in %, 25% = 4 Columns
}

.container .item .item-child {
  width: 130px;
  height: 180px;
  background: red;
  margin: 10px;
}

@media (max-width: 360px) {
  .container .item {
    flex-basis: 100%;
  }
}

@media (min-width:360px) and (max-width: 520px) {
  .container .item {
    flex-basis: 50%;
  }
}

@media (min-width:520px) and (max-width: 680px) {
  .container .item {
    flex-basis: 33.33%;
  }
}
<div class="container">

  <div class="item">
    <div class="item-child">1</div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>

</div>

CHÚ THÍCH
1) Không cần tạo div con. Nó có thể là bất kỳ thẻ nào khác như 'img' r bất cứ điều gì bạn muốn ..
2) Nếu bạn muốn nhiều cột hơn điều chỉnh các truy vấn phương tiện và các cột no.of tối đa.


Điều này chỉ tạo ra 3 trong IE mới nhất
Akxe

6

Nếu bạn muốn một lưới có một khoảng trống giữa các mục và các mục bắt đầu mà không có không gian ban đầu thì giải pháp đơn giản này hoạt động:

.grid {
    display: flex;
    flex-flow: row wrap;
    margin: 0 -5px; // remove the inital 5px space
    width: auto;
}
.grid__item {
    width: 25%;
    padding: 0 5px; // should be same as the negative margin above.
}

Nếu bạn muốn không gian 5px ban đầu thì chỉ cần loại bỏ lề âm :) Đơn giản.

https://jsfiddle.net/b97ewrno/2/

Câu trả lời được chấp nhận, trong khi tốt, nó khiến không có khoảng cách giữa các thành phần trên hàng thứ hai ..


1
Ngạc nhiên vì điều này không có thêm phiếu bầu nào. Đây là một cách tiếp cận đẹp thuộc về bảo tàng Flex.
Eduardo La Hoz Miranda

1
@EduardoLaHozMiranda cảm ơn! Nhưng tại sao "bảo tàng"? IE11 không hỗ trợ lưới css và hầu hết các trang web vẫn cần hỗ trợ điều đó. + Một số bộ định thời lớn trong phát triển frontend vẫn cho rằng có các trường hợp sử dụng khác nhau cho lưới so với flexbox. Nhưng có lẽ bạn chỉ muốn nói rằng đây phải là một phần quan trọng của lịch sử web: D
OZZIE

1
Lol, vâng. Tôi đã rất phấn khích vào thời điểm đó. Chỉ có nghĩa là nó là một vấn đề tuyệt vời và tối thiểu cho vấn đề này.
Eduardo La Hoz Miranda

@dencey bạn không cần biết rằng đối với giải pháp này, nó chiếm tối đa 4% cho mỗi hàng, nhưng bạn có thể sử dụng bất cứ tỷ lệ phần trăm nào bạn muốn
OZZIE

@OZZIE Ý tôi là chiều rộng của mục là cố định (như 100px), nhưng chiều rộng vùng chứa là động, vì vậy các mục trên mỗi hàng là động.
dencey

4

Nếu bạn muốn căn chỉnh mục cuối cùng vào lưới, hãy sử dụng mã sau:

Lưới container

.card-grid {
  box-sizing: border-box;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  justify-content: space-between;
  align-items: stretch;
  align-content: stretch;
  -webkit-box-align: stretch;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
}

.card-grid:after {
  content: "";
  flex: 1 1 100%;
  max-width: 32%;
}

Mục trong lưới

.card {
  flex: 1 1 100%;
  box-sizing: border-box;
  -webkit-box-flex: 1;
  max-width: 32%;
  display: block;
  position: relative;

}

Mẹo nhỏ là đặt chiều rộng tối đa của mục bằng với chiều rộng tối đa của .card-lưới: sau.

Bản demo trực tiếp trên Codepen


cthulu ban phước cho bạn và máy tính của bạn
L422Y

3
Cách tiếp cận này không hoạt động khi kích thước của thẻ được cố định và số lượng thẻ ở mỗi hàng không xác định. codepen.io/zendu/pen/WXNGvo
zendu

3

Có thể sử dụng "flex-start" và thêm lề bằng tay. Nó đòi hỏi một số hack toán học nhưng chắc chắn dễ thực hiện và làm cho nó dễ sử dụng với bộ tiền xử lý CSS như LESS.

Xem ví dụ mixin LESS này:

.flexboxGridMixin(@columnNumber,@spacingPercent) {
  @contentPercent: 100% - @spacingPercent;
  @sideMargin: @spacingPercent/(@columnNumber*2);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  > * {
    box-sizing: border-box;
    width: @contentPercent/@columnNumber;
    margin-left: @sideMargin;
    margin-right: @sideMargin;
  }
}

Và sau đó nó có thể dễ dàng được sử dụng để hiển thị bố cục lưới đáp ứng:

ul {
  list-style: none;
  padding: 0;
  @spacing: 10%;
  @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
  @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
  @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
  @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
  @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
}

li {
  background: pink;
  height: 100px;
  margin-top: 20px;
}

Đây là một ví dụ về

http://codepen.io/anon/pen/YyLqVB?editors=110


Bạn không bao giờ sử dụng @contentPercent. Bạn đã có ý định?
neverfox

chiều rộng: @ contentPercent / @ cộtNumber;
realtebo

Ôi! Tôi thực sự ấn tượng bởi giải pháp này. Tôi sẽ cố gắng thích nghi với hoàn cảnh của mình
realtebo

3

Vấn đề này đã được giải quyết cho tôi bằng cách sử dụng lưới CSS,

Giải pháp này chỉ có thể áp dụng nếu bạn đang sửa số lượng cột tức là không. các yếu tố để hiển thị trong một hàng

-> sử dụng lưới nhưng không chỉ định số lượng hàng, vì số phần tử tăng nó kết thúc thành các cột và thêm các hàng động, tôi đã chỉ định ba cột trong ví dụ này

-> bạn không phải đưa ra bất kỳ vị trí nào cho con / tế bào của bạn, vì nó sẽ khiến nó sửa chữa, điều mà chúng tôi không muốn.

.grid-class{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 80px;
}


1

Phiên bản này là cách tốt nhất cho các khối có chiều rộng cố định:

http://codepen.io/7iomka/pen/oxxeNE

Trong các trường hợp khác - phiên bản của bộ đệm

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
justify-content:center;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  max-width:200px;
  min-width:200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>


0

Có một cách không có flexbox, mặc dù bạn cần phải đáp ứng các điều kiện sau. 1) Container có đệm. 2) Các mục có cùng kích thước và bạn biết chính xác có bao nhiêu bạn muốn trên mỗi dòng.

ul {
  padding: 0 3% 0 5%;
}
li {
  display: inline-block; 
  padding: 0 2% 2% 0;
  width: 28.66%;
}

Phần đệm nhỏ hơn ở bên phải của container cho phép phần đệm thêm ở bên phải của mỗi mục danh sách. Giả sử các mục khác trong cùng cha mẹ với đối tượng danh sách được đệm bằng 0 5%, nó sẽ được xóa với chúng. Bạn cũng có thể điều chỉnh tỷ lệ phần trăm theo tỷ lệ phần trăm bạn muốn hoặc sử dụng tính toán giá trị px.

Tất nhiên, bạn có thể làm tương tự mà không cần phần đệm trên container bằng cách sử dụng nth-child (IE 9+) để xóa lề trên mỗi hộp thứ ba.


0

Sử dụng flexbox và một vài truy vấn phương tiện, tôi đã thực hiện công việc nhỏ này: http://codepen.io/una/pen/yNEGjv (hơi hack nhưng hoạt động được):

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  max-width: 1200px;
  margin: 0 auto;
}

.item {
  background-color: gray;
  height: 300px;
  flex: 0 30%;
  margin: 10px;

  @media (max-width: 700px) {
     flex: 0 45%;
  }

  @media (max-width: 420px) {
    flex: 0 100%;
  }

  &:nth-child(3n-1) {
    margin-left: 10px;
    margin-right: 10px;
  }
}

0

Tôi đã tạo ra một mixin SCSS cho nó.

@mixin last-row-flexbox($num-columns, $width-items){

  $filled-space: $width-items * $num-columns;
  $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1));

  $num-cols-1 : $num-columns - 1;

  &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & {
    margin-left: $margin;
  }
  @for $i from 1 through $num-columns - 2 { 
    $index: $num-columns - $i;
    &:nth-child(#{$num-columns}n+#{$index}):last-child{
      margin-right: auto;
    }
  }
}

Đây là liên kết codepen: http://codepen.io/diana_aceves/pen/KVGNZg

Bạn chỉ cần đặt chiều rộng của mục theo tỷ lệ phần trăm và số cột.

Tôi hy vọng điều này có thể giúp bạn.


0

Đây là một vài mixins scss.

Các mixin này giả định rằng bạn sẽ không sử dụng các plugin js như Isotope (chúng không tôn trọng thứ tự đánh dấu html, do đó gây rối với các quy tắc css nth).

Ngoài ra, bạn sẽ có thể tận dụng tối đa lợi thế của chúng, đặc biệt nếu bạn đang viết các điểm dừng đáp ứng của mình theo cách di động. Bạn lý tưởng sẽ sử dụng flexbox_grid () trên điểm dừng nhỏ hơn và flexbox_cell () trên các điểm dừng sau. flexbox_cell () sẽ đảm nhiệm việc đặt lại các lề đã giải quyết trước đó không còn được sử dụng trên các điểm dừng lớn hơn.

Và nhân tiện, miễn là bạn thiết lập chính xác các thuộc tính flex của người chứa, bạn cũng có thể chỉ sử dụng flexbox_cell () trên các mục, nếu bạn cần.

Đây là mã:

// apply to the container (for ex. <UL> element)
@mixin flexbox_grid($columns, $gutter_width){

  display: flex;
  flex-direction:row;
  flex-wrap:wrap;
  justify-content: flex-start;

  > *{
    @include flexbox_cell($columns, $gutter_width);
  }
}

// apply to the cell (for ex. a <LI> element)
@mixin flexbox_cell($columns, $gutter_width){
  $base_width: 100 / $columns;
  $gutters: $columns - 1;
  $gutter_offset: $gutter_width * $gutters / $columns;

  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: auto; // IE10 doesn't support calc() here

  box-sizing:border-box; // so you can freely apply borders/paddings to items
  width: calc( #{$base_width}% - #{$gutter_offset} );

  // remove useless margins (for cascading breakponts)
  &:nth-child(#{$columns}n){
    margin-right: 0;
  }

  // apply margin
  @for $i from 0 through ($gutters){
    @if($i != 0){
      &:nth-child(#{$columns}n+#{$i}){
        margin-right: $gutter_width;
      }
    }
  }
}

Sử dụng:

ul{
   // just this:
   @include flexbox_grid(3,20px);
}

// and maybe in following breakpoints, 
// where the container is already setted up, 
// just change only the cells:

li{
   @include flexbox_cell(4,40px);
}

Rõ ràng, cuối cùng bạn sẽ đặt phần đệm / lề / chiều rộng và lề dưới của ô chứa và tương tự.

Hy vọng nó giúp!


0

Điều này là khá hacky, nhưng nó làm việc cho tôi. Tôi đã cố gắng để đạt được khoảng cách / lề nhất quán.

.grid {
  width: 1024px;
  display: flex;
  flex-flow: row wrap;
  padding: 32px;
  background-color: #ddd;  

  &:after {
    content: "";
    flex: auto;
    margin-left:-1%;
  }

  .item {
    flex: 1 0 24.25%;
    max-width: 24.25%;
    margin-bottom: 10px;
    text-align: center;
    background-color: #bbb;

    &:nth-child(4n+2),
    &:nth-child(4n+3),
    &:nth-child(4n+4) {
      margin-left: 1%;
    }

    &:nth-child(4n+1):nth-last-child(-n+4),
      &:nth-child(4n+1):nth-last-child(-n+4) ~ .item {
        margin-bottom: 0;
    }    

  }
}

http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/


0

Có vẻ như không ai đề xuất giải pháp tăng trưởng flex cho mục cuối cùng. Ý tưởng là để vật phẩm flex cuối cùng của bạn có thể sử dụng flex-grow: 1.

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.grid > *:last-child {
  flex-grow: 1;
}

Lưu ý: Giải pháp này không hoàn hảo, đặc biệt nếu bạn có các yếu tố trung tâm bên trong các mục flex của mình vì nó sẽ tập trung vào mục flex cuối cùng có thể rất lớn.


0

Đây là sự kết hợp của rất nhiều câu trả lời nhưng nó thực hiện chính xác những gì tôi cần - đó là, sắp xếp đứa trẻ cuối cùng trong một hộp đựng linh hoạt sang trái trong khi duy trì hành vi giữa không gian (trong trường hợp này là một cột ba cột bố trí).

Đây là đánh dấu:

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

.flex-container:after {
  content: "";
  flex-basis: 30%;
}

1
Để chung chung hơn: kích thước cơ sở flex phải bằng kích thước của trẻ em.
Christian Toffolo

1
Tôi đã tìm thấy flex-grow: 0.9thay vì flex-basislàm việc cho bất kỳ số lượng cột. Đã thử nghiệm trong một loạt các trình duyệt hiện đại - nó hoạt động trong tất cả nhưng phần đệm bị hỏng trong IE (nhưng hoạt động trong Edge0
Patabugen

0

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 và 9, v.v. Nếu lề trái là 10px thì mỗi hàng sẽ có lề 30px được phân phối giữa 4 mục. Chiều rộng phần trăm cho mục đượ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 3em;
  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>


0

Nếu bạn biết chiều rộng của khoảng trắng giữa các phần tử trong hàng và số lượng phần tử trong một hàng, điều này sẽ hoạt động:

Ví dụ: 3 phần tử liên tiếp, khoảng cách 10px giữa các phần tử

div:last-child:nth-child(3n+2) {
  flex-grow: 1
  margin-left: 10px
}

0

Chỉ cần sử dụng thủ thuật Jquery / Javascript để thêm một div trống:

if($('.exposegrid').length%3==2){
 $(".exposegrid").append('<div class="exposetab"></div>');
}

-1

Ôi trời, tôi nghĩ rằng tôi đã tìm thấy một giải pháp tốt với CSS tối thiểu và không có JS. Kiểm tra xem nó:

img {width:100%;}
li {
  display: inline-block;
  width:8em;
  list-style:none;
}
ul {text-align: justify;}
<ul>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Chìa khóa ở đây là hãy nhớ rằng những gì chúng ta đang cố gắng đạt được chính xác là những gì text-align: justify !

Các yếu tố trống trong HTML có ở đó để làm cho hàng cuối cùng hiển thị hoàn hảo mà không thay đổi giao diện, nhưng có thể không cần thiết cho những gì bạn đang cố gắng đạt được. Để cân bằng hoàn hảo trong mọi tình huống, bạn cần ít nhất x-4 phần tử trống, x là số phần tử cần hiển thị hoặc n-2, n là số cột bạn muốn hiển thị.


-1

Chỉ cần thêm một vài mục giả mạo có cùng thuộc tính ngoại trừ chiều cao được đặt thành 0px đến cuối.


Thêm các mặt hàng giả là thực hành xấu trong mọi cách. Bạn không cần phải điền vào DOM với các công cụ chỉ để hack xung quanh css trừ khi bắt buộc. Vì nhiều lý do, từ khả năng truy cập, đến việc tràn ngập codebase với những thứ kỳ lạ, để làm cho logic trở nên phức tạp hơn để hiểu và danh sách tiếp tục. Đừng đề nghị hack trừ khi bạn nói rõ ràng đó có thể là một giải pháp tồi hoặc có trường hợp đặc biệt cho điều đó.
Eksapsy

-4

bạn muốn căn chỉnh

sử dụng align-content: flex-start;thay vìjustify-content: space-between;

Điều này kéo các mục cuối cùng sang trái và cũng phân bổ không gian đồng đều,

.container {
  display: flex;
  flex-flow: row wrap;
  align-content: flex-start;
  /*justify-content: space-between; remove this line!!!! */ 
}

https://codepen.io/anon/pen/aQggBW?editors=1100


giải pháp danAnderson KHÔNG phải là NĂNG ĐỘNG. NHANH CHÓNG !!

khi chiều rộng mục thay đổi từ 25 thành 28 dan và không có khoảng trống giữa các hình ảnh

danAnderson: https://codepen.io/anon/pen/ZwYPmB?editors=1100

năng động: https://codepen.io/anon/pen/aQggBW?editors=1100

đó là những gì tôi đã cố gắng nói Dans là hack .....


-7

Tôi đã có thể làm điều đó với justify-content: space-betweentrên container

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.