文章类别:首页>编程技术>前端>CSS

CSS弹性布局:Flex弹性盒布局详解教程

发布时间:2024-11

浏览量:157

本文字数:4957

读完约 17 分钟

flex布局发展的背景原因

    布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

    2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持。Flex 布局是一种新型的 CSS 布局模式,它主要用于弹性盒子布局。相比于传统的布局方式,它更加灵活,易于调整,也更加适应不同的设备和屏幕尺寸。

Flex布局是什么?

    Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。

    flexbox,是一种一维的布局模型。一个 flexbox 一次只能处理一个维度上的元素布局,一行或者一列。作为对比的是另外一个二维布局 CSS Grid Layout,可以同时处理行和列上的布局。

image.png

任何一个容器都可以指定为Flex布局。

.box{
  display: flex;
  }

行内元素也可以使用Flex布局。

.box{
  display: inline-flex;
  }

Webkit内核的浏览器,必须加上-webkit前缀。

.box{
  display: -webkit-flex; /* Safari */
  display: flex;
  }

设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。

Flex的使用

1、基本概念

image.png

1)容器与项目

    采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。

    容器(Container):设置了display: flex; 的元素成为Flex容器。容器内的子元素自动成为Flex项目。

.container{
  display: flex;
}

<div class="container">
  <div class="item"> </div>
  <div class="item">
    <p class="sub-item"> </p>
  </div>
  <div class="item"> </div>
</div>

    上面代码中, 最外层的 div 就是容器,内层的三个 div 就是项目。

    项目只能是容器的直接子元素,不包含项目下的子元素,比如上面代码的 p 元素就不是项目。flex布局只对直接子元素生效。

2)轴线

    容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。

    项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

image.png

主轴(main axis)

    沿其布置子容器的从 main-start 开始到 main-end ,请注意,它不一定是水平的;这取决于 flex-direction 属性(见下文), main size 是它可放置的宽度,是容器的宽或高,取决于 flex-direction。

交叉轴(cross axis)
    垂直于主轴的轴称为交叉轴,它的方向取决于主轴方向,是主轴写满一行后另起一行的方向,从 cross-start 到 cross-end , cross size 是它可放置的宽度,是容器的宽或高,取决于 flex-direction。

2、容器属性

容器的属性主要包括:(写在容器元素内)

flex-direction:定义了主轴的方向,可以是水平或垂直,以及其起始和结束的方向。

flex-wrap:决定了当容器空间不足时,项目是否换行。

flex-flow:这是flex-direction和flex-wrap的简写形式。

justify-content:设置项目在主轴上的对齐方式。

align-items:定义了项目在交叉轴上的对齐方式。

align-content:定义了多根轴线时,项目在交叉轴上的对齐方式。

gap row-gapcolumn-gap:设置容器内项目间的间距

1)主轴方向(flex-direction)

    flex-direction定义主轴的方向,也就是子项目元素排列的方向。

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

row(默认值):主轴为水平方向,起点在左端。

row-reverse:主轴为水平方向,起点在右端。

column:主轴为垂直方向,起点在上沿。

column-reverse:主轴为垂直方向,起点在下沿。

image.png

2)换行(flex-wrap)

    默认情况下不换行(nowrap),项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

image.png

.container {
  flex-wrap: nowrap | wrap | wrap-reverse;
}

nowrap(默认):不换行。

image.png

wrap:换行,第一行在最上方,后续向下换行排列。

image.png

wrap-reverse:换行,第一行在最下方,后续向上换行排列。

image.png

3)简写(flex-flow)

    flex-direction 和 flex-wrap 属性的简写,默认值为 row nowrap。

.box {
  flex-flow: <flex-direction> <flex-wrap>;
  }

image.png

4)主轴对齐方式(justify-content)

    justify-content属性定义了项目在主轴上的对齐方式。默认是 flex-start。

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

它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。

flex-start(默认值):左对齐

