Lưới các ô vuông đáp ứng


170

Tôi đang tự hỏi làm thế nào tôi có thể tạo ra một bố cục với các hình vuông đáp ứng . Mỗi hình vuông sẽ có nội dung được sắp xếp theo chiều dọc và chiều ngang . Ví dụ cụ thể được hiển thị bên dưới ...

hình vuông đáp ứng với nội dung


Tôi ghét cách các câu hỏi với câu trả lời tuyệt vời chỉ được đóng ngẫu nhiên bởi những người có triển vọng thực sự mang tính mô phạm về việc stackoverflow sẽ như thế nào. Nếu họ có câu trả lời tốt, được chấp nhận, được nêu lên ... tại sao lại đóng nó ??? Đâu là sự nhầm lẫn? Chắc chắn, trên "lưới các ô vuông phản hồi" của riêng nó có thể cần một chút, hoặc rất nhiều, để giải thích, nhưng đây là một câu hỏi 7 năm tuổi, hơn 160 với câu trả lời hơn 400. Tôi đang bỏ phiếu mở lại.
leinaD_natipaC

Câu trả lời:


416

Bạn có thể tạo lưới phản ứng vuông với nội dung trung tâm dọc và ngang chỉ với CSS . Tôi sẽ giải thích làm thế nào trong một quá trình từng bước nhưng trước tiên đây là 2 bản demo về những gì bạn có thể đạt được:

Lưới phản ứng 3x3 vuông Hình ảnh phản hồi vuông trong lưới 3x3

Bây giờ hãy xem làm thế nào để làm cho các hình vuông đáp ứng ưa thích!



1. Tạo các hình vuông đáp ứng:

Mẹo để giữ cho các phần tử vuông (hoặc bất kỳ tỷ lệ khung hình nào khác) là sử dụng phần trăm padding-bottom.
Lưu ý bên lề: bạn có thể sử dụng phần đệm trên cùng hoặc lề trên / dưới nhưng nền của phần tử sẽ không hiển thị.

Vì phần đệm trên cùng được tính theo chiều rộng của phần tử cha ( Xem MDN để tham khảo ), chiều cao của phần tử sẽ thay đổi theo chiều rộng của phần tử. Bây giờ bạn có thể Giữ tỷ lệ khung hình của nó theo chiều rộng của nó.
Tại thời điểm này, bạn có thể mã:

HTML :

 <div></div>

CSS

div {
    width: 30%;
    padding-bottom: 30%; /* = width for a square aspect ratio */
}

Dưới đây là một ví dụ bố trí đơn giản của lưới ô vuông 3 * 3 bằng cách sử dụng mã ở trên.

Với kỹ thuật này, bạn có thể thực hiện bất kỳ tỷ lệ khung hình nào khác, dưới đây là bảng đưa ra các giá trị của phần đệm dưới theo tỷ lệ khung hình và chiều rộng 30%.

 Aspect ratio  |  padding-bottom  |  for 30% width
------------------------------------------------
    1:1        |  = width         |    30%
    1:2        |  width x 2       |    60%
    2:1        |  width x 0.5     |    15%
    4:3        |  width x 0.75    |    22.5%
    16:9       |  width x 0.5625  |    16.875%




2. Thêm nội dung bên trong hình vuông

Vì bạn không thể thêm nội dung trực tiếp vào các hình vuông (nó sẽ mở rộng chiều cao của chúng và hình vuông sẽ không còn là hình vuông nữa), bạn cần tạo các phần tử con (ví dụ này tôi đang sử dụng div) bên trong chúng position: absolute;và đặt nội dung bên trong chúng . Điều này sẽ đưa nội dung ra khỏi dòng chảy và giữ kích thước của hình vuông.

Đừng quên thêmposition:relative; vào div cha mẹ để con cái tuyệt đối được định vị / kích thước tương đối với cha mẹ của chúng.

