【问题标题】:Fit boxes dynamically in a container with flexbox使用 flexbox 在容器中动态调整盒子
【发布时间】:2018-05-24 06:15:56
【问题描述】:

我想使用 flexbox 在容器中动态排列盒子。安排如下:

对于三个或四个盒子,盒子应该像第一张图片一样排列。 对于六个盒子,这些盒子应该适合两行三列。但是对于七个盒子,排列应该看起来像第二张图片中显示的那样,依此类推。

容器的宽度和高度是固定的。

这完全可以通过 Flexbox 实现吗?

HTML:

<div class="container">
  <div class="box">AB</div>
  <div class="box">CD</div>
  <div class="box">EF</div>
  <div class="box">GH</div>
  <div class="box">IJ</div>
  <div class="box">KL</div>
  <div class="box">MN</div>
  <div class="box">OP</div>
  <div class="box">QR</div>
  <div class="box">ST</div>
  <div class="box">UV</div>
  <div class="box">XY</div>
</div>

CSS:

.container {
  width: 160px;
  height: 160px;
  border: 1px solid blue;
  display: flex;
}

.box {
  border: 1px solid red;
  text-align: center;
}

JavaScript:

function align(nodes) {
    var nodeLength = nodes.length;
    if(nodeLength == 1) {
  // nodes occupies entire box
  }

  else if (nodeLength == 2) {
    // nodes displayed in two columns
  }

  else if(nodeLength > 2 && nodeLength < 5) {
  // nodes displayed in two rows, two columns
  }

  else if(nodeLength > 4 && nodeLength <= 6) {
  // display in two columns and three rows
  }

 /*
   .
   .
   .
   and so on
 */
}

var boxes = document.getElementsByClassName('box');

align(boxes);

Here 也是一样的。

【问题讨论】:

  • 如果我没记错的话,有办法。我只是不太熟悉它。尝试查看 css 网格。我认为有fill 属性可能会促进这一点。

标签: javascript html css flexbox


【解决方案1】:

Flexbox 解决方案(无 JavaScript)

如下计算正方形中每个项目的宽度和高度

.square-item {
  width: calc(100% / n);
  height: calc(100% / n);
}

n 是列数(或行数)。

示例

.square-wrapper {
  display: inline-block;
  vertical-align: top;
}

.square {
  --size: 160px;
}

.square {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  width: var(--size);
  height: var(--size);
}

.square>div {
  box-shadow: 1px 3px 3px #abc;
  position: relative;
}

