【问题标题】:CSS grid square layout [duplicate]CSS网格正方形布局[重复]
【发布时间】:2019-07-22 10:57:06
【问题描述】:

我正在尝试创建由正方形组成的网格/布局。每行四个方格。正方形不能在屏幕调整大小时扭曲。宽度和高度必须始终相同(我不想要固定值)。我必须使用 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>

【问题讨论】:

  • 如果你只想要正方形,只需将padding-bottom: 100%;添加到div,以防没有内容
  • @TemaniAfif 如果我有一些内容怎么办?
  • 我已经编辑了我的答案以获得更通用的内容

标签: html css css-grid


【解决方案1】:

只有使用 CSS,您才能使用伪元素将纵横比始终保持为 1:1 或使用新的 aspect-ratio 属性,例如

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

【讨论】:

  • 内联阻塞和不阻塞的任何特殊原因?
  • 为了好奇,在这种情况下垂直对齐有什么用?
  • @guitarzero 在 line-height 默认设置为基线时避免底部的 4pixel 间隙
  • @TemaniAfif 你也可以使用显示块。但是如果您需要在元素内放置一些数据,最好使用 inline-block,这样数据就不会移动到伪元素下方
  • 为什么不直接为.container div 设置padding-bottom: 100%height: 0 而不使用任何伪元素?
【解决方案2】:

为了乐趣,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 行,您的高度技巧将起作用,应根据行数进行调整
  • @TemaniAfif ,那么 height 将设置在 children 上。请注意,50vw(父母为 2 行)为孩子降低到 25vw ;)
  • 一个小问题,就是 vw 包含滚动条,所以当有滚动条时你不会有完美的正方形
  • 另外,如果你不知道容器的宽度,这也行不通。
【解决方案3】:

另一个技巧,您可以在不破坏比例的情况下将任何内容放入其中。这个想法是将网格放在一个大正方形内,然后将其分成小正方形:

.container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(4,minmax(0,1fr));
  grid-template-rows: repeat(4,minmax(0,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>

您可以控制行数限制。在上面我将它们设为 4,通过使用填充 50% 而不是 100%,我们只能得到 2。我们将有一个大矩形,里面有 8 个正方形(每行 4 个)。

.container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(4,minmax(0,1fr));
  grid-template-rows: repeat(2,minmax(0,1fr));
  grid-gap: 5px;
}

.container div {
  background-color: red;
}

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

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>

您可以使用 CSS 变量控制行数或列数,并拥有更通用的东西:

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

.container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(var(--m),minmax(0,1fr));
  grid-template-rows: repeat(var(--n),minmax(0,1fr));
  grid-gap: 5px;
}

.container div {
  background-color: red;
}

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

body {
  position:relative;
}

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>

【讨论】:

  • 你能解释一下这段代码吗? body:before { content: ""; padding-top: calc(var(--n)/var(--m) * 100%); }
  • @FredHors 它允许保持整个网格的比例......如果我们有相同数量的行和列,我们应该有一个正方形,因此它在填充中将是 100%,因为填充考虑宽度作为参考,它会增加高度,所以高度=宽度......如果我们有 n 行和 m 列,则比率是 n/m(不再是正方形)所以高度应该是 (n/m)*width 这就是为什么填充需要为 n/m*100%
  • 这些不是正方形。
【解决方案4】:

** @fcalderan 的回答解决了这个问题并保留所有信用。 **

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

为了在使用文本时进一步保持纵横比,我会将文本设为position: absolute

使用::before::after 时请参阅下面的sn-p 来说明我的观点。

.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>

【讨论】:

  • 我们在这两种情况下都不再有正方形
  • 你确实是对的@TemaniAfif 并且刚刚进行了编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-25
  • 2019-03-24
  • 1970-01-01
  • 2019-08-01
  • 2018-06-22
  • 1970-01-01
相关资源
最近更新 更多