【css】快速上手Flexbox布局(理论讲解+实战)

Flexbox布局三剑客

flexbox布局的三大核心概念:

1. 方向(flex-direction)

flex-direction属性定义了主轴的方向,决定项目是水平排列还是垂直排列。
可选值:

  • row(默认):主轴为水平方向,项目从左到右排列。

  • row-reverse:主轴为水平方向,项目从右到左排列。

  • column:主轴为垂直方向,项目从上到下排列。

  • column-reverse:主轴为垂直方向,项目从下到上排列。
    示例代码:

    .box {
    flex-direction: row | row-reverse | column | column-reverse;
    }

2. 主轴对齐属性(justify-content)

justify-content属性管理项目在主轴上的对齐和分布。
对齐类:

  • flex-start(默认):项目向主轴起点对齐。

  • flex-end:项目向主轴终点对齐。

  • center:项目在主轴上居中对齐。
    分布类:

  • space-between:项目均匀分布在主轴上,两端不留空隙。

  • space-around:项目两侧间距相等,项目之间空隙是其他间隔的一半。

  • space-evenly:所有项目之间的间隔完全相等,包括两端。
    示例代码:

    .box {
    justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
    }

这样优化后的内容结构更清晰,描述更准确,方便读者理解和应用Flexbox布局。

3.交叉轴对齐(Align Items)

align-items 管理项目在交叉轴上的对齐方式。

  1. stretch (默认值)
    效果:拉伸所有 Flex 项目,使其在交叉轴方向上填满整个容器的高度。

条件:只有当项目没有设置固定高度(或 min-height / max-height)时,拉伸才会生效。如果项目设置了高度,则会使用该高度。

视觉表现:所有项目看起来都一样高,并且和容器一样高。

  • flex-start
    效果:所有项目在交叉轴上紧贴容器起始点对齐。

视觉表现:项目从顶部开始排列,高度由自身内容或高度属性决定。

  • flex-end
    效果:所有项目在交叉轴上紧贴容器结束点对齐。

视觉表现:项目从底部开始排列,高度由自身内容或高度属性决定。

  • center
    效果:所有项目在交叉轴上居中对齐。

视觉表现:项目在垂直方向上居中,高度由自身内容或高度属性决定。这是非常常用的一个值。

  • baseline
    效果:所有项目根据它们文本的基线进行对齐。

视觉表现:无论每个项目的高度是否相同,它们的文字都会在同一水平线上对齐。这对于对齐不同字体大小的文本内容非常有用。

实战一下

掌握了基础知识,我们来个小案例实践以下,我们现在要制作如下的效果,想让他拥有一定的自适应,又不会变形很严重,应该怎么制作呢?

整体布局结构

  • 使用嵌套 flex 布局实现两行四列的卡片布局
  • 外层容器垂直排列,内层容器水平排列

主要布局代码分析

1. 外层容器 card-container

复制代码
.card-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 20px;
  width: 100%;
  box-sizing: border-box;
}
  • display: flex + flex-direction: column: 创建垂直方向的弹性布局
  • gap: 16px: 设置子元素(两行)之间的垂直间距
  • padding: 20px: 容器内边距,确保内容不贴边
  • box-sizing: border-box: 盒模型计算包含padding和border

2. 行容器 card-row

复制代码
.card-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 16px;
  width: 100%;
}
  • display: flex: 创建水平方向的弹性布局
  • flex-wrap: nowrap: 禁止换行,强制所有卡片在一行内显示
  • gap: 16px: 设置卡片间的水平间距
  • width: 100%: 占满父容器宽度

3. 卡片项 card-item

复制代码
.card-item {
  flex: 1 1 calc(25% - 12px);
  min-width: 300px;
}
  • flex: 1 1 calc(25% - 12px):
    • flex-grow: 1: 有剩余空间时可以放大
    • flex-shrink: 1: 空间不足时可以缩小
    • flex-basis: calc(25% - 12px): 初始宽度为25%减去间隙占用空间
  • min-width: 300px: 设置最小宽度,防止卡片过小

HTML结构说明

