返回文章列表

CSS 查缺补漏 2(居中 / BFC)

居中

水平居中方式

margin: 0 auto;

原理:当 margin 值为 auto 时,元素会尝试占据尽可能大的空间。比如,margin-left 会让 div 尽量靠最右侧。

margin: 0 auto; 相当于垂直 margin: 0 的同时,让 margin-left: auto 和 margin-right: auto,所以把盒子挤在水平居中位置。

.parent{ text-align: center; }

适用于内联/行内块元素。

垂直居中

.child { height: 100px; line-height: 100px; }

单行文本的行高与容器高度相同实现垂直居中。

通用方法

现代最常用的方案无疑是 flex 布局和 grid 布局。

值得关注的是关于 inset 属性的使用,这是之前缺少具体了解的。

/* 方案1:Flex(性能好、通用) */
.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 方案2:Grid(最简洁) */
.parent {
  display: grid;
  place-items: center;
}

/* 方案3:绝对定位 + margin: auto(宽高已知) */
.child {
  position: absolute;
/*
	inset: 0(= top: 0; right: 0; bottom: 0; left: 0),
	告诉浏览器:这个元素的上/右/下/左边界必须分别紧贴父容器的对应边。
	相当于给元素框定了一个矩形区域,可以理解成"虚拟父容器"
	margin: auto 在里面做水平+垂直方向的双重平分。
*/
  inset: 0;
  margin: auto;
  width: 200px;
  height: 100px;
}

/* 方案4:绝对定位 + transform(宽高未知) */
.child {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

BFC(Block Formatting Contexts)

块级格式化上下文。指一个独立的布局环境,BFC 内部元素与外部元素互不影响。

创建方式

浏览器会自动给根元素(<html>)生成一个 BFC。其他常见方式:

/* 浮动 */
float: left | right

/* 定位脱离文档流 */
position: absolute | fixed

/* overflow 不是 visible */
overflow: hidden | auto | scroll

/* display 的特殊值 */
display: inline-block | table-cell | flow-root

/* 现代布局 */
display: flex          /* flex 容器 */
display: inline-flex   /* inline-flex 容器 */
display: grid          /* 网格容器 */
display: inline-grid   /* inline-grid 容器 */

最佳实践: display: flow-root 是专门为创建 BFC 而生的,语义最干净,副作用最少。比 overflow: hidden 优雅多了。

用途

  1. 解决父元素高度塌陷。当父元素高度由子元素撑起时,如果子元素浮动会导致父元素塌陷。可以给父元素添加 overflow: hidden 来设置 BFC,避免塌陷。

  2. 解决 margin 折叠问题(区块的上下外边距有时会合并(折叠)为单个边距,其大小为两个边距中的最大值(或如果它们相等,则仅为其中一个),这种行为称为外边距折叠。注意:设有浮动和绝对定位的元素不会发生外边距折叠)。

    通过给其中一个元素包裹一个 BFC 容器:

    <div style="margin-bottom: 50px;">A</div>
    <div style="display: flow-root;">
      <div style="margin-top: 30px;">B</div>
    </div>
  3. 阻止元素被浮动元素覆盖。浮动元素会盖在后面的块级元素上。把后面的块级元素变成 BFC 可以避免。

    .float-box {
      float: left;
      width: 200px;
      height: 100px;
    }
    .content {
      display: flow-root;  /* 不与浮动元素重叠 */
    }