现代 CSS 布局技术详解

(7 个月前)
Nick Chen
约 5 分钟

现代 CSS 为我们提供了强大的布局工具,从 Flexbox 到 CSS Grid,再到最新的 Container Queries。让我们深入了解这些技术如何改变网页设计。

CSS Grid 完全指南

CSS Grid 是二维布局系统,非常适合复杂的页面布局。

基础网格设置

.grid-container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto 1fr auto;
  grid-gap: 1rem;
  min-height: 100vh;
}

/* 命名网格线 */
.advanced-grid {
  display: grid;
  grid-template-columns: [sidebar-start] 250px [sidebar-end main-start] 1fr [main-end];
  grid-template-rows: [header-start] 60px [header-end content-start] 1fr [content-end footer-start] 40px [footer-end];
}

网格区域定义

.layout-grid {
  display: grid;
  grid-template-areas:
    "header header header"
    "sidebar main aside"
    "footer footer footer";
  grid-template-columns: 200px 1fr 200px;
  grid-template-rows: 60px 1fr 40px;
  gap: 1rem;
  height: 100vh;
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }

响应式网格

.responsive-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
  padding: 2rem;
}

/* 卡片网格 */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 1.5rem;
}

.card {
  background: white;
  border-radius: 8px;
  padding: 1.5rem;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

Flexbox 深度应用

Flexbox 在一维布局中表现出色,特别适合组件内部的排列。

高级 Flex 技巧

/* 等高卡片 */
.flex-cards {
  display: flex;
  gap: 1rem;
}

.flex-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: white;
  border-radius: 8px;
  overflow: hidden;
}

.card-content {
  flex: 1;
  padding: 1rem;
}

.card-footer {
  padding: 1rem;
  margin-top: auto;
  background: #f5f5f5;
}

/* 居中对齐的多种方式 */
.center-content {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* Flex 导航 */
.nav-flex {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1rem 2rem;
}

.nav-links {
  display: flex;
  gap: 2rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

Flex 排序和对齐

.flex-container {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.flex-item {
  flex: 1 1 300px; /* grow shrink basis */
}

/* 特殊排序 */
.priority-item {
  order: -1; /* 显示在最前面 */
}

.last-item {
  order: 1; /* 显示在最后面 */
}

/* 对齐方式组合 */
.flex-space-around {
  display: flex;
  justify-content: space-around;
  align-items: stretch;
}

Container Queries 新特性

Container Queries 允许组件根据其容器大小而非视口大小来调整样式。

/* 定义容器 */
.card-container {
  container-type: inline-size;
  container-name: card;
}

/* 容器查询 */
@container card (min-width: 400px) {
  .card {
    display: flex;
    gap: 1rem;
  }

  .card-image {
    flex: 0 0 150px;
  }

  .card-content {
    flex: 1;
  }
}

@container card (min-width: 600px) {
  .card {
    flex-direction: row;
  }

  .card-image {
    flex: 0 0 200px;
  }
}

子网格 (Subgrid) 功能

.main-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}

.sub-container {
  grid-column: span 4;
  display: grid;
  grid-template-columns: subgrid;
  gap: inherit;
}

/* 子网格对齐 */
.sub-item {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
}

实用布局模式

圣杯布局(现代版)

.holy-grail {
  display: grid;
  grid-template-areas:
    "header header header"
    "nav main aside"
    "footer footer footer";
  grid-template-rows: auto 1fr auto;
  grid-template-columns: 200px 1fr 200px;
  min-height: 100vh;
}

@media (max-width: 768px) {
  .holy-grail {
    grid-template-areas:
      "header"
      "nav"
      "main"
      "aside"
      "footer";
    grid-template-columns: 1fr;
  }
}

媒体对象模式

.media-object {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.media-image {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
}

.media-content {
  flex: 1;
  min-width: 0; /* 允许文本换行 */
}

.media-title {
  margin: 0 0 0.5rem 0;
  font-weight: bold;
}

.media-description {
  margin: 0;
  color: #666;
}

卡片瀑布流

.masonry-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  grid-auto-rows: 10px;
  gap: 1rem;
}

.masonry-item {
  background: white;
  border-radius: 8px;
  padding: 1rem;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

/* JavaScript 计算高度并设置 grid-row-end */
.masonry-item[data-height="small"] {
  grid-row-end: span 20;
}

.masonry-item[data-height="medium"] {
  grid-row-end: span 30;
}

.masonry-item[data-height="large"] {
  grid-row-end: span 40;
}

高级响应式技巧

流体排版

:root {
  --fluid-min-width: 320;
  --fluid-max-width: 1140;
  --fluid-screen: 100vw;
  --fluid-bp: calc(
    (var(--fluid-screen) - var(--fluid-min-width) / 16 * 1rem) /
    (var(--fluid-max-width) - var(--fluid-min-width))
  );
}

.fluid-text {
  font-size: calc(1rem + 2 * var(--fluid-bp));
  line-height: calc(1.3rem + 0.6 * var(--fluid-bp));
}

/* 使用 clamp 的简化版本 */
.heading {
  font-size: clamp(1.5rem, 4vw, 3rem);
  line-height: clamp(1.2, 1.5, 1.8);
}

组件驱动的响应式设计

/* 根据容器宽度调整组件 */
.component {
  display: grid;
  gap: 1rem;
  container-type: inline-size;
}

.component > * {
  grid-column: 1;
}

@container (min-width: 30rem) {
  .component {
    grid-template-columns: 1fr 2fr;
  }

  .component-aside {
    grid-column: 1;
  }

  .component-main {
    grid-column: 2;
  }
}

布局调试技巧

/* 网格调试 */
.debug-grid {
  background-image:
    linear-gradient(rgba(255,0,0,0.1) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,0,0,0.1) 1px, transparent 1px);
  background-size: 20px 20px;
}

/* Flex 调试 */
.debug-flex > * {
  outline: 1px solid red;
  background: rgba(255,0,0,0.1);
}

/* 容器查询调试 */
.debug-container::before {
  content: "Container width: " attr(data-width);
  position: absolute;
  top: 0;
  left: 0;
  background: yellow;
  padding: 0.25rem;
  font-size: 0.75rem;
}

性能考虑

减少重排和重绘

/* 使用 transform 替代改变位置 */
.animate-move {
  transform: translateX(100px);
  transition: transform 0.3s ease;
}

/* 使用 will-change 提示浏览器 */
.will-animate {
  will-change: transform, opacity;
}

/* 动画完成后移除 will-change */
.animation-complete {
  will-change: auto;
}

GPU 加速

.gpu-layer {
  transform: translateZ(0);
  /* 或者 */
  will-change: transform;
  /* 或者 */
  backface-visibility: hidden;
}

浏览器兼容性处理

/* 特性检测 */
@supports (display: grid) {
  .layout {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
}

@supports not (display: grid) {
  .layout {
    display: flex;
    flex-wrap: wrap;
  }

  .layout > * {
    flex: 1 1 300px;
  }
}

/* 渐进增强 */
.container {
  /* 基础 Flexbox 布局 */
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

@supports (display: grid) {
  .container {
    /* 如果支持 Grid,使用 Grid */
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  }
}

现代 CSS 布局技术为我们提供了前所未有的控制力和灵活性。通过组合使用这些技术,我们可以创建出既美观又实用的响应式布局。

记住,选择合适的布局技术很重要:

  • Flexbox:一维布局,组件内排列
  • Grid:二维布局,页面级布局
  • Container Queries:组件级响应式
  • 传统技术:兜底和渐进增强

推荐资源: