响应方块网格

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 添加到.contentRESULT

垂直对齐:

这变得严重了!诀窍是使用

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 来固定高度,因此实际上与接受的答案相同。唯一的区别是网格的制作方式,而不是方形网格。

以上是关于响应方块网格的主要内容,如果未能解决你的问题,请参考以下文章

响应式正方形网格内的响应式正方形网格

使用div标签的响应式俄罗斯方块网格

如何在响应式方形网格中仅使背景图像透明?

css 响应方块级元素

scss 创建响应方块

React Native - 响应式图像宽度(百分比?)