你不知道的 CSS flex 陷阱

简介: 本文通过一个实际案例,深入解析了使用CSS Flexbox布局时,因`flex-wrap: wrap`与父容器高度设置导致的意外间距问题。作者指出,该现象源于`align-content`属性的默认行为(stretch),并通过设置`align-content: flex-start`有效解决。文章还对比了MDN与W3C文档对该属性默认值的差异,并系统梳理了`flex-wrap`和`align-content`的用法,帮助开发者更好掌握多行Flex布局的控制技巧。

目录

前言

你好,我是喵喵侠。在现代Web开发中,CSS的Flexbox布局模式,因其灵活性和简洁性而备受推崇。然而,即使是经验丰富的前端开发者,有时也会遇到一些令人困惑的问题。例如,当我们使用 flex-wrap: wrap 属性后,发现元素之间出现了意想不到的上下间距,这到底是为什么呢?怎么样才能解决这个问题呢?

我将会在本文中,为你详细探讨这一现象的原因,并提供具体的解决方法。与此同时,我也会穿插一些与此案例相关的Flexbox属性教程,以帮助你更好地理解和应用Flexbox布局。

问题描述

某次我做项目时候,用到了 flex 布局,布局的页面效果,大概是一个父容器盒子 div 里面,有几个子元素 div,这几个子元素 div 一行大概只能放下 3 个,超出就需要换行显示了。显示效果是依次从左到右,从上至下排列,如下图所示:

请在此添加图片描述

知道要换行,当然就用flex-wrap:wrap这个了,这代表 flex 布局的子元素需要换行显示。

正当我洋洋得意,以为这个小问题立马被搞定时,现实给我泼了一盆冷水,奇怪的事情发生了!

效果跟我上面预想的不太一样,第一行和第二行之间,出现了莫名的间距。

请在此添加图片描述

为了更好的展示我当时有问题的代码,我把示例代码简化成了这样:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    .container {
      display: flex;
      flex-wrap: wrap;
      width: 300px;
      height: 300px;
      background-color: lightgrey;
    }

    .item {
      width: 100px;
      height: 100px;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 36px;
      font-weight: bold;
    }

    .item:nth-child(1) {
      background-color: cornflowerblue;
    }

    .item:nth-child(2) {
      background-color: lightblue;
    }

    .item:nth-child(3) {
      background-color: pink;
    }

    .item:nth-child(4) {
      background-color: lightgreen;
    }
  </style>
  <title>Flexbox Wrap 案例分享</title>
</head>

<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
  </div>
</body>

</html>

仔细看没毛病啊,我也没有设置对齐方式什么的,这个间距是哪儿来的呢?

解决办法

我想,我可能是对 flex 还是不够了解。我翻阅了MDN 文档关于flex-wrap的描述,也没有发现端倪。

我通过G 字头的搜索引擎,查询关键词flex-wrap 出现间距 ,得到的第一个结果,就是我想要的答案。

请在此添加图片描述

答案其实很简单,一行代码就能搞定,在父盒子上,加一行代码可以搞定:

align-content:flex-start;

这样设置,是从起始点开始放置 flex 子元素,而align-content的默认值是stretch,会让元素均匀分布,这样就导致了元素之间出现了间隙。

另外我发现,如果我不设置高度,子元素换行是不会有这个垂直间隙的,而我正好设置了父容器盒子的高度。

总的来说就是,flex-wrap +父盒子高度设置,致使我落入了align-content 的陷阱。

小插曲

我在寻找align-content 默认值出处的时候,翻阅了 MDN 文档,发现文档描述的初始值是 normal 而不是stretch

请在此添加图片描述

W3C 的官方文档,写的align-content 默认值是stretch

请在此添加图片描述

两个都是业内非常权威的文档,却因为这个属性,出现了不一致的描述。为了验证下,我在浏览器用审查元素,查看了下父容器盒子的计算属性,发现默认值是 normal

请在此添加图片描述

tips:一开始看不到这么多的属性,选中 Show all即可查看全部计算后属性。

我又问了下AI助手,给出的解释是,大部分情况下这二者表现差异不大,几乎可以等同。

请在此添加图片描述

这样一来就清楚了,无论align-content 的默认值是哪个,都会对有高度的容器内的子元素进行拉伸排布。

flex 布局属性

问题解决了,让我们来复习一下flex-wrapalign-content的属性。

flex-wrap

flex-wrap 属性定义了当一行容不下所有子元素时,如何进行换行。它有三个可能的值:

  • nowrap(默认):所有子元素将在一行中排列。
  • wrap:子元素会在必要时换行。
  • wrap-reverse:子元素会在必要时换行,但新行会排列在上一行的上方。

align-content

align-content 属性在有多行时,用于定义这些行在容器内的排列方式。常用值包括:

  • flex-start:所有行位于容器的顶部。
  • flex-end:所有行位于容器的底部。
  • center:所有行位于容器的中央。
  • space-between:行之间的间距相等,首行和末行紧贴容器边缘。
  • space-around:行之间的间距相等,首行和末行与容器边缘有一半的间距。
  • stretch(默认):行将拉伸以填满容器的高度。

