Flexbox, responsive grid of square divs maintaining aspect ratio

喜你入骨 提交于 2019-12-07 01:16:53

问题


I'm trying to create a 2x2 grid with divs. Some of the divs might contain an image, but it will probably be set as a background, with the option background-size: cover.

Here's the pen I created: 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>

I'd like to force the divs to be squares and maintain the aspect ratio when resizing it. I was mistakenly hoping that this would have been straightforward with flexbox, but unless I'm missing something, I was wrong.


回答1:


To maintain your items aspect ratio, a very simple method is to use CSS Viewport units

I modified your pen to see how this units work: 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;
}

Hope it helps.




回答2:


Use the old "padding-bottom" trick for fixed aspect ratio. Extra divs are reqiured though:

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



回答3:


Guess you would have to set at least the min-height to maintain the aspect ration on re-size, if you want to go with a flex-box layout.

Here is a quick and dirty example.

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>

Hope it helps.




回答4:


As i understand i think you want flexible boxes all the time so you can perform this action by using JavaScript.

  1. Find the Highest height of the content
  2. assign that highest width and height for the whole classes

and that's how you can maintain flexible boxes

or you can use external library

  1. Css tricks
  2. JQuery Flexbox


来源:https://stackoverflow.com/questions/34152213/flexbox-responsive-grid-of-square-divs-maintaining-aspect-ratio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!