前端不能没有flex(有个问题求解答)

332 阅读6分钟

前言

在网页设计和开发中,布局是一个至关重要的方面。随着移动设备的普及和屏幕尺寸的多样化,响应式设计变得越来越重要。作为一个入局新手,采用传统的浮动和定位的方式来布局页面,实在是令我多有苦恼,flex的出现立刻让我为之倾心。

什么是Flex布局?

Flex布局是CSS3引入的一种新的布局模式,旨在提供更加灵活和自适应的布局方式。它基于"弹性盒子"模型,允许我们以一种简洁而直观的方式对元素进行布局,而无需使用传统的浮动或定位技术。

Flex布局的核心概念

在学习Flex布局之前,有几个核心概念是需要理解的:

  1. 主轴和交叉轴:Flex布局是基于主轴和交叉轴的概念。主轴是Flex容器的主要方向,可以是水平方向或垂直方向。而交叉轴则是与主轴垂直的方向。
  2. 弹性容器和弹性项:Flex布局中,容器称为“弹性容器”,而容器内的子元素则称为“弹性项”。
  3. 主轴对齐和交叉轴对齐:Flex布局通过justify-content属性控制主轴上的对齐方式,通过align-items属性控制交叉轴上的对齐方式。

justify-content

  1. flex-start:子元素在主轴上与 Flex 容器的起始位置对齐。
image.png
  1. flex-end:子元素在主轴上与 Flex 容器的结束位置对齐。
image.png
  1. center:子元素在主轴上居中对齐。
image.png
  1. space-between:在主轴上均匀地分配空间,使得子元素之间的间隔相等,且第一个和最后一个子元素与 Flex 容器的起始和结束位置对齐。
image.png
  1. space-around:在主轴上均匀地分配空间,使得子元素两侧的间隔相等,且子元素与 Flex 容器的起始和结束位置的间隔是其他间隔的一半。
image.png
  1. space-evenly:在主轴上均匀地分配空间,使得子元素之间及与 Flex 容器的起始和结束位置的间隔都相等。
image.png

Flex的三个组成属性(很多人会忽略)

  • flex-grow:该属性定义了弹性盒子的子元素在分配剩余空间时的放大比例。它接受一个非负数值作为参数,默认值为0。
  • flex-shrink:该属性定义了弹性盒子的子元素在空间不足时的收缩比例。它接受一个非负数值作为参数,默认值为1。
  • flex-basis:该属性定义了弹性盒子的子元素在分配多余空间之前,占据的主轴空间。它可以接受一个长度值、百分比值或者关键字作为参数,默认值为 auto。当设置为 auto 时,子元素的大小由其内容决定。

让我们用一个例子来说明:

假设有一个 .container,包含三个项目 .item,它们的 flex 属性分别为:

  • .item-1:flex: 1;,意味着它的 flex-grow :1,flex-shrink :1,flex-basis :0。
  • .item-2:flex: 2 1 100px;,意味着它的 flex-grow:2,flex-shrink:1,flex-basis :100px。
  • .item-3:flex: 1 0 50px;,意味着它的 flex-grow :1,flex-shrink:0,flex-basis:50px。

在这个例子中:

  • 初始情况下,.item-1 的尺寸是0,因为它的 flex-basis 为0;.item-2 的尺寸是100px,因为它的 flex-basis 为100px;.item-3 的尺寸是50px,因为它的 flex-basis 为50px。

  • 当容器有额外空间时,.item-1.item-2 和 .item-3 会按照它们的 flex-grow 值来分配剩余空间,.item-2 将获得的空间是其他两个项目的两倍。

.container的宽度为600px:

item-1:( 600-(100+50) ) / 4 * 1

item-2:( 600-(100+50) ) / 4 * 2+100

item-3:( 600-(100+50) ) / 4 * 1+50

image.png
  • 当容器空间不足时,.item-3 不会收缩,.item-1 和 .item-2 会根据它们的 flex-shrink 值进行收缩,.item-2 会收缩得更多。

扣除容量 = 子元素的flex-basis加起来减去父元素的宽度。

平分的比例 = 子项目的flex-basis * flex-shrink 除以每个子项目的flex-basis * flex-shrink之和

.container的宽度为100px:

NT = (100+50)-100 = 50

item-1:0-0 * 1 /(1 * 0 + 1 * 100 + 0 * 50)* NT = 0

item-2:100 - 100 * 1 /(1 * 0 + 1 * 100 + 0 * 50)* NT = 50

item-3:50 - 50 * 0 /(1 * 0 + 1 * 100 + 0 * 50)* NT = 50

当时感觉这种计算方式巨正确,结果把我雷的体无完肤!

大问题

完全不知道为什么会出现这样的结果,😰😰😰菜菜无法解决,求大佬们解答一下

image.png

得到解答了,是里面的字符撑开了宽度,但是计算方式是正确的,感谢m33作者的纠正指导!

image.png

代码

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>弹性布局</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .box {
      width: 100px;
      height: 200px;
      background: #4686bb;
      display: flex;
      align-items: center;
    }


    .item {
      height: 100px;
    }

    .item1 {
      background: pink;
      flex: 1;
    }

    .item2 {
      background: #6cc396;
      flex: 2 1 100px;
    }

    .item3 {
      background: #f0ee64;
      flex: 1 0 50px;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="item item1">item-1</div>
    <div class="item item2">item-2</div>
    <div class="item item3">item-3</div>
  </div>
</body>

</html>

其他属性

1.flex-direction

flex-direction 属性用于指定 Flex 容器的主轴方向。

  • 语法flex-direction: row | row-reverse | column | column-reverse;

  • 取值

    • row:水平方向,从左到右。
    • row-reverse:水平方向,从右到左。
    • column:垂直方向,从上到下。
    • column-reverse:垂直方向,从下到上。

2.flex-wrap

flex-wrap 属性用于控制 Flex 容器中的子元素是单行显示还是换行显示。

  • 语法flex-wrap: nowrap | wrap | wrap-reverse;

  • 取值

    • nowrap:不换行,所有子元素在一行显示。
    • wrap:换行,第一行在上方。
    • wrap-reverse:换行,第一行在下方。

3.flex-flow

flex-flow 是 flex-direction 和 flex-wrap 两个属性的缩写,用于同时设置主轴方向和换行方式。

  • 语法flex-flow: <flex-direction> <flex-wrap>;

  • 取值

    • <flex-direction>:决定了 Flex 容器的主轴方向,可以是 rowrow-reversecolumn 或 column-reverse
    • <flex-wrap>:决定了 Flex 容器中的子元素是单行显示还是换行显示,可以是 nowrapwrap 或 wrap-reverse

示例代码:

/* 设置主轴方向为水平,子元素不换行 */
.container1 {
  display: flex;
  flex-flow: row nowrap;
}

/* 设置主轴方向为垂直,子元素不换行 */
.container2 {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
}

/* 设置主轴方向为水平,子元素换行 */
.container3 {
  display: flex;
  flex-flow: row wrap;
}

最后

小编很喜欢通过写文章来温故而知新,如果你觉得小编的总结有帮助,请“一键三连”吧。