复制代码
<template>
  <div class="card-container">
    <!-- 第一行 -->
    <div class="card-row">
      <div v-for="card in cardList.slice(0, 4)" :key="card.id" class="card-item">
        <!-- 卡片内容 -->
      </div>
    </div>
    <!-- 第二行 -->
    <div class="card-row">
      <div v-for="card in cardList.slice(4, 8)" :key="card.id" class="card-item">
        <!-- 卡片内容 -->
      </div>
    </div>
  </div>
</template>
  • cardList.slice(0, 4): 取前4个卡片用于第一行
  • cardList.slice(4, 8): 取后4个卡片用于第二行
  • 每行独立的 card-row 容器确保两行布局的稳定性

这种布局方式在 flex-wrap: nowrap 的约束下实现了稳定的两行四列布局,并具有良好的响应式特性。

完整代码

复制代码
<!-- FlexLab.vue -->
<script setup lang="ts">
  interface CardItem {
    id: number;
    title: string;
    description: string;
  }

  const cardList: CardItem[] = [
    { id: 1, title: '卡片一', description: '第一个功能卡片' },
    { id: 2, title: '卡片二', description: '第二个功能卡片' },
    { id: 3, title: '卡片三', description: '第三个功能卡片' },
    { id: 4, title: '卡片四', description: '第四个功能卡片' },
    { id: 5, title: '卡片五', description: '第五个功能卡片' },
    { id: 6, title: '卡片六', description: '第六个功能卡片' },
    { id: 7, title: '卡片七', description: '第七个功能卡片' },
    { id: 8, title: '卡片八', description: '第八个功能卡片' }
  ];
</script>

<template>
  <div class="card-container">
    <!-- 第一行 -->
    <div class="card-row">
      <div
        v-for="card in cardList.slice(0, 4)"
        :key="card.id"
        class="card-item"
        >
        <h3 class="card-title">{{ card.title }}</h3>
        <p class="card-description">{{ card.description }}</p>
      </div>
    </div>
    <!-- 第二行 -->
    <div class="card-row">
      <div
        v-for="card in cardList.slice(4, 8)"
        :key="card.id"
        class="card-item"
        >
        <h3 class="card-title">{{ card.title }}</h3>
        <p class="card-description">{{ card.description }}</p>
      </div>
    </div>
  </div>
</template>

<style scoped>
  .card-container {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 20px;
    width: 100%;
    box-sizing: border-box;
  }

  .card-row {
    display: flex;
    flex-wrap: nowrap;
    gap: 16px;
    width: 100%;
  }

  .card-item {
    flex: 1 1 calc(25% - 12px);
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    border-radius: 12px;
    padding: 20px;
    color: white;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    transition: all 0.3s ease;
    box-sizing: border-box;
    min-width: 300px;
  }

  .card-item:hover {
    transform: translateY(-5px);
    box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);
  }

  .card-title {
    font-size: 18px;
    margin-bottom: 8px;
    font-weight: 600;
  }

  .card-description {
    font-size: 14px;
    opacity: 0.9;
  }


</style>

参考文献:

https://www.runoob.com/w3cnote/flex-grammar.html

相关推荐
2501_938780286 小时前
服务器 Web 安全:Nginx 配置 X-Frame-Options 与 CSP 头,防御 XSS 与点击劫持
服务器·前端·安全
IT_陈寒6 小时前
Java 17 新特性实战:这5个隐藏功能让你的代码效率提升50%
前端·人工智能·后端
艾小码6 小时前
2025年组件化开发这样做,效率提升300%
前端·javascript
驭风少年君13 小时前
《搭建属于自己的网站之网页前端学习》基础入门
前端·学习
刘一说14 小时前
深入理解 Spring Boot 嵌入式 Web 容器:从原理到性能调优
前端·spring boot·firefox
你的人类朋友14 小时前
设计模式的原则有哪些?
前端·后端·设计模式
!执行15 小时前
Web3 前端与合约交互
前端·web3·1024程序员节
潘小安15 小时前
跟着 AI 学(二)- Quill 接入速通
前端
十里-15 小时前
在 Vue2 中为 Element-UI 的 el-dialog 添加拖拽功能
前端·vue.js·ui