Hãy thêm một số nội dung vào lưới ô vuông 3x3 của chúng tôi:

HTML :

<div class="square">
    <div class="content">
        .. CONTENT HERE ..
    </div>
</div>
... and so on 9 times for 9 squares ...

CSS :

.square {
    float:left;
    position: relative;
    width: 30%;
    padding-bottom: 30%; /* = width for a 1:1 aspect ratio */
    margin:1.66%;
    overflow:hidden;
}

.content {
    position:absolute;
    height:80%; /* = 100% - 2*10% padding */
    width:90%; /* = 100% - 2*5% padding */
    padding: 10% 5%;
}

KẾT QUẢ <- với một số định dạng để làm cho nó đẹp!



3. Trung tâm nội dung

Theo chiều ngang:

Điều này là khá dễ dàng, bạn chỉ cần thêm text-align:centervào .content.
KẾT QUẢ

Căn dọc

Điều này trở nên nghiêm trọng! Bí quyết là sử dụng

display:table;
/* and */
display:table-cell;
vertical-align:middle;

nhưng chúng ta không thể sử dụng display:table;trên .squarehoặc .contentdivs vì nó mâu thuẫn với position:absolute;vì vậy chúng tôi cần phải tạo ra hai đứa con bên trong .contentdiv. Mã của chúng tôi sẽ được cập nhật như sau:

HTML :

<div class="square">
    <div class="content">
        <div class="table">
            <div class="table-cell">
                ... CONTENT HERE ...
            </div>
        </div>
    </div>
</div>
... and so on 9 times for 9 squares ...

CSS:

.square {
    float:left;
    position: relative;
    width: 30%;
    padding-bottom : 30%; /* = width for a 1:1 aspect ratio */
    margin:1.66%;
    overflow:hidden;
}

.content {
    position:absolute;
    height:80%; /* = 100% - 2*10% padding */
    width:90%; /* = 100% - 2*5% padding */
    padding: 10% 5%;
}
.table{
    display:table;
    height:100%;
    width:100%;
}
.table-cell{
    display:table-cell;
    vertical-align:middle;
    height:100%;
    width:100%;
}




Bây giờ chúng ta đã hoàn thành và chúng ta có thể xem kết quả ở đây:

KẾT QUẢ HOÀN TOÀN

Fiddle có thể chỉnh sửa ở đây



2
@ d.raev có. Tỷ lệ phần trăm và tỷ lệ phần trăm được tính theo chiều rộng của cha mẹ. Kiểm tra tại đây để đệm nhà phát
triển.mozilla.org/en-US/docs

4
Điều đó thật tuyệt. Chỉ cần một người đứng đầu: nếu bạn đang sử dụng, * { box-sizing: border-box; }bạn cần điều chỉnh chiều cao và chiều rộng trong div .content thành 100%. :)
Rob Flaherty

2
những gì tính toán đằng sau giá trị ký quỹ? Nếu tôi muốn đặt lưới 5x5 thì sao?
kiwi1342

2
@ kiwi1342 tổng của tất cả các lề + tất cả chiều rộng trên một hàng phải bằng 100%. Vì vậy, đối với lưới 5x5, bạn có thể sử dụng chiều rộng 18% với lề 1% cho mỗi bên của các phần tử.
web-tiki

1
Tuyệt diệu. Chỉ cần ngẩng cao đầu: Để tập trung theo chiều ngang và chiều dọc, chỉ cần đặt .content thành một flexbox vớijustify-content: center; align-items: center; flex-flow: column nowrap;
NonameSL

14

Bạn có thể sử dụng các đơn vị vw (view-width), điều này sẽ làm cho các ô vuông phản ứng theo độ rộng của màn hình.

Một bản mô phỏng nhanh về điều này sẽ là:

html,
body {
  margin: 0;
  padding: 0;
}
div {
  height: 25vw;
  width: 25vw;
  background: tomato;
  display: inline-block;
  text-align: center;
  line-height: 25vw;
  font-size: 20vw;
  margin-right: -4px;
  position: relative;
}
/*demo only*/

div:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: inherit;
  width: inherit;
  background: rgba(200, 200, 200, 0.6);
  transition: all 0.4s;
}
div:hover:before {
  background: rgba(200, 200, 200, 0);
}
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>


4
Đừng sử margin-left: -4px;dụng sử dụng margin-right:-4px. Thay vào đó, đừng gây rối với sự không nhất quán trong không gian minchars mà được đặt thành kích thước phông chữ của trình bao bọc thành 0 và thay cho các phần tử con được đặt lại thành 1rem(tương đối)
Roko C. Buljan

9

Câu trả lời được chấp nhận là rất tốt, tuy nhiên điều này có thể được thực hiện với flexbox.

Đây là một hệ thống lưới được viết bằng cú pháp BEM cho phép hiển thị 1-10 cột trên mỗi hàng.

Nếu có hàng cuối cùng không đầy đủ (ví dụ: bạn chọn hiển thị 5 ô trên mỗi hàng và có 7 mục), các mục ở cuối sẽ được căn giữa theo chiều ngang. Để kiểm soát căn chỉnh ngang của các mục theo dõi, chỉ cần thay đổi thuộc justify-contenttính trong .square-gridlớp.

.square-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.square-grid__cell {
  background-color: rgba(0, 0, 0, 0.03);
  box-shadow: 0 0 0 1px black;
  overflow: hidden;
  position: relative;
}

.square-grid__content {
  left: 0;
  position: absolute;
  top: 0;
}

.square-grid__cell:after {
  content: '';
  display: block;
  padding-bottom: 100%;
}

// Sizes  Number of cells per row

.square-grid__cell--10 {
  flex-basis: 10%;
}

.square-grid__cell--9 {
  flex-basis: 11.1111111%;
}

.square-grid__cell--8 {
  flex-basis: 12.5%;
}

.square-grid__cell--7 {
  flex-basis: 14.2857143%;
}

.square-grid__cell--6 {
  flex-basis: 16.6666667%;
}

.square-grid__cell--5 {
  flex-basis: 20%;
}

.square-grid__cell--4 {
  flex-basis: 25%;
}

.square-grid__cell--3 {
  flex-basis: 33.333%;
}

.square-grid__cell--2 {
  flex-basis: 50%;
}

.square-grid__cell--1 {
  flex-basis: 100%;
}

Fiddle: https://jsfiddle.net/patrickber siêu / noLm1r45 / 3 /

Điều này đã được thử nghiệm trong FF và Chrome.


3
Tuy nhiên, bạn đang sử dụng phần đệm dưới để cố định chiều cao, vì vậy đây thực sự là một câu trả lời giống như được chấp nhận. Sự khác biệt duy nhất là cách lưới được tạo ra, không phải ô vuông.
extempl

0

Tôi sử dụng giải pháp này cho các hộp đáp ứng của các khẩu phần khác nhau:

HTML:

<div class="box ratio1_1">
  <div class="box-content">
            ... CONTENT HERE ...
  </div>
</div>

CSS:

.box-content {
  width: 100%; height: 100%;
  top: 0;right: 0;bottom: 0;left: 0;
  position: absolute;
}
.box {
  position: relative;
  width: 100%;
}
.box::before {
    content: "";
    display: block;
    padding-top: 100%; /*square for no ratio*/
}
.ratio1_1::before { padding-top: 100%; }
.ratio1_2::before { padding-top: 200%; }
.ratio2_1::before { padding-top: 50%; }
.ratio4_3::before { padding-top: 75%; }
.ratio16_9::before { padding-top: 56.25%; }

Xem bản demo trên JSfiddle.net


2
Sẽ có ích nếu bạn giải thích thêm về câu trả lời của mình ... hoặc thậm chí bao gồm một JSFiddle
Wavesailor
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.