响应方块网格
Posted
技术标签:
【中文标题】响应方块网格【英文标题】:Grid of responsive squares 【发布时间】:2013-12-25 17:45:47 【问题描述】:我想知道如何使用响应式方块创建布局。每个方块都有垂直和水平对齐的内容。具体示例如下图...
【问题讨论】:
我讨厌答案很好的问题会被那些对 *** 应该是什么样子有着非常迂腐观点的人随机关闭。如果他们有好的、接受的、赞成的答案……为什么要关闭它???哪里有混乱?当然,就其自身的“响应式方块网格”而言,可能需要一点或很多解释,但这是一个 7 岁、160 多个问题和 400 多个答案的问题。我正在重新投票。 【参考方案1】:您只能使用 CSS 制作具有垂直和水平居中内容的响应式正方形网格。我将逐步解释如何进行,但首先这里有 2 个演示,说明您可以实现的目标:
Grid of square images Grid of squares with content
现在让我们看看如何制作这些花哨的响应方块!
1.制作响应方块:
保持元素正方形(或任何其他纵横比)的技巧是使用百分比padding-bottom
。旁注:您也可以使用顶部填充或顶部/底部边距,但元素的背景不会显示。
由于顶部填充是根据父元素 (See MDN for reference) 的宽度计算的,因此元素的高度将根据其宽度而变化。您现在可以根据其宽度保持其纵横比。 此时可以编码:
html:
<div></div>
CSS:
div
width: 30%;
padding-bottom: 30%; /* = width for a square aspect ratio */
这是一个 simple layout example 的 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。在方块内添加内容:
由于您不能直接在正方形内添加内容(它会扩大它们的高度并且正方形不再是正方形),因此您需要在其中创建子元素(在此示例中我使用 div)position: absolute;
并将内容放入其中。这会将内容从流中取出并保持正方形的大小。
不要忘记在父 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%;
RESULT
3。内容居中:
水平:
这很简单,您只需将text-align:center
添加到.content
。RESULT
垂直对齐:
这变得严重了!诀窍是使用
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%;
我们现在已经完成了,我们可以在这里看看结果:
LIVE FULLSCREEN RESULT
editable fiddle here
【讨论】:
@d.raev 是的。百分比填充和边距是根据父项的宽度计算的。在这里检查填充developer.mozilla.org/en-US/docs/Web/CSS/padding 这很棒。提醒其他人:如果您使用* box-sizing: border-box;
,则需要将 .content div 中的高度和宽度调整为 100%。 :)
保证金值背后的计算方法是什么?如果我想设置一个 5x5 的网格怎么办?
@kiwi1342 all 边距的总和 + 一行的所有宽度必须等于 100%。因此,对于 5x5 网格,您可以在元素的每一侧使用 18% 的宽度和 1% 的边距。
太棒了。请注意:要水平和垂直居中,只需将 .content 设置为带有 justify-content: center; align-items: center; flex-flow: column nowrap;
的弹性框【参考方案2】:
现在我们可以使用aspect-ratio
ref 属性轻松做到这一点
.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>
【讨论】:
【参考方案3】:我将此解决方案用于不同口粮的响应盒:
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上查看演示
【讨论】:
【参考方案4】:您可以使用 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>
【讨论】:
不要使用margin-left: -4px;
使用margin-right:-4px
。宁可不要混淆 mincharspace 中的不一致,而是将包装父字体大小设置为 0,而不是将子元素重置为 1rem
(relative-em)【参考方案5】:
接受的答案很好,但是可以使用flexbox
来完成。
这是一个使用BEM syntax 编写的网格系统,允许每行显示 1-10 列。
如果最后一行不完整(例如,您选择每行显示 5 个单元格并且有 7 个项目),则尾随项目将水平居中。要控制尾随项目的水平对齐方式,只需更改 .square-grid
类下的 justify-content
property。
.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 中测试的。
【讨论】:
仍然,您正在使用 padding-bottom 来固定高度,因此实际上与接受的答案相同。唯一的区别是网格的制作方式,而不是方形网格。以上是关于响应方块网格的主要内容,如果未能解决你的问题,请参考以下文章