Vanson's Eternal Blog

CSS布局

Css basic.png
Published on
/14 mins read/---

CSS布局

弹性布局(Flex)

弹性布局(Flexbox)是一种一维布局模型,主要用于在一个方向上(行或列)排列元素。它特别适合于小规模布局,如导航栏、表单元素等。

基本概念

弹性布局包含两个主要角色:

  1. 弹性容器(Flex Container) - 设置了display: flex或display: inline-flex的元素
  2. 弹性项目(Flex Items) - 弹性容器的直接子元素

弹性布局有两个轴:

  • 主轴(Main Axis) - 由flex-direction属性定义的方向
  • 交叉轴(Cross Axis) - 垂直于主轴的方向

容器属性

.flex-container {
  /* 启用弹性布局 */
  display: flex/* 或 inline-flex */
 
  /* 主轴方向 */
  flex-direction: row/* 默认值,从左到右 */
  /* 其他值: row-reverse(从右到左), column(从上到下), column-reverse(从下到上) */
 
  /* 换行行为 */
  flex-wrap: nowrap/* 默认值,不换行 */
  /* 其他值: wrap(换行), wrap-reverse(反向换行) */
 
  /* 简写属性 */
  flex-flow: row nowrap/* flex-direction 和 flex-wrap 的组合 */
 
  /* 主轴对齐 */
  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, space-evenly */
 
  /* 间隙 */
  gap10px/* 行和列间隙相同 */
  row-gap10px/* 行间隙 */
  column-gap20px/* 列间隙 */
}

项目属性

.flex-item {
  /* 顺序 */
  order0/* 默认值,数值越小排列越靠前 */
 
  /* 放大比例 */
  flex-grow0/* 默认值,不放大 */
  /* 值为正数,表示相对于其他项目的放大比例 */
 
  /* 缩小比例 */
  flex-shrink1/* 默认值,空间不足时会缩小 */
  /* 值为正数,表示相对于其他项目的缩小比例,0表示不缩小 */
 
  /* 基础尺寸 */
  flex-basis: auto/* 默认值,项目本来的大小 */
  /* 可以设置具体的长度值,如 100px, 20% 等 */
 
  /* 简写属性 */
  flex01 auto/* flex-grow, flex-shrink, flex-basis 的组合 */
  /* 常用值: flex: 1 (1 1 0%), flex: auto (1 1 auto), flex: none (0 0 auto) */
 
  /* 自身对齐 */
  align-self: auto/* 默认值,继承父容器的 align-items 属性 */
  /* 其他值: flex-start, flex-end, center, baseline, stretch */
}

实际应用示例

导航栏

<nav class="navbar">
  <div class="logo">Logo</div>
  <ul class="nav-links">
      <li><a href="#">首页</a></li>
      <li><a href="#">关于</a></li>
      <li><a href="#">服务</a></li>
      <li><a href="#">联系</a></li>
  </ul>
  <div class="nav-right">
      <button>登录</button>
  </div>
</nav>
 
.navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding1rem2rem;
  background-color#333;
  color: white;
}
 
.nav-links {
  display: flex;
  list-style: none;
  gap20px;
}
 
/* 响应式设计 */
@media (max-width768px) {
.navbar {
    flex-direction: column;
    align-items: flex-start;
  }
 
.nav-links {
    margin-top1rem;
    width100%;
  }
}
 

卡片布局

<div class="card-container">
  <div class="card">卡片 1</div>
  <div class="card">卡片 2</div>
  <div class="card">卡片 3</div>
  <div class="card">卡片 4</div>
</div>
.card-container {
  display: flex;
  flex-wrap: wrap;
  gap20px;
  justify-content: center;
}
 
.card {
  flex01300px/* 不放大,可缩小,基础宽度300px */
  height200px;
  background-color#f0f0f0;
  border-radius8px;
  padding20px;
  box-shadow02px5pxrgba(0,0,0,0.1);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size1.5rem;
}
 

