在 flex 布局
中, 通过对子项设置 margin-auto;
的方式去吃掉剩余空间, 这种小技巧在很多时候能极大简化我们的布局哦.
单元素水平垂直居中
如果父容器是 flex, 要实现元素水平垂直居中, 直接在容器项添加:
display: flex;
justify-content: center;
align-items: center;
但其实我们可以直接给子项添加 margin: auto;
就搞定啦!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex + margin</title>
<style>
.main {
width: 500px;
height: 300px;
background-color: #ccc;
display: flex;
}
.main div {
width: 100px;
height: 100px;
background-color: pink;
/* 水平垂直居中 */
margin: auto;
}
</style>
</head>
<body>
<div class="main">
<div></div>
</div>
</body>
</html>
原理就是通过子项的 margin 去占满它 top / right / bottom / left 的空间. 四个方向都能设置, 那对齐方式就自由控制四个方向啦.
某些项靠右对齐
初始是这样的:
a, b, c
现在想要将 c 挤压到最右边去:
a, b, c
道理是一样的, 直接在子项中给 c 设置 margin-left: right
就搞定.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex + margin</title>
<style>
.main {
width: 500px;
height: 300px;
background-color: #ccc;
display: flex;
}
.main div {
width: 100px;
height: 100px;
background-color: pink;
}
.move {
margin-left: auto;
}
</style>
</head>
<body>
<div class="main">
<div>a</div>
<div>b</div>
<div class="move">c</div>
</div>
</body>
</html>
同理, 如果是要移动两个到右边也是一样的操作, 给 b 盒子设置上 margin-left: auto
即可.
a b, c
同理, 如果是要实现这样的效果, 也是直接找出 c 盒子, 左右 margin: auto; 就搞定.
ab c d
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex + margin</title>
<style>
.main {
width: 500px;
height: 300px;
background-color: #ccc;
display: flex;
}
.main div {
width: 100px;
height: 100px;
background-color: pink;
}
.move {
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
<div class="main">
<div>a</div>
<div>b</div>
<div class="move">c</div>
<div>d</div>
</div>
</body>
</html>
列表布局
子元素横向排列, 可以控制每行排列几个元素, 当排不下时, 自动换行.
就有点像二维布局了, 但这里我们不用 grid. 就非要用 flex 技巧.
如果在父容器上进行操作,
display: flex;
flex-wrap: wrap;
justify-content: space-between;
这样肯定是不行的, 不仅不能控制每一行的元素个数, 且最后一行的排列必定出问题哦.
但还是可以在子项设置 margin, 不过这里要给 margin 固定值哈, 类似设置这样就好:
.main div {
background-color: pink;
width: 30px;
height: 40px;
margin: 15px 20px;
}
假设我们现在每行要排列 7个盒子, 且知道每个盒子的宽度是定值 30px, 则剩余空间为父容器的宽度 100%
减去盒子宽度 乘7即可.
剩余宽度 = 100% - 盒宽 * 7
每个盒子的左右 margin 为: 剩余宽度 / 7 / 2
/* 每个盒子的左右 margin 为: 剩余宽度 / 7 / 2 */
margin: 10px calc((100% - 30px * 7) / 7 / 2);
最后可将每行排列几个设置为变量即可, 主要应用于页面做响应式的场景.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flex + margin</title>
<style>
.main {
width: 500px;
height: 300px;
background-color: #ccc;
display: flex;
/* 允许元素换行, 并设置交叉轴, 从起点开始放置元素 */
flex-wrap: wrap;
align-content: flex-start;
}
.main div {
width: 40px;
height: 40px;
background-color: pink;
/* --n: 7; */
/* --n: 10; */
--n: 6;
--gap: calc((100% - 40px * var(--n)) / var(--n) / 2);
margin: 10px var(--gap);
}
</style>
</head>
<body>
<div class="main">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
</div>
</body>
</html>
通过变量来动态计算 margin, 不仅是每行可以控制几个元素排列, 盒子大小也可以做变量, 就很强大哦!
实际项目中熟练应用这几个小技巧, 就已经很够用了. 尤其是左右布局的时候, margin-left: auto;
简直是一个神来之笔呢.