CSS 布局是前端开发的核心,经历了从早期浮动、定位到现代 Flexbox 和 Grid 的演变。下面将系统地介绍当前主流和必须掌握的 CSS 布局方案。

布局演进简图

表格布局 (已淘汰) -> 浮动布局 (Legacy) -> 定位布局 (特定场景) -> Flexbox (一维布局主流) -> Grid (二维布局主流)

一、现代布局核心:Flexbox 与 Grid

  1. Flexbox (弹性盒子布局)
  • 核心概念:为一维布局提供高效、灵活的分布方式。“一维” 指一次只处理一个维度(行或列)的布局

  • 应用场景:导航栏; 垂直居中(经典的“不知高度,垂直居中”);卡片组件布局;不均匀分布的空间分配;任何需要弹性伸缩的线性布局

  • 核心属性:

    容器属性:
    display: flex | inline-flex;
    flex-direction: 定义主轴方向 (row, column, row-reverse, column-reverse)
    justify-content: 主轴对齐 (flex-start | flex-end | center | space-between | space-around | space-evenly)
    align-items: 单行/行内对齐 (stretch | flex-start | flex-end | center | baseline)
    align-content:多行/行间对齐 (stretch | flex-start | flex-end | center | space-between | space-around);
    flex-wrap: 是否换行 (nowrap | wrap | wrap-reverse)
    gap: 10px; /* 项目之间的间距 */
    row-gap: 10px;
    column-gap: 10px;
    项目属性:
    flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ];
    flex-grow:  放大比例 /* 默认 0:不放大*/
    flex-shrink: 缩小比例 /* 默认 1:等比例缩小 */
    flex-basis: | auto 项目初始大小  /* 默认 auto */
    align-self: 覆盖容器的 align-items 属性

  1. CSS Grid (网格布局)
  • 核心概念:专为二维布局设计,以 “网” 的形式划分页面为单元格,实现项目的精准定位(同时管控行与列)。

  • 应用场景:首页页面布局(Header, Sidebar, Main, Footer);杂志式图片墙;行列精准控制布局;需同时管控行列的布局

  • 关键属性:

网格编排

①. display: grid 将容器变为网格容器(网格容器的子元素自动变成块盒,即使是span元素)

②. grid-template-columns / grid-template-rows: 设置网格每一列/行的宽度和高度及数量(显示网格)完全受控

grid-auto-rows / grid-auto-column :隐式控制行高和列宽 动态内容超出就按照(隐式网格)排列

常用值:

- length:固定值,如 100px, 5em, 20rem

- <percentage>:百分比,如 50%

- fr:剩余空间比例单位,如 1fr 2fr(1份和2份)

- auto: 由内容决定大小

- min-content: 最小内容尺寸

- max-content: 最大内容尺寸

- minmax(min,max):尺寸范围,如 minmax(100px,1fr)

- repeat(count,values):重复模式,如 repeat(3,1fr) 或 repeat(auto-fill,100px)

.container {
  grid-template-columns: 100px 1fr 2fr;           /* 固定 | 1份 | 2份 */
  grid-template-columns: repeat(4, 25%);          /* 4等分列 */
  grid-template-columns: 200px minmax(100px, 1fr); /* 固定 + 弹性 */
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); /* 响应式 */
}

③. gap:设置网格项间距。

常用值:

- <length>:长度值,如10px,1em

- <percentage>: 百分比(相对网格容器尺寸)

.container {
  gap: 20px;           /* 行和列间距都是20px */
  gap: 10px 15px;      /* 行间距10px,列间距15px */
  row-gap: 10px;       /* 仅行间距 */
  column-gap: 20px;    /* 仅列间距 */
}

④. grid-template-areas: 通过命名区域布局

核心:给网格区域起名字,再用名字分配元素的位置

常用值: <string>:区域名称字符串