居中布局

<div class="center-container">
  <div class="centered-content">完全居中的内容</div>
</div>
 
.center-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height100vh/* 视口高度 */
}
 
.centered-content {
  padding2rem;
  background-color#e0f0ff;
  border-radius8px;
}
 

Flexbox的优势

  • 简化布局 - 比传统方法(如浮动、定位)更直观
  • 响应式设计 - 容易创建适应不同屏幕尺寸的布局
  • 垂直居中 - 轻松实现水平和垂直居中
  • 动态空间分配 - 可以根据可用空间动态调整元素大小
  • 顺序控制 - 可以通过CSS改变元素的视觉顺序,而不改变HTML结构

网格布局(Grid)

网格布局(Grid)是一种二维布局系统,允许开发者同时在行和列上控制元素的排列。它特别适合于复杂的页面布局,如整个网站的框架结构。

基本概念

网格布局包含两个主要角色:

  • 网格容器(Grid Container) - 设置了display: grid或display: inline-grid的元素
  • 网格项目(Grid Items) - 网格容器的直接子元素

网格布局的其他重要概念:

  • 网格线(Grid Lines) - 构成网格结构的水平和垂直线
  • 网格轨道(Grid Tracks) - 两条相邻网格线之间的空间,即行或列
  • 网格单元(Grid Cell) - 四条网格线围成的区域,是最小的网格单位
  • 网格区域(Grid Area) - 由任意数量的网格单元组成的矩形区域

容器属性

.grid-container {
  /* 启用网格布局 */
  display: grid/* 或 inline-grid */
 
  /* 定义列 */
  grid-template-columns100px200px100px; /* 三列,宽度分别为100px、200px、100px */
  /* 使用fr单位: grid-template-columns: 1fr 2fr 1fr; 按比例分配空间 */
  /* 使用repeat: grid-template-columns: repeat(3, 1fr); 三等分列 */
  /* 自动填充: grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); */
 
  /* 定义行 */
  grid-template-rows100px auto 100px/* 三行,第一行和第三行高度100px,中间行自适应 */
 
  /* 定义区域 */
  grid-template-areas
      "header header header"
      "sidebar content content"
      "footer footer footer";
  /* 使用 . 表示空单元格: "header header ." */
 
  /* 间隙 */
  gap20px/* 行和列间隙相同 */
  row-gap10px/* 行间隙 */
  column-gap20px/* 列间隙 */
 
  /* 自动生成的网格轨道 */
  grid-auto-rows100px/* 自动生成的行高度为100px */
  grid-auto-columns100px/* 自动生成的列宽度为100px */
  grid-auto-flow: row/* 自动放置的方向,row(先行后列)或column(先列后行) */
  /* 添加 dense 关键字可以紧密填充: grid-auto-flow: row dense; */
 
  /* 对齐网格项 */
  justify-items: stretch/* 默认值,水平方向拉伸填满单元格 */
  /* 其他值: start, end, center */
  align-items: stretch/* 默认值,垂直方向拉伸填满单元格 */
  /* 其他值: start, end, center */
 
  /* 对齐网格轨道 */
  justify-content: start/* 默认值,网格在容器中的水平对齐方式 */
  /* 其他值: end, center, stretch, space-around, space-between, space-evenly */
  align-content: start/* 默认值,网格在容器中的垂直对齐方式 */
  /* 其他值: end, center, stretch, space-around, space-between, space-evenly */
}

项目属性

