水平垂直居中

justify-content: main axis
align-items: cross axis

  1. .parent {
  2. display: flex;
  3. justify-content: center;
  4. align-items: center;
  5. }

两端对齐(margin)

flex_margin.png

  1. .header {
  2. display: flex;
  3. }
  4. .header .image {
  5. /* nothing needed! */
  6. }
  7. .header .sign-in {
  8. margin-left: auto
  9. }

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,并在尾部溢出。

flex-margin.jpg

  1. <div class="container">
  2. <div class="box">
  3. <div>About</div>
  4. <div class="item">Authoritarianism</div>
  5. <div>Blog</div>
  6. </div>
  7. <div class="box">
  8. <div>About</div>
  9. <div class="item">Authoritarianism</div>
  10. <div>Blog</div>
  11. </div>
  12. </div>
  1. .container {
  2. display: flex;
  3. justify-content: center;
  4. .box {
  5. display: flex;
  6. flex-direction: column;
  7. margin: 20px 60px;
  8. padding: 5px;
  9. width: 100px;
  10. border-radius: 8px;
  11. background: #999;
  12. &:first-child {
  13. .item {
  14. margin: auto;
  15. }
  16. }
  17. &:last-child {
  18. .item {
  19. align-self: center;
  20. }
  21. }
  22. div {
  23. border-radius: 8px;
  24. background: #eee;
  25. margin: 5px;
  26. padding: 5px;
  27. }
  28. }
  29. }

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 autoflex: auto
  • 任何时候都不压缩也不拉伸:flex: 0 0 autoflex: 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

flex-grid.jpg

  1. <div class="container">
  2. <div>1</div>
  3. <div>2</div>
  4. <div>3</div>
  5. <div>4</div>
  6. <div>5</div>
  7. <div>6</div>
  8. <div>7</div>
  9. <div>8</div>
  10. <div>9</div>
  11. </div>
  1. .container {
  2. display: flex;
  3. flex: 1;
  4. width: 400px;
  5. flex-wrap: wrap;
  6. }
  7. .container > div {
  8. text-align: center;
  9. width: 100px;
  10. box-shadow: 0 0 1px #000;
  11. }

flex item 实际尺寸计算

  1. .parent {
  2. display: flex;
  3. width: 600px;
  4. }
  5. .parent > div {
  6. height: 100px;
  7. }
  8. .item-1 {
  9. width: 140px;
  10. flex: 2 1 0%;
  11. }
  12. .item-2 {
  13. width: 100px;
  14. flex: 2 1 auto;
  15. }
  16. .item-3 {
  17. flex: 1 1 200px;
  18. }
  • 主轴父元素 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

  1. .parent {
  2. display: flex;
  3. flex-direction: row; // column 时无法撑开父元素
  4. flex-wrap: wrap;
  5. }

实现两端对齐排列时最后一行如何左对齐

张鑫旭-让CSS flex布局最后一行列表左对齐的N种方法
spaceBetween.png

  1. <div class="container">
  2. <div class="list"></div>
  3. <div class="list"></div>
  4. <div class="list"></div>
  5. <div class="list"></div>
  6. <div class="list"></div>
  7. <div class="list"></div>
  8. <div class="list"></div>
  9. </div>
  1. .container {
  2. display: flex;
  3. justify-content: space-between;
  4. flex-wrap: wrap;
  5. }
  6. .list {
  7. width: 24%; height: 100px;
  8. background-color: skyblue;
  9. margin-top: 15px;
  10. }

元素宽度固定,最后一行动态 margin

  1. .container {
  2. display: flex;
  3. /* 两端对齐 */
  4. justify-content: space-between;
  5. flex-wrap: wrap;
  6. }
  7. .list {
  8. width: 24%; height: 100px;
  9. background-color: skyblue;
  10. margin-top: 15px;
  11. }
  12. /* 如果最后一行是3个元素 */
  13. .list:last-child:nth-child(4n - 1) {
  14. margin-right: calc(24% + 4% / 3);
  15. }
  16. /* 如果最后一行是2个元素 */
  17. .list:last-child:nth-child(4n - 2) {
  18. margin-right: calc(48% + 8% / 3);
  19. }

元素宽度不固定,

最后一项margin-right:auto

  1. .container {
  2. display: flex;
  3. justify-content: space-between;
  4. flex-wrap: wrap;
  5. }
  6. .list {
  7. background-color: skyblue;
  8. margin: 10px;
  9. }
  10. /* 最后一项margin-right:auto */
  11. .list:last-child {
  12. margin-right: auto;
  13. }

创建伪元素并设置flex:auto或flex:1

  1. .container {
  2. display: flex;
  3. justify-content: space-between;
  4. flex-wrap: wrap;
  5. }
  6. .list {
  7. background-color: skyblue;
  8. margin: 10px;
  9. }
  10. /* 使用伪元素辅助左对齐 */
  11. .container::after {
  12. content: '';
  13. flex: auto; /* 或者flex: 1 */
  14. }

每行列数不固定

使用足够的空白标签进行填充占位,具体的占位数量是由最多列数的个数决定的,例如这个布局最多7列,那我们可以使用7个空白标签进行填充占位,最多10列,那我们需要使用10个空白标签。

  1. <div class="container">
  2. <div class="list"></div>
  3. <div class="list"></div>
  4. <div class="list"></div>
  5. <div class="list"></div>
  6. <div class="list"></div>
  7. <div class="list"></div>
  8. <div class="list"></div>
  9. <i></i><i></i><i></i><i></i><i></i>
  10. </div>
  1. .container {
  2. display: flex;
  3. justify-content: space-between;
  4. flex-wrap: wrap;
  5. margin-right: -10px;
  6. }
  7. .list {
  8. width: 100px; height:100px;
  9. background-color: skyblue;
  10. margin: 15px 10px 0 0;
  11. }
  12. /* 和列表一样的宽度和margin值 */
  13. .container > i {
  14. width: 100px;
  15. margin-right: 10px;
  16. }

css grid (兼容性不好)

  1. .container {
  2. display: grid;
  3. justify-content: space-between;
  4. grid-template-columns: repeat(auto-fill, 100px);
  5. grid-gap: 10px;
  6. }
  7. .list {
  8. width: 100px; height:100px;
  9. background-color: skyblue;
  10. margin-top: 5px;
  11. }

参考链接

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/