CSS网格正方形布局

时间:2019-02-28 13:45:18

标签: html css css3 css-grid

我正在尝试创建由正方形组成的网格/布局。每行四个正方形。正方形在屏幕调整大小时不会变形。宽度和高度必须始终保持相同(我不需要固定值)。我必须使用CSS网格。谁能帮我吗?

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-gap: 5px;
}
.container div {
  background-color: red;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

4 个答案:

答案 0 :(得分:7)

仅使用CSS,您可以使用伪元素将纵横比始终保持为1:1,例如

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-gap: 5px;
}
.container div {
  background-color: red;
}

.container div::before {
  content: "";
  padding-bottom: 100%;
  display: inline-block;
  vertical-align: top;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

答案 1 :(得分:7)

出于对grid行为的好奇心并避免使用伪元素

您还可以将高度设置为等于网格容器的宽度,网格系统将自动拉伸行。

  

提醒您:

     

https://css-tricks.com/snippets/css/complete-guide-grid/

     

和示例https://gridbyexample.com/


工作示例,如果您的网格使用了整个浏览器的宽度

  * {
  margin: 0;
  padding: 0;
}

.container {
  display: grid;
  height: calc(50vw - 5px);  /*instead playing around with grid gap gap */
  grid-template-columns: 1fr 1fr 1fr 1fr;
}

.container div {
  /* bg to show i'm squarred or not ? */
  background-image: linear-gradient( 45deg, transparent 50%, rgba(0, 0, 0, 0.5) 50%);
 
 margin: 0 5px 5px 0;  /*instead playing around with grid gap gap */
  background-color: red;
}


/* extra for demo, not needed */

.container {
  counter-reset: test;
}

.container div {
  display: flex;  /* or grid */
}

.container div:before {
  counter-increment: test;
  content: 'Div N°:'counter(test)' -';
  margin: auto;/* center me */
  color: yellow;
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

A codepen to fork or play with

答案 2 :(得分:4)

另一个技巧,您可以在其中放置任何内容而不破坏比率。想法是将网格放在一个大正方形内,然后将其分成小正方形:

.container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr;
  grid-gap: 5px;
}

.container div {
  background-color: red;
}

body:before {
  content: "";
  display: block;
  padding-top: 100%;
}

body {
  position: relative;
  margin: 0;
}

img {
  max-width: 100%;
  max-height: 100%;
}
<div class="container">
  <div>any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div>any contet here any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div></div>
</div>

没有position:absolute的另一种语法,您可以在其中依靠flexbox的拉伸功能:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr;
  grid-gap: 5px;
  flex-grow:1;
}

.container div {
  background-color: red;
}

body:before {
  content: "";
  padding-top: 100%;
}

body {
  display:flex;
}

img {
  max-width: 100%;
  max-height: 100%;
}
<div class="container">
<div>any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div>any contet here any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div></div>
</div>

您可以控制行数限制。在上面我把它们设为4,通过填充50%代替100%,我们只能有2个。我们将在内部有一个大矩形,其中将有8个正方形(每行4个)。

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  grid-gap: 5px;
  flex-grow:1;
}

.container div {
  background-color: red;
}

body:before {
  content: "";
  padding-top: 50%;
}

body {
  display:flex;
  margin: 0;
}

img {
  max-width: 100%;
  max-height: 100%;
}
<div class="container">
  <div>any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
</div>

您可以使用CSS变量控制行数:

:root {
  --n:6;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: repeat(var(--n),1fr);
  grid-gap: 5px;
  flex-grow:1;
}

.container div {
  background-color: red;
}

body:before {
  content: "";
  padding-top: calc(var(--n) * 25%);
}

body {
  display:flex;
}

img {
  max-width: 100%;
  max-height: 100%;
  display:block;
}
<div class="container">
  <div>any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div>any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
</div>

我们还可以通过添加另一个变量使列数更通用,从而控制列数:

:root {
  --n:6;
  --m:6;
}

.container {
  display: grid;
  grid-template-columns: repeat(var(--m),1fr);
  grid-template-rows: repeat(var(--n),1fr);
  grid-gap: 5px;
  flex-grow:1;
}

.container div {
  background-color: red;
}

body:before {
  content: "";
  padding-top: calc(var(--n)/var(--m) * 100%);
}

body {
  display:flex;
}

img {
  max-width: 100%;
  max-height: 100%;
}
<div class="container">
  <div>any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div>any contet here</div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div></div>
  <div></div>
  <div><img src="https://picsum.photos/200/300?image=1069"></div>
  <div></div>
  <div><img src="https://picsum.photos/200/200?image=1062"></div>
  <div>any contet here any contet here</div>
  <div></div>
  <div></div>
</div>

答案 3 :(得分:1)

** @fcalderan的答案解决了该问题,并保留了所有信用。 **

这显然会破坏正方形,但是如果您要使用任何文本,则进行一些小的调整将对您有利。您宁愿使用::after伪元素来不下推或拆分潜在内容。据我所知,更改为display: block也消除了vertical-aling: top的必要性。

为了在使用文本时进一步保持宽高比,我将文本设置为position: absolute

使用::before::after来说明我的观点时,请参见下面的代码段。

.container,
.container2 {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-gap: 5px;
}
.container div {
  background-color: red;
}

.container div::before {
  content: "";
  padding-bottom: 100%;
  display: inline-block;
  vertical-align: top;
}

.container2 div::after {
  content: "";
  padding-bottom: 100%;
  display: block;
}

.container2 .text {
  position: absolute;  
}

.container2 div {
  background-color: green;
  position: relative;
  overflow: hidden;
}
<div class="container">
  <div>
    <div class="text">Here is some text.</div>
  </div>
  <div>
    <div class="text">Here is some more text.</div>
  </div>
  <div>
    <div class="text">Here is some longer text that will break how this looks.</div>
  </div>
</div>
  
  <hr>
  <div class="container2">
  <div>
    <div class="text">Here is some text.</div>
  </div>
  <div>
    <div class="text">Here is some more text.</div>
  </div>
  <div>
    <div class="text">Here is some longer text that will break how this looks.</div>
  </div>
</div>