.grid-item {
  /* 指定位置 */
  grid-column1 / 3/* 从第1条列网格线到第3条列网格线,跨越2列 */
  grid-column-start1/* 起始列网格线 */
  grid-column-end3/* 结束列网格线,也可以使用 span 2 表示跨越2列 */
 
  grid-row1 / 3/* 从第1条行网格线到第3条行网格线,跨越2行 */
  grid-row-start1/* 起始行网格线 */
  grid-row-end3/* 结束行网格线,也可以使用 span 2 表示跨越2行 */
 
  /* 简写属性 */
  grid-area1 / 1 / 3 / 3/* grid-row-start / grid-column-start / grid-row-end / grid-column-end */
  grid-area: header; /* 使用模板区域名称 */
 
  /* 自身对齐 */
  justify-self: stretch/* 默认值,水平方向拉伸填满单元格 */
  /* 其他值: start, end, center */
  align-self: stretch/* 默认值,垂直方向拉伸填满单元格 */
  /* 其他值: start, end, center */
}

实际应用示例

经典网站布局

<div class="site-layout">
  <header class="header">页眉</header>
  <nav class="sidebar">侧边栏</nav>
  <main class="content">主内容区域</main>
  <footer class="footer">页脚</footer>
</div>
.site-layout {
  display: grid;
  grid-template-columns200px1fr; /* 侧边栏固定宽度,内容区域自适应 */
  grid-template-rows: auto 1fr auto/* 页眉和页脚自适应高度,内容区域占剩余空间 */
  grid-template-areas
      "header header"
      "sidebar content"
      "footer footer";
  min-height100vh/* 至少占满视口高度 */
  gap10px;
}
 
.header {
  grid-area: header;
  background-color#333;
  color: white;
  padding1rem;
}
 
.sidebar {
  grid-area: sidebar;
  background-color#f0f0f0;
  padding1rem;
}
 
.content {
  grid-area: content;
  background-color#fff;
  padding1rem;
}
 
.footer {
  grid-area: footer;
  background-color#333;
  color: white;
  padding1rem;
}
 
/* 响应式设计 */
@media (max-width768px) {
.site-layout {
    grid-template-columns1fr/* 单列布局 */
    grid-template-areas
      "header"
      "sidebar"
      "content"
      "footer";
  }
}

照片画廊

<div class="gallery">
  <img src="img1.jpg" alt="图片1" class="gallery-item">
  <img src="img2.jpg" alt="图片2" class="gallery-item featured">
  <img src="img3.jpg" alt="图片3" class="gallery-item">
  <img src="img4.jpg" alt="图片4" class="gallery-item">
  <img src="img5.jpg" alt="图片5" class="gallery-item">
  <img src="img6.jpg" alt="图片6" class="gallery-item">
</div>
.gallery {
  display: grid;
  grid-template-columnsrepeat(auto-fillminmax(200px1fr));
  gap10px;
  padding10px;
}
 
.gallery-item {
  width100%;
  height200px;
  object-fit: cover;
  border-radius4px;
}
 
.featured {
  grid-column: span 2;
  grid-row: span 2;
  height100%;
}

仪表板布局

<div class="dashboard">
  <div class="widget widget-1">小部件 1</div>
  <div class="widget widget-2">小部件 2</div>
  <div class="widget widget-3">小部件 3</div>
  <div class="widget widget-4">小部件 4</div>
  <div class="widget widget-5">小部件 5</div>
  <div class="widget widget-6">小部件 6</div>
</div>
.dashboard {
  display: grid;
  grid-template-columnsrepeat(41fr);
  grid-auto-rowsminmax(100px, auto);
  gap15px;
  padding15px;
}
 
.widget {
  background-color#f0f0f0;
  border-radius8px;
  padding15px;
  box-shadow02px5pxrgba(0,0,0,0.1);
}
 
.widget-1 {
  grid-column1 / 3;
  grid-row1 / 3;
}
 
.widget-2 {
  grid-column3 / 5;
}
 
.widget-3 {
  grid-column3 / 4;
}
 
.widget-4 {
  grid-column4 / 5;
}
 
.widget-5 {
  grid-column1 / 3;
}
 
.widget-6 {
  grid-column3 / 5;
}