.container {
  display: grid;//  1. 网格布局
  grid-template-areas://2. 网格区域命名
    "header header header"  /* 第一行:整个宽度都叫 "header" */
    "sidebar main main"     /* 第二行:左边是 "sidebar",右边两列是 "main" */
    "footer footer footer"; /* 第三行:整个宽度都叫 "footer" */
}
//3. 分配子元素到对应的区域
header { grid-area: header; background: #ff9900; }
aside { grid-area: sidebar; background: #3333cc; color: white; }
main { grid-area: main; background: #cc3333; color: white; }
footer { grid-area: footer; background: #339966; }

⑤. 控制网格单元格内元素

justify-items:控制单元格内水平方向对齐

align-items : 控制单元格内垂直方向对齐

place-items:align-items justify-items的简写 (先垂直后水平)

常用值:

- start: 元素靠单元格的起始侧(垂直:顶部;水平:左侧)

- end: 元素靠单元格的结束侧(垂直:底部;水平:右侧)

- center:元素在单元格内居中对齐

- stretch: 拉伸填满单元格(默认值)

.container {
  place-items: center stretch; /* align-items justify-items */
  place-items: center;         /* 水平和垂直都居中 */
}
子项放置

①. grid-column/grid-row :定义网格项占据的网格线。

常用值:

- <number>:网格线编号(从1开始)

- span<number>:跨越的轨道数量

.item {
  grid-column: 1 / 3;      /* 从第1线到第3线 */
  grid-column: 1 / span 2; /* 从第1线开始跨越2列 */
  grid-column: span 2;     /* 自动跨越2列 */
}

②. grid-area:指定网格项占据的区域

用法一: 引用 grid-template-columns 定义的区域

 .item {
  grid-area: header;
}

用法二: 作为 grid-row-start / grid-column-start / grid-row-end/ grid-column-end 的简写

.item {
  grid-area: 1 / 1 / 3 / 3; /* row-start / column-start / row-end / column-end */
}

③. justify-self / align-self /place-self : 控制单个网格项在单元格内的对齐。

常用值:

- start | end | center | stretch

- auto :使用容器的 justify-items /align-items 值

.item {
  place-self: center start; /* align-self justify-self */
  place-self: center;       /* 水平和垂直都居中 */
}
特殊值和单位详解

①. fr 单位(分数单位):按比例分配剩余空间(在固定尺寸轨道分配之后)

.container {
  grid-template-columns: 100px 1fr 2fr;
  /* 总宽度 = 100px + 剩余空间的1/3 + 剩余空间的2/3 */
}

②. minmax(min,max): 定义尺寸范围。

.container {
  grid-template-columns: minmax(200px, 1fr) minmax(300px, 2fr);
  /* 第一列:最小200px,最大1份剩余空间 */
  /* 第二列:最小300px,最大2份剩余空间 */
}

③. repeat() 函数

.container {
  grid-template-columns: repeat(3, 100px);     /* 重复3次,每次100px */
  grid-template-columns: repeat(2, 1fr 2fr);   /* 1fr 2fr 1fr 2fr */
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* 自动填充 */
}

④. auto-fill 和 auto-fit

  • auto-fill:动态改容器宽度时,优先生成最多列,剩余列留空白占位

  • auto-fit:动态改容器宽度时,折叠空白列,现有列拉伸填

二. 传统布局

虽然现代项目首选 Flex/Grid,但理解这些传统技术对于维护老项目或特定场景仍有必要。

  1. Float (浮动布局)
  • 核心概念:最初用于文字环绕图片,后被“黑科技”般地用于整个页面布局(需配合清除浮动)。

  • 现状:在布局领域已基本被 Flexbox 和 Grid 取代,但现在仍用于文字环绕图片等原始用途。

  • 示例

.container::after {
  content: "";
  display: table;
  clear: both; /* 清除浮动 */
}
.left { float: left; width: 200px; }
.right { float: right; width: 200px; }
.main { margin: 0 210px; }
  1. position定位
  • 核心概念:通过 position 属性将元素脱离正常文档流进行精确位置控制。

  • 应用场景:

- 自定义下拉菜单

- 固定在视口的元素(如 position:fixed 的导航栏)

- 在卡片内创建标签、角标、按钮

  • 示例:

.modal {
  position: fixed; /* 相对于视口定位 */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%); /* 经典居中技巧 */
  z-index: 1000;
}

三. 响应式布局的基石

  1. 媒体查询
  • 根据不同的设备视口尺寸、屏幕特性(如分辨率、方向)应用差异化的 CSS 样式,是网格布局实现多端响应式的核心手段之一。

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr; /* 桌面端默认3列网格布局 */
  grid-gap: 20px; /* 网格项间距 */
}
/* 平板设备:屏幕宽度小于1024px时,改为2列网格 */
@media (max-width: 1024px) {
  .container {
    grid-template-columns: 1fr 1fr;
    grid-gap: 15px; /* 同步缩小间距适配平板 */
  }
}
/* 移动端:屏幕宽度小于768px时,改为单列网格 */
@media (max-width: 768px) {
  .container {
    grid-template-columns: 1fr; /* 单列流式布局 */
    grid-gap: 10px; /* 进一步缩小移动端间距 */
    padding: 0 10px; /* 增加左右内边距,优化移动端边距体验 */
  }
}
  1. 相对单位与流体布局
  • 使用%,vw,vh,rem,em等相对单位替代固定的px,使布局能够随容器或视口大小变化。相对单位常与minmax()、repeat()等css-主流布局函数结合。

/* 流体网格容器:占父容器90%宽度,大屏最大宽度限制避免过度拉伸 */
.fluid-grid {
  display: grid;
  /* 结合相对单位与网格函数:列宽最小15vw(视口宽度占比),最大1fr分配剩余空间 */
  grid-template-columns: repeat(auto-fit, minmax(15vw, 1fr));
  grid-gap: 2vw; /* 间距用vw单位,随视口宽度同步缩放 */
  width: 90%; /* 容器宽度为父元素的90% */
  max-width: 1200px;
  margin: 0 auto;
}
/* 网格项:使用rem单位适配字体,em单位适配内边距 */
.grid-item {
  font-size: 1.2rem; /* 基于根元素字体大小的相对单位,适配全局字体设置 */
  padding: 1em 1.5em; /* 内边距随当前元素字体大小变化,保持比例 */
  background: #f0f0f0;
}