flex-end:右对齐

center: 居中

space-between:两端对齐,项目之间的间隔都相等。

space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

image.png

5)交叉轴对齐方式(align-items)

    align-items属性定义项目在交叉轴上如何对齐。

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
  }

它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。

flex-start:交叉轴的起点对齐。

flex-end:交叉轴的终点对齐。

center:交叉轴的中点对齐。

baseline: 项目的第一行文字的基线对齐。

stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

image.png

6)多根轴线对齐方式(align-content

    align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

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

该属性可能取6个值。

flex-start:与交叉轴的起点对齐。

flex-end:与交叉轴的终点对齐。

center:与交叉轴的中点对齐。

space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。

space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。

stretch(默认值):轴线占满整个交叉轴。

image.png

7)间距(gap | row-gap | column-gap)

    设置容器内项目之间的间距,只控制项目与项目的间距,对项目与容器的间距不生效。

.container {
  display: flex;
  ...
  gap: 10px;
  gap: 10px 20px; /* row-gap column gap */
  row-gap: 10px;
  column-gap: 20px;
}

image.png

3、项目属性

项目 item 的属性包括:(写在每个项目元素内)

order:指定了项目的排列顺序。

flex-grow:定义了在有可用空间时的放大比例。

flex-shrink:定义了在空间不足时的缩小比例。

flex-basis:指定了项目在分配空间前的初始大小。flex:这是flex-grow、flex-shrink和flex-basis的简写形式。

align-self:允许单个项目独立于其他项目在交叉轴上对齐。

1)排序位置(order)

    order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

.item {
  order: <integer>;
  }

image.png

2)弹性成长(flex-grow)

    flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

    定义的是可放大的能力,0 (默认)禁止放大,大于 0 时按占的比重分放大,负数无效。

    在容器主轴上存在剩余空间时, flex-grow才有意义。

.item {
  flex-grow: <number>; /* default 0 */
  }

    如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

image.png

3)弹性收缩(flex-shrinik)

    flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

    当容器主轴 “空间不足” 且 “禁止换行” 时, flex-shrink才有意义。定义的是可缩小的能力,1 (默认)等大于 0 的按比例权重收缩, 0 为禁止收缩,负数无效。

.item {
  flex-shrink: <number>; /* default 1 */
  }

image.png

    如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

4)弹性基值(flex-basis)

    flex-basis 指定了 flex 元素在主轴方向上的初始尺寸,它可以是长度(例如 20% 、 5rem 等)或关键字。felx-wrap根据它计算是否换行,默认值为 auto ,即项目的本来大小。它会覆盖原本的width 或 height。

.item {
  flex-basis: <length> | auto; /* default auto */
  }

    它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。

5)弹性简写(flex)

    flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

image.png

6)自我对齐(align-self)

    允许为单个弹性项目覆盖默认的交叉轴对齐方式 align-items。

    默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
  }

image.png

弹性与网格的区别

    弹性盒子是一维布局方法,而网格布局是二维布局方法。

    弹性元素允许换行,但是一旦这样做,每一行都会变成一个新的弹性容器。当空间被分配时,弹性盒子不会参考其他行中的元素的位置,而只是将元素彼此对齐。

.box {
  display: flex;
  flex-wrap: wrap;
}

.box>* {
  flex: 1 1 200px;
}

<div class="box">
  <div>One</div>
  <div>Two</div>
  <div>Three</div>
  <div>Four</div>
  <div>Five</div>
  <div>Six</div>
  <div>Seven</div>
</div>

image.png

    如果我们使用网格布局创建一个非常相似的布局,我们可以控制行和列的布局。

.box {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, auto));
}

image.png

    在网格布局中,你需要在容器上设置大部分尺寸规范,设置轨道然后将元素放入其中。在弹性盒子中,虽然你创建了弹性容器并设置了该级别的方向,但是对元素大小的任何控制都需要在元素本身之上进行。

^