CSS 布局

Web 布局从最初的 Table、Float 发展到现在的 Flex 和 Grid,能力越来越强。掌握 Flex 和 Grid 是现代前端开发的基本功。

一、Flex 布局

Flexbox 用于一维布局(行或列)。

1. 容器属性

  • flex-direction: 主轴方向。
    • row (默认): 水平,从左到右。
    • column: 垂直,从上到下。
  • justify-content: 主轴对齐方式。
    • flex-start, flex-end, center, space-between (两端对齐), space-around.
  • align-items: 交叉轴对齐方式(单行)。
    • stretch (默认, 拉伸), flex-start, flex-end, center, baseline.
  • flex-wrap: 是否换行。
    • nowrap (默认), wrap.

2. 项目属性

  • flex-grow: 存在剩余空间时,项目的放大比例(默认 0,即存在剩余空间也不放大)。
  • flex-shrink: 空间不足时,项目的缩小比例(默认 1,空间不足时会自动缩小)。
  • flex-basis: 在分配多余空间之前,项目在主轴方向上的初始大小(默认 auto)。
  • 简写 flex:
    • flex: 1 => flex: 1 1 0% (最常用,平均分配剩余空间)。
    • flex: auto => flex: 1 1 auto.
    • flex: none => flex: 0 0 auto (常用于固定侧边栏)。
TIP

flex: flex-grow flex-shrink flex-basis的简写,常用来快速设置弹性项目的行为。

二、Grid 布局

Grid 用于二维布局(同时管理行和列),是 CSS 最强大的布局系统。

基本用法

.container {
  display: grid;
  /* 3列,宽度分别为 100px、自适应、200px */
  grid-template-columns: 100px 1fr 200px; 
  /* 2行,高度固定 */
  grid-template-rows: 100px 100px;
  /* 网格间距 */
  gap: 10px;
}

常用技巧

  • repeat(): grid-template-columns: repeat(3, 1fr); (3等分)。
  • minmax(): minmax(100px, 1fr) (最小100px,最大自适应)。
  • 响应式网格:
    /* 自动填充,每列最小200px */
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));

三、CSS 定位

position 属性指定了元素的定位类型。

属性值是否脱离文档流参考点说明
static默认值,按照正常文档流排列。
relative自身位置相对自己原来的位置偏移,原占位保留。常作为 absolute 的父级参照。
absolute最近定位祖先相对于最近的非 static 祖先元素定位。若无,则相对于 HTML 根元素。
fixed视口随着页面滚动位置固定不变(如导航栏、悬浮按钮)。
sticky否 (表现像 relative)滚动容器粘性定位。跨越特定阈值前为 relative,之后变为 fixed 固定在容器边缘。

四、常见布局面试题

1.flex: 1 的完整写法是什么?

  • 代表 flex-grow: 1; flex-shrink: 1; flex-basis: 0%;
  • 含义:该元素可放大、可缩小,且初始宽度为 0(即优先平分剩余空间,而不考虑内容本身的宽度)。

2. 两栏布局(左定宽,右自适应)如何实现?

  • Flex 方案
.layout {
  display: flex;
}

.left {
  width: 200px;
}

.right {
  flex: 1;
  min-width: 0;
}
  • Grid 方案
.layout {
  display: grid;
  grid-template-columns: 200px 1fr;
}
  • Absolute 方案
.layout {
  position: relative;
}

.left {
  position: absolute;
  left: 0;
  top: 0;
  width: 200px;
}

.right {
  margin-left: 200px;
}

3. 三栏布局(左右定宽,中间自适应)?

  • Flex 方案
.layout {
  display: flex;
}

.left,
.right {
  width: 200px;
}

.center {
  flex: 1;
  min-width: 0;
}
  • Grid 方案
.layout {
  display: grid;
  grid-template-columns: 200px 1fr 200px;
}
  • 圣杯布局(Float)方案
.layout {
  padding: 0 200px;
}

.center {
  float: left;
  width: 100%;
}

.left {
  float: left;
  width: 200px;
  margin-left: -100%;
  position: relative;
  left: -200px;
}

.right {
  float: left;
  width: 200px;
  margin-left: -200px;
  position: relative;
  right: -200px;
}

4.sticky 定位失效的原因?

  • 父元素设置了 overflow: hidden / auto / scroll
  • 未设置 top / bottom / left / right 阈值。
  • 父元素高度不足以让其滚动。