响应正方形网格

我想知道我将如何去创建一个与 响应正方形布局。每个正方形都有 垂直和水平排列内容。具体的示例如下所示..。

responsive squares with content

212442 次浏览

新解决方案(2022)

自从编写这个答案以来,CSS 已经发生了变化。我们现在有几个属性可以极大地简化正方形网格的代码:

  • 处理网格布局的 网格属性(MDN 参考资料)
  • 用于处理每个网格项(MDN 参考资料)的平方长宽比的 长宽比属性
  • 合身的衣服属性用于处理图像居中以及它们是否应该覆盖正方形(MDN 参考资料)

这里有一个例子:

.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2%;
}


.square {
aspect-ratio: 1/ 1;
display: flex;
align-items: center;
padding: 5%;
background-color: #1E1E1E;
color: #fff;
}


.square img {
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}


.square.fullImg {
padding: 0;
}


.square.fullImg img {
object-fit: cover;
}
<div class="grid">
<div class="square">
<ul>This demo shows you can center multiple types of content :
<li>Text</li>
<li>Images</li>
<li>Lists</li>
<li>... (you can also do it with forms)</li>
</ul>
</div>
<div class="square">98%</div>
<div class="square">3.9/5</div>
<div class="square"><img src="https://farm3.staticflickr.com/2878/10944255073_973d2cd25c.jpg" /></div>
<div class="square"><img src="https://farm9.staticflickr.com/8461/8048823381_0fbc2d8efb.jpg" /></div>
<div class="square"><img class="rs" src="https://farm5.staticflickr.com/4144/5053682635_b348b24698.jpg" /></div>
<div class="square fullImg"><img src="https://farm9.staticflickr.com/8461/8048823381_0fbc2d8efb.jpg" /></div>
<div class="square fullImg"><img class="rs" src="https://farm5.staticflickr.com/4144/5053682635_b348b24698.jpg" /></div>
<div class="square fullImg"><img src="https://farm3.staticflickr.com/2878/10944255073_973d2cd25c.jpg" /></div>
</div>



前一个答案

这仍然可以工作,但是 CSS 自从编写以来已经发生了变化,ne 属性可以使代码更简单、更容易理解。

您可以使 响应式正方形网格与垂直和水平 中心内容只与 CSS。我将一步一步地解释如何做到这一点,但首先这里有两个演示,你可以实现:

Responsive 3x3 square grid Responsive square images in a 3x3 grid

现在让我们看看如何制作这些奇妙的响应方块!



1. 制作响应方块:

保持元素平方的诀窍(或者任何其他的纵横比)是使用百分比 padding-bottom
注意: 您也可以使用顶部填充或顶部/底部边距,但元素的背景不会显示。

由于顶部填充是根据 父元素(参见 MDN)的宽度计算的,因此元素的高度将根据其宽度而变化。您现在可以根据 保持它的长宽比的宽度。
此时,您可以编写代码:

HTML :

<div></div>

CSS :

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

这是一个使用上面代码的3 * 3正方形网格的 一个简单的布局例子

使用这种技术,您可以创建任何其他的长宽比,这里有一个表格,根据长宽比和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. 在正方形内添加内容:

因为你不能直接在正方形内部添加内容(这样会扩大它们的高度,而正方形不再是正方形) ,所以你需要用 position: absolute;在正方形内部创建子元素(对于这个例子,我使用 div) ,并将内容放在正方形内部。这将使内容脱离流,并保持正方形的大小。

不要忘记在父 div 上添加 position:relative;,这样绝对子节点的位置/大小就相对于父节点来说。

让我们在3x3的正方形网格中添加一些内容:

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%;
}

结果 < ——使用一些格式使其更美观!


3. 以内容为中心:

横向:

这非常简单,只需要将 text-align:center添加到 .content
结果

垂直排列:

这就严重了! 诀窍是使用

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

但是 我们不能在 .square.content div 上使用 display:table;,因为它与 position:absolute;冲突,所以我们需要在 .content div 内创建两个子节点。我们的代码将更新如下:

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%;
}

我们现在已经完成了,我们可以在这里看看结果:

全屏直播结果

可编辑的小提琴


您可以使用 vw (视图宽度)单位,它可以根据屏幕的宽度使正方形响应。

一个简单的模型如下:

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>

接受的答案是伟大的,但这可以做到与 flexbox

下面是一个用 BEM 语法编写的网格系统,它允许每行显示1-10列。

如果最后一行不完整(例如,您选择每行显示5个单元格,并且有7个项目) ,则尾随的项目将水平居中。要控制尾随项的水平对齐,只需更改 .square-grid类下的 justify-content财产

.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%;
}

.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%;
}
<div class='square-grid'>
<div class='square-grid__cell square-grid__cell--7'>
<div class='square-grid__content'>
Some content
</div>
</div>
<div class='square-grid__cell square-grid__cell--7'>
<div class='square-grid__content'>
Some content
</div>
</div>
<div class='square-grid__cell square-grid__cell--7'>
<div class='square-grid__content'>
Some content
</div>
</div>
<div class='square-grid__cell square-grid__cell--7'>
<div class='square-grid__content'>
Some content
</div>
</div>
<div class='square-grid__cell square-grid__cell--7'>
<div class='square-grid__content'>
Some content
</div>
</div>
<div class='square-grid__cell square-grid__cell--7'>
<div class='square-grid__content'>
Some content
</div>
</div>
<div class='square-grid__cell square-grid__cell--7'>
<div class='square-grid__content'>
Some content
</div>
</div>
<div class='square-grid__cell square-grid__cell--7'>
<div class='square-grid__content'>
Some content
</div>
</div>
</div>

小提琴: https://jsfiddle.net/patrickberkeley/noLm1r45/3/

这是在 FF 和 Chrome 中测试的。

我使用这个解决方案来处理不同口粮的响应箱:

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%; }

请看 JSfiddle.net上的演示

现在我们可以使用 aspect-ratio 翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳属性轻松地完成这项工作

.container {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr)); /* 3 columns */
grid-gap: 10px;
}


.container>* {
aspect-ratio: 1 / 1; /* a square ratio */
border: 1px solid;
  

/* center content */
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}


img {
max-width: 100%;
display: block;
}
<div class="container">
<div> some content here </div>
<div><img src="https://picsum.photos/id/25/400/400"></div>
<div>
<h1>a title</h1>
</div>
<div>more and more content <br>here</div>
<div>
<h2>another title</h2>
</div>
<div><img src="https://picsum.photos/id/104/400/400"></div>
</div>

也像下面这样,我们可以有一个可变数量的列

.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 10px;
}


.container>* {
aspect-ratio: 1 / 1; /* a square ratio */
border: 1px solid;
  

/* center content */
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}


img {
max-width: 100%;
display: block;
}
<div class="container">
<div> some content here </div>
<div><img src="https://picsum.photos/id/25/400/400"></div>
<div>
<h1>a title</h1>
</div>
<div>more and more content <br>here</div>
<div>
<h2>another title</h2>
</div>
<div><img src="https://picsum.photos/id/104/400/400"></div>
<div>more and more content <br>here</div>
<div>
<h2>another title</h2>
</div>
<div><img src="https://picsum.photos/id/104/400/400"></div>
</div>