水平垂直居中
justify-content: main axis
align-items: cross axis
.parent {
display: flex;
justify-content: center;
align-items: center;
}
两端对齐(margin)
.header {
display: flex;
}
.header .image {
/* nothing needed! */
}
.header .sign-in {
margin-left: auto
}
Flex spec: Aligning with auto margins :
- 在计算 flex bases 和 flexible lengths 时, auto margins 被视为 0;
- auto margins 优先于对齐属性(justify-content、align-items、align-self)分配可用空间,使对齐属性不起作用;
- Overflowing boxes 会忽略 auto margins,并在尾部溢出。
<div class="container">
<div class="box">
<div>About</div>
<div class="item">Authoritarianism</div>
<div>Blog</div>
</div>
<div class="box">
<div>About</div>
<div class="item">Authoritarianism</div>
<div>Blog</div>
</div>
</div>
.container {
display: flex;
justify-content: center;
.box {
display: flex;
flex-direction: column;
margin: 20px 60px;
padding: 5px;
width: 100px;
border-radius: 8px;
background: #999;
&:first-child {
.item {
margin: auto;
}
}
&:last-child {
.item {
align-self: center;
}
}
div {
border-radius: 8px;
background: #eee;
margin: 5px;
padding: 5px;
}
}
}
flex item 不会发生外边距塌陷 margin collapse
栅格布局
flex-direction : row/column 设置排列方向;
justify-content / align-items:主轴 / 交叉轴方向的排列方式;space-around 和 space-between 可以简单实现均匀隔开 item;
flex item 设置:flex: flex-grow flex-shrink flex-basis
- 当空间不足时压缩,但任何时候都不要拉伸:
flex: 0 1 auto
- 当有多余空间时拉伸,当空间不足时压缩:
flex: 1 1 auto
或flex: auto
- 任何时候都不压缩也不拉伸:
flex: 0 0 auto
或flex: none
- 单一非负数字:该值为 flex-grow 值,
flex: flex-grow 1 0%
,例如flex: 2
- 长度或百分比:该值为flex-basis的值,
flex: 1 1 flex-basis
,例如flex: 0% 或 flex: 100px
- 2个非负数字:
flex: flex-grow flex-shrink 0%
,例如flex: 2 1
- 1个非负数字和长度或百分比:
flex: flex-grow 1 flex-basis
,例如flex: 1 100px
<div class="container">
<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>
.container {
display: flex;
flex: 1;
width: 400px;
flex-wrap: wrap;
}
.container > div {
text-align: center;
width: 100px;
box-shadow: 0 0 1px #000;
}
flex item 实际尺寸计算
.parent {
display: flex;
width: 600px;
}
.parent > div {
height: 100px;
}
.item-1 {
width: 140px;
flex: 2 1 0%;
}
.item-2 {
width: 100px;
flex: 2 1 auto;
}
.item-3 {
flex: 1 1 200px;
}
- 主轴父元素 parent 宽度:600px
- flex-basis:基准值
- 0%:0 宽度
- auto:等于 item 的 width,例如 item-2 的基准值为 100px
- 200px:固定值
- 剩余空间 = 父元素宽度 - 子元素总基准值,即 600 - (0 + 100 + 200) = 300
- flex-grow: 放大比例,2 + 2 + 1 = 5
- 按放大比例分配剩余空间
- item-1 为 2/5 即 120px
- item-2 为 2/5 即 120px
- item-3 为 1/5 即 60px
- 结果:
- item-1 为 0 + 120 = 120px
- item-2 为 100 + 120 = 220px
- item-3 为 1/5 即 200 + 60 = 260px
flex-direction: column 时,flex-wrap: wrap 无法撑开父元素 width
stackOverflow: When flexbox items wrap in column mode, container does not grow its width
.parent {
display: flex;
flex-direction: row; // column 时无法撑开父元素
flex-wrap: wrap;
}
实现两端对齐排列时最后一行如何左对齐
<div class="container">
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
</div>
.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list {
width: 24%; height: 100px;
background-color: skyblue;
margin-top: 15px;
}
元素宽度固定,最后一行动态 margin
.container {
display: flex;
/* 两端对齐 */
justify-content: space-between;
flex-wrap: wrap;
}
.list {
width: 24%; height: 100px;
background-color: skyblue;
margin-top: 15px;
}
/* 如果最后一行是3个元素 */
.list:last-child:nth-child(4n - 1) {
margin-right: calc(24% + 4% / 3);
}
/* 如果最后一行是2个元素 */
.list:last-child:nth-child(4n - 2) {
margin-right: calc(48% + 8% / 3);
}
元素宽度不固定,
最后一项margin-right:auto
.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list {
background-color: skyblue;
margin: 10px;
}
/* 最后一项margin-right:auto */
.list:last-child {
margin-right: auto;
}
创建伪元素并设置flex:auto或flex:1
.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list {
background-color: skyblue;
margin: 10px;
}
/* 使用伪元素辅助左对齐 */
.container::after {
content: '';
flex: auto; /* 或者flex: 1 */
}
每行列数不固定
使用足够的空白标签进行填充占位,具体的占位数量是由最多列数的个数决定的,例如这个布局最多7列,那我们可以使用7个空白标签进行填充占位,最多10列,那我们需要使用10个空白标签。
<div class="container">
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<div class="list"></div>
<i></i><i></i><i></i><i></i><i></i>
</div>
.container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-right: -10px;
}
.list {
width: 100px; height:100px;
background-color: skyblue;
margin: 15px 10px 0 0;
}
/* 和列表一样的宽度和margin值 */
.container > i {
width: 100px;
margin-right: 10px;
}
css grid (兼容性不好)
.container {
display: grid;
justify-content: space-between;
grid-template-columns: repeat(auto-fill, 100px);
grid-gap: 10px;
}
.list {
width: 100px; height:100px;
background-color: skyblue;
margin-top: 5px;
}
参考链接
11 things I learned reading the flexbox spec
Flex spec: Aligning with auto margins
stackOverflow: When flexbox items wrap in column mode, container does not grow its width
https://www.zhangxinxu.com/wordpress/2019/08/css-flex-last-align/