总结

通过这篇文章,想必你对使用 flex-wrap: wrap 后元素之间意外间距出现的原因非常熟悉了,下次遇到你就知道可以通过设置 align-content 属性来解决这一问题。

Flexbox布局模式提供了强大的功能和灵活性,但要充分利用它,我们需要深入理解其属性和行为。在实践过程中,我们需要通过不断尝试和调试,才能够更好地掌握Flexbox的使用技巧,从而创建出更为灵活和美观的网页布局。

希望这篇文章能够帮助你解决实际开发中的问题,同时对Flexbox布局有更深入的理解。如果你有任何疑问或建议,欢迎在评论区与我交流讨论哦。

参考

flex-wrap: wrap 之后元素上下间距过大怎么解决?_消除display: flex; 上下间距-CSDN博客

目录
相关文章
|
6天前
|
前端开发 开发者 容器
如何解决 flex 布局下子元素 width 宽度设置失效的问题
本文通过实际案例,探讨前端开发中flex布局导致子元素宽度设置失效的问题,分析原因并提供两种解决方案:去除flex布局(不推荐)和设置min-width(推荐),帮助开发者深入理解flex特性,提升布局控制能力。
65 0
如何解决 flex 布局下子元素 width 宽度设置失效的问题
|
6天前
|
前端开发 JavaScript 定位技术
前端表单输入框自动填充和覆盖逻辑的实现
本文介绍Web开发中表单联动的实现方案,针对输入框与下拉框的数据填充需求,提出两种解决思路:一是通过比对选项label判断是否覆盖,二是监听用户输入行为设置flag开关。结合Vue与Element-UI实战代码,详解如何智能控制数据填充逻辑,避免覆盖用户手动输入内容,提升表单交互体验。
55 0
前端表单输入框自动填充和覆盖逻辑的实现
|
6天前
|
JavaScript 前端开发 定位技术
Vue项目中的虚拟滚动:提升页面渲染性能的最佳实践
本文介绍虚拟滚动技术及其在Vue项目中的应用,通过vue-virtual-scroller实现大数据量下长列表的高性能渲染,提升页面流畅度与用户体验,适用于地图轨迹等业务场景。
90 0
|
6天前
|
JavaScript Linux iOS开发
使用 nvs 工具来切换 node 版本
nvs是一款跨平台Node版本管理工具,支持Windows、macOS和Linux,可轻松切换不同项目的Node版本。本文介绍其安装方法、常用命令(如添加、切换、默认版本设置)及实用技巧,助力多项目高效开发。
81 0
使用 nvs 工具来切换 node 版本
|
6天前
|
人工智能 JavaScript UED
如何实现两个下拉选择框 select选中联动效果?
本文通过一个公司与产品联动的下拉选择案例,详细讲解了Element UI中双向联动下拉框的实现方法。涵盖数据过滤、回显处理、重置功能及注意事项,结合Vue实战代码,帮助开发者提升表单交互体验,适用于各类关联选择场景的开发参考。(238字)
96 0
如何实现两个下拉选择框 select选中联动效果?
|
6天前
|
文字识别 程序员 数据安全/隐私保护
macOS 上值得推荐的软件(第一弹)
本文推荐三款提升macOS使用效率的优质软件:Longshot(支持滚动截图的截图工具)、Mos(优化鼠标平滑滚动与方向设置)、NetNewsWire(免费开源RSS阅读器)。涵盖截图、系统操作与信息获取场景,助力程序员高效工作。无广告,可免费试用,欢迎体验与分享。
48 0
macOS 上值得推荐的软件(第一弹)
|
6天前
|
移动开发 前端开发 JavaScript
uni-app实战案例:实现H5页面麦克风权限获取与录音功能
本文介绍如何在uni-app的H5页面中实现麦克风权限获取与录音功能,涵盖音频流转换为Blob、Base64及文件下载的完整方案,助力前端语音交互开发。
147 0
|
6天前
|
自然语言处理 前端开发 Windows
推荐一款很好用的VSCode变量翻译插件
本文介绍VSCode插件“var-translate-en”,可一键将中文翻译为英文并转为小驼峰等命名格式,支持百度、腾讯、阿里等翻译服务。通过简单配置与快捷键设置,提升变量命名效率,解决命名难题。
117 0
|
6天前
|
Linux Android开发 iOS开发
新一代的抓包神器——Reqable
本文介绍全平台抓包工具Reqable,支持Windows、Mac、Linux及Android、iOS,操作简单,无需复杂配置,可轻松抓取HTTP/HTTPS和WebSocket请求,适合开发者快速分析数据,提升调试效率。
173 0
|
6天前
|
JavaScript 数据可视化 前端开发
从零开始:使用 Vue-ECharts 实现数据可视化图表功能
本文介绍如何使用 Vue-ECharts 在 Vue 项目中快速开发图表,重点讲解安装、引入方式及分组柱状图的实现,帮助开发者高效完成数据可视化。
144 0