.square p {
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.square.s-2_2>div {
  width: calc(100% / 2);
  height: calc(100% / 2);
}

.square.s-3_3>div {
  width: calc(100% / 3);
  height: calc(100% / 3);
}

.square.s-4_4>div {
  width: calc(100% / 4);
  height: calc(100% / 4);
}


/* Add more custom square classes */


/* ... */
<div class="square-wrapper">
  <div class="square s-2_2">
    <div>
      <p>1</p>
    </div>
    <div>
      <p>2</p>
    </div>
    <div>
      <p>3</p>
    </div>
    <div>
      <p>4</p>
    </div>
  </div>
</div>
<div class="square-wrapper">
  <div class="square s-3_3">
    <div>
      <p>1</p>
    </div>
    <div>
      <p>2</p>
    </div>
    <div>
      <p>3</p>
    </div>
    <div>
      <p>4</p>
    </div>
    <div>
      <p>5</p>
    </div>
    <div>
      <p>6</p>
    </div>
    <div>
      <p>7</p>
    </div>
    <div>
      <p>8</p>
    </div>
    <div>
      <p>9</p>
    </div>
  </div>
</div>
<div class="square-wrapper">
  <div class="square s-4_4">
    <div>
      <p>1</p>
    </div>
    <div>
      <p>2</p>
    </div>
    <div>
      <p>3</p>
    </div>
    <div>
      <p>4</p>
    </div>
    <div>
      <p>5</p>
    </div>
    <div>
      <p>6</p>
    </div>
    <div>
      <p>7</p>
    </div>
    <div>
      <p>8</p>
    </div>
    <div>
      <p>9</p>
    </div>
    <div>
      <p>10</p>
    </div>
    <div>
      <p>11</p>
    </div>
    <div>
      <p>12</p>
    </div>
    <div>
      <p>13</p>
    </div>
    <div>
      <p>14</p>
    </div>
    <div>
      <p>15</p>
    </div>
    <div>
      <p>16</p>
    </div>
  </div>
</div>

使用 flexbox 的 JavaScript 解决方案

获取所有.square。遍历它们并遍历它们的子元素,并为每个子元素添加样式。

child.setAttribute("style", "width: ...; height: ...")

大小为calc(100% / Math.sqrt(number of square items))

示例

var squares = document.querySelectorAll(".square");

for (var i = 0; i < squares.length; i += 1) {
  for (var j = 0; j < squares[i].children.length; j += 1) {
    var child = squares[i].children[j],
      size = "calc(100% /" + Math.ceil(Math.sqrt(squares[i].children.length)) + ")";
    child.setAttribute("style", "width: " + size + "; height: " + size);
  }
}
.square-wrapper {
  display: inline-block;
  vertical-align: top;
}

.square {
  --size: 160px;
}

.square {
  display: flex;
  flex-wrap: wrap;
  align-content: start;
  width: var(--size);
  height: var(--size);
}

.square>div {
  box-shadow: 1px 3px 3px #abc;
  position: relative;
}

.square p {
  margin: 0;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<div class="square-wrapper">
  <div class="square">
    <div>
      <p>1</p>
    </div>
    <div>
      <p>2</p>
    </div>
    <div>
      <p>3</p>
    </div>
    <div>
      <p>4</p>
    </div>
    <div>
      <p>5</p>
    </div>
  </div>
</div>

<div class="square-wrapper">
  <div class="square">
    <div>
      <p>1</p>
    </div>
    <div>
      <p>2</p>
    </div>
    <div>
      <p>3</p>
    </div>
    <div>
      <p>4</p>
    </div>
  </div>
</div>
<div class="square-wrapper">
  <div class="square">
    <div>
      <p>1</p>
    </div>
    <div>
      <p>2</p>
    </div>
    <div>
      <p>3</p>
    </div>
    <div>
      <p>4</p>
    </div>
    <div>
      <p>5</p>
    </div>
    <div>
      <p>6</p>
    </div>
    <div>
      <p>7</p>
    </div>
    <div>
      <p>8</p>
    </div>
    <div>
      <p>9</p>
    </div>
  </div>
</div>
<div class="square-wrapper">
  <div class="square">
    <div>
      <p>1</p>
    </div>
    <div>
      <p>2</p>
    </div>
    <div>
      <p>3</p>
    </div>
    <div>
      <p>4</p>
    </div>
    <div>
      <p>5</p>
    </div>
    <div>
      <p>6</p>
    </div>
    <div>
      <p>7</p>
    </div>
    <div>
      <p>8</p>
    </div>
    <div>
      <p>9</p>
    </div>
    <div>
      <p>10</p>
    </div>
    <div>
      <p>11</p>
    </div>
    <div>
      <p>12</p>
    </div>
    <div>
      <p>13</p>
    </div>
    <div>
      <p>14</p>
    </div>
    <div>
      <p>15</p>
    </div>
    <div>
      <p>16</p>
    </div>
  </div>
</div>

【讨论】:

  • 感谢您的回答。但是,您已经稍微更改了影响代码的标记。我用你遵循的类似方法自己解决了这个问题。基本上通过boxWidth = containerWidth/Math.ceil(Math.sqrt(nodes.length))计算每个框的宽度。然后将内联样式应用于宽度设置为boxWidth 的所有框。当然,我还必须对容器框使用 flexbox 样式来实现所需的行为:display: flex; flex-wrap: wrap; align-content: flex-start
  • 没错。我更改标记的原因是使用&lt;p&gt;&lt;/p&gt; 将内容水平和垂直居中。并取了不同的名称以使其更清晰。
猜你喜欢
  • 1970-01-01
  • 2014-03-22
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-15
  • 2020-10-14
  • 1970-01-01
相关资源
最近更新 更多