【问题标题】:Flexbox, responsive grid of square divs maintaining aspect ratioFlexbox,保持纵横比的方形 div 响应网格
【发布时间】:2015-12-08 20:33:23
【问题描述】:

我正在尝试使用 div 创建一个 2x2 网格。一些 div 可能包含一个图像,但它可能会被设置为背景,带有选项 background-size: cover

这是我创建的笔:http://codepen.io/qarlo/pen/vLEprq

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  margin: auto;
  max-width: 960px;
  width: 80%;
}
.container__item {
  align-content: center;
  border: 1px solid #333;
  display: flex;
  flex-basis: 1;
  font-size: 3em;
  justify-content: center;
  height: 100%;
  margin-bottom: 1em;
  min-height: 300px;
  width: 47%;
}
<div class="container">
  <div class="container__item">?</div>
  <div class="container__item">?</div>
  <div class="container__item">?</div>
  <div class="container__item">?</div>
</div>

我想强制 div 为正方形,并在调整大小时保持纵横比。我错误地希望这对 flexbox 来说是直截了当的,但除非我遗漏了什么,否则我错了。

【问题讨论】:

  • @SalmanA,谢谢,但它在 Firefox 上不起作用,甚至在 Chrome 上似乎也起作用,我失去了内容的对齐方式

标签: css flexbox grid-layout aspect-ratio


【解决方案1】:

要保持物品的纵横比,一个非常简单的方法是使用CSS Viewport units

我修改了你的笔,看看这个单元是如何工作的:http://codepen.io/vladbicu/pen/wMBmOb

.container {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    margin: auto;
    max-width: 960px;
    width: 80%;
}

.container__item {
    align-content: center;
    border: 1px solid #333;
    display: flex;
    flex-basis: 1;
    font-size: 3em;
    justify-content: center;
    margin-bottom: 1em;

    // maintain aspect ratio
    width: 30vw;
    height: 30vw;
}

希望对你有帮助。

【讨论】:

  • 这很好,但是这样看来 align-content: center 不再起作用了,是吗?
  • 如果你想垂直对齐你的内容,使用 align-items: center on container__item div。检查此blog post 以查看 align-content 和 align-items 之间的区别。
  • 我实际上知道其中的区别,但我错误地使用了另一个。嗯,这很棒,我认为这是最好的解决方案。谢谢
  • Flex-basis 不是 1. 查看文档developer.mozilla.org/en-US/docs/Web/CSS/flex-basis
【解决方案2】:

old "padding-bottom" trick 用于固定纵横比。但是需要额外的 div:

.container {
  margin: auto;
  width: 80%;
  max-width: 960px;
}
.container__square {
  float: left;
  position: relative;
  padding-bottom: 50%;
  width: 50%;
  background: linear-gradient(45deg, #CCC, #000, #CCC);
}
.container__square__item {
  position: absolute;
  top: 1em;
  bottom: 1em;
  left: 1em;
  right: 1em;
  border: 1px solid #333;
  background: #FFF;
}
/* clearfix */
.container::after {
  content: "";
  display: block;
  clear: both;
}
<div class="container">
  <div class="container__square">
    <div class="container__square__item">?</div>
  </div>
  <div class="container__square">
    <div class="container__square__item">?</div>
  </div>
  <div class="container__square">
    <div class="container__square__item">?</div>
  </div>
  <div class="container__square">
    <div class="container__square__item">?</div>
  </div>
</div>

【讨论】:

  • 这行得通,是一个不错的解决方案,但它没有使用 flexbox。所以我猜 flexbox 属性根本不足以解决这个问题(还没有?)
  • @Carlo 据我所知没有 flexbox 解决方案。您仍然可以将 flexbox 用于 .container.container__square 而不是浮动。我使用浮点数是因为它的老派很像填充技巧。
【解决方案3】:

如果您想使用 flex-box 布局,您可能必须至少设置 min-height 以保持调整大小时的纵横比。

这是一个快速而肮脏的例子。

function setCellsMinHeight (parentSelector, cellsMargin, aspect) {
  var winWidth = window.innerWidth,
      containerList = document.querySelectorAll(parentSelector),
      containerArray = Array.prototype.slice.call(containerList),
      childMargin = cellsMargin;

  containerArray.forEach(function(elem) {
    var containerWidth = elem.offsetWidth,
        childCount = elem.children.length,
        childWidth = (containerWidth - ((childMargin * 2) * childCount)) / childCount,
        childMinHeight = (childWidth / 100) * aspect;
    for (i = 0; i < childCount; i++) {
      elem.children[i].style.margin = childMargin + "px";
      elem.children[i].style.minHeight = childMinHeight + "px";
    }
  });
}

window.onresize = function(event) {
  setCellsMinHeight('.container', 4, 100);
};

setCellsMinHeight('.container', 4, 100);
body {
  margin: 0;
}
.container {
  display: flex;
  flex-flow: row wrap;
  align-items: stretch;
  max-width: 100%;
  margin: 0 auto;
}

.content-cell {
  flex: 1;
  background-color: #ccc;
}

@media (min-width: 801px) {
  .container {
    max-width: 800px;
  }
}
<div class="container">
  <div class="content-cell"></div>
  <div class="content-cell"></div>
</div>

<div class="container">
  <div class="content-cell"></div>
  <div class="content-cell"></div>
</div>

希望对你有帮助。

【讨论】:

  • 感谢您的脚本,它似乎可以工作,但又一次:我想实施 flexbox 解决方案的主要原因是避免棘手的变通方法并仅依赖于 flexbox,但似乎仍然不可能
【解决方案4】:

据我了解,我认为您一直都需要灵活的盒子,这样您就可以使用 JavaScript 来执行此操作。

  1. 查找内容的最高高度
  2. 为整个班级分配最高的宽度和高度

这就是你如何维护灵活的盒子

或者你可以使用外部库

  1. Css tricks
  2. JQuery Flexbox

【讨论】:

  • 将内容的最高高度设置为所有元素不会使它们响应,但是。此外,从我的示例中,您可以看到内容也可以只是一个字符。 CSS 技巧文章只是一个关于 flexbox 的教程,不是吗?
  • 是的,这就是您想要的具有相同和方形高度的正确响应式网格
  • 但是仅仅找到最高高度是不够的,因为它不会在调整大小时自动调整。
猜你喜欢
  • 2017-07-11
  • 2014-07-15
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
  • 1970-01-01
  • 2012-08-20
相关资源
最近更新 更多