javascript - 使用 flexbox 在容器中动态调整盒子
问题描述
我想使用 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);
这是相同的小提琴。
解决方案
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>
推荐阅读
- python - TensorFlow 自定义损失类保存和加载
- verilog - Verilog 波形显示一些变量的蓝线和 Hiz
- python - class().method() 和 class.method() 可以做不同的事情吗?
- java - Android - FTPS 会话重用 - 无字段 sessionHostPortCache
- python - 当我在 python 中绘制导入的 excel 文件时,xticks 重叠并聚集在左侧。我该如何解决?
- vue.js - Vue中如何顺利引用公共目录中的图片?
- java - 使用 java 实现 Trie
- php - 循环通过 php 中的 x 个数据列表下拉列表
- javascript - 带有 javascript 的 HTML 画布
- r - 如何从整个世界栅格和该特定国家的 shapefile 绘制特定国家/地区的地图?