Grid的优势

  1. 二维布局 - 同时控制行和列,更适合复杂布局
  2. 显式定位 - 可以精确控制元素在网格中的位置
  3. 区域命名 - 通过命名区域简化布局代码
  4. 对齐控制 - 提供丰富的对齐选项
  5. 响应式设计 - 结合媒体查询和minmax()等功能,轻松创建响应式布局
  6. 间隙控制 - 简单设置元素之间的间隙,无需使用外边距

浮动布局(Float)

浮动布局是CSS早期用于实现多列布局的主要方法。

虽然现在有了更现代的布局技术(Flexbox和Grid),但浮动仍然在某些场景下有其用途,特别是文本环绕图片等情况。基本用法

基本用法

.float-left {
  float: left/* 元素浮动到左侧 */
}
 
.float-right {
  float: right/* 元素浮动到右侧 */
}
 
.clear {
  clear: both/* 清除两侧浮动 */
  /* 其他值: left(清除左浮动), right(清除右浮动), none(默认值) */
}

清除浮动的方法

浮动元素会脱离正常文档流,可能导致父容器高度塌陷。以下是几种清除浮动的常用方法:

使用clear属性

<div class="container">
  <div class="float-left">浮动元素</div>
  <div class="clear"></div> <!-- 清除浮动 -->
</div>
 
.clear {
  clear: both;
}

父元素设置overflow

<div class="container clearfix">
  <div class="float-left">浮动元素</div>
</div>
.clearfix {
  overflow: auto/* 或 hidden */
}

使用伪元素(推荐)

<div class="container clearfix">
  <div class="float-left">浮动元素</div>
</div>
.clearfix::after {
  content: "";
  display: block;
  clear: both;
  visibility: hidden;
  height: 0;
}

实际应用示例

文本环绕图片

<div class="text-wrap">
  <img src="image.jpg" alt="示例图片" class="float-left">
  <p>这是一段长文本,将环绕在图片周围。这是一段长文本,将环绕在图片周围。这是一段长文本,将环绕在图片周围。这是一段长文本,将环绕在图片周围。这是一段长文本,将环绕在图片周围。这是一段长文本,将环绕在图片周围。</p>
</div>
.text-wrap {
  overflow: auto/* 清除浮动 */
}
 
.float-left {
  float: left;
  margin-right15px;
  margin-bottom10px;
  width200px;
}

简单的多列布局

<div class="columns clearfix">
  <div class="column">第一列内容</div>
  <div class="column">第二列内容</div>
  <div class="column">第三列内容</div>
</div>
.clearfix::after {
  content: "";
  display: block;
  clear: both;
  visibility: hidden;
  height: 0;
}
 
.column {
  float: left;
  width33.33%;
  padding15px;
  box-sizing: border-box;
}

浮动的局限性

  1. 需要清除浮动 - 否则可能导致布局问题
  2. 复杂布局困难 - 难以实现垂直居中等效果
  3. 响应式设计复杂 - 需要更多代码来处理不同屏幕尺寸
  4. 顺序依赖 - 元素在HTML中的顺序会影响布局效果

布局技术的选择

何时使用Flexbox

  • 一维布局(行或列)
  • 小规模组件布局
  • 需要对齐、分布或排序元素
  • 内容大小未知或动态变化

何时使用Grid

  • 二维布局(同时控制行和列)
  • 大规模页面布局
  • 需要精确定位元素
  • 布局结构相对固定
  • 需要命名区域简化布局

何时使用Float

  • 文本环绕图片或其他元素
  • 需要支持旧版浏览器
  • 简单的多列布局(虽然Flexbox或Grid更适合)

混合使用

在实际项目中,通常会混合使用这些布局技术:

  • 使用Grid创建整体页面布局
  • 使用Flexbox处理导航栏、卡片等组件
  • 使用Float处理文本环绕图片等特定场景
← Previous postCSS选择器
Next post →CSS盒模型