首页 > 代码库 > CSS3 ---flex box

CSS3 ---flex box

  flexbox布局是CSS3中新增的布局属性,但任何样式属性起作用的前提则是,它必须有对应的html结构。我们首先在html 文件中定义相应的结构,才能使用布局样式。我们简单地写一个ul li 列表,体验一个flex 布局的强大。新建一个index.html 书写结构,一个index.css 书写样式。

  index.html , 为了以后便于说明,给每一个li 作了一个1,2,3 标记。

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

  index.css, 主要是提供默认样式,以便后面进行操作。

ul {
    margin: 0;
    padding:0;
    width: 600px;
    margin: 100px auto;
    background: grey;
}
li {
  list-style: none;
  width: 100px;
  height: 100px;
  margin: 8px;
  text-align: center;
  line-height: 100px;
  font-size: 20px;
}
li:nth-child(1) {
    background: red;
}
li:nth-child(2) {
    background: green;
}
li:nth-child(3) {
    background: yellow;
}

  现在在html页面中展示如下:

技术分享

  基本的内容已经完成,现在可以使用flexbox了。使用flex布局,首先要定义一个flex容器。容器,容器,肯定是指父元素,因为它包含子元素,可以称之为容器,在我们这个例子中就是在ul,给ul设置怎样的样式才能使之成了flex 容器,那就是display: flex, 或display:inline-flex. 设为flex 或 inline-flex 都会使ul变成了flex容器,它们的区别是设置display:flex 后,ul 仍然是块级元素,独占一行,而display:inline-flex 则使ul 成了行内元素,可以和其他行内元素进行水平排列。我们可以在ul 后面添加一个span标签实验一个,html 修改如下

    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <span>测试ul 是行内元素还是块级元素</span>

  给ul添加dispaly: flex 属性:

ul {
    display: flex;   /*增加 display: flex;属性*/

    margin: 0;
    padding:0;
    width: 600px;
    margin: 100px auto;
    background: grey;
}

  可以看到页面如下,给ul 设置display:flex 后,ul仍然是块级元素

技术分享

   把ul 的display: flex 换成display:inline-flex,  页面展示如下:

技术分享

  display: inline-flex , 确实使ul变成了一个行内元素,在水平方向上进行排列。

  不管设置成什么,ul 都成了flex容器,因为我们发现, li元素由原来的垂直排列变成了水平排列。这时元素li也有了另外一个名称,叫flex items(flex 项目)。flex容器中的每一个元素都称之为一个flex项目。 这就是flex布局中非常重要的两个概念: flex 容器和flex 项目。

  当一个元素成为了flex容器后,它默认存在两根轴上,主轴(main axis)和 侧轴(cross axis), 它就是我们平常理解的水平轴和垂直轴,因为在一个平面中,只有这两根轴,flex布局也是在平面上布局,它也不例外,那为什么不叫水平轴和垂直轴?因为主轴的方向是不固定的,它即可以是水平方向,也可以是垂直方向。当主轴是水平方向时,侧轴就是重直方向,当主轴是垂直方向时,侧轴就是水平方向。 它有两种可能,所以不能简单称之为水平轴或垂直轴。

技术分享

  主轴是什么方向也很重要,因为它影响了flex 项目的排列。就像上图展示,如果主轴是水平方向,flex 项目就是水平方向依次排列。如果主轴是垂直方向,那么flex项目就会沿着垂直方向依次排列。所以当一个元素成为flex 容器时,我们首先要确定的就是主轴的方向。正好flex-direction属性提供这样的设置。

  flex-direction 定义了主轴的方向,相应地也确定了侧轴的方向,因为只有这两个轴且它们是垂直关系。它有四个属性值:row || row-reverse || column || column-reverse。

  row: 主轴为水平方向,元素从左边开始排列。

  row-reverse: 主轴方向为水平方向,不过元素从右向左开始排列。

  column: 主轴为垂直方向,元素从上到下排列。

  column-reverse: 主轴为垂直方向,不过元素是从下向上排列。

    reverse是反转的意思,row-reverse 就是表示,在row的基础进行反转,原来是从左到右排列,那么现在是从右到左, column-reverse 就表示从下到上。

技术分享

 

  它的默认值是row , 甚至我们不设置这个属性,它的值也是row.  这也就解释了上面,当我们只给ul 设置display:flex, 时,所有的li 横向排列。

  除了flex-direction之外,还有5个属性可以用到flex 容器上,就是父元素上,它们是: flex-wrap, flex-flow, Justify-content, Align-items, Align-content。下面 我们一一介绍

  flex-wrap: 它定义了当我们的flex项目非常多时,在flex容器中一行放不下时,元素怎么排列,到底换不换行。 它有三种属性值: nowrap, wrap 和wrap-reverse; 

    nowrap  是它的默认值,表示不换行,这么多项目始终在一行排列,这就导致了所有的项目都要进行缩小处理。

    wrap  表示可以换行,那么一行放不下的元素,就会放到下一行,形成了多行。

      wrap-reverse , 可能你已经猜到了,它也是表示可以换行,不过方向相反而已。

  我们给ul 元素分加别添加 这三个属性试一试, 这时我们设置方轴方向为row, flex-drection: nowrap

ul {
    display: flex;   /*增加 display: flex;属性*/
    flex-direction: row;  /*设置主轴方向*/
    flex-wrap: nowrap;    /*设置是否多行显示*/
    margin: 0;
    padding:0;
    width: 600px;
    margin: 100px auto;
    background: grey;
}

  由于li元素也较少,能在一行放下,我们再写几个li, 使flex 项目在一行放不下。

<ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
    </ul>

  这时页面展示如下,在no-wrap 下,无论flex项目有多少,它都不会换行,每个项目只会进行缩小来适应整个容器的宽度。

技术分享

  现在把flex-wrap:nowrap 改成flex-wrap:wrap, 可以看到以下展示,两行显示,flex项目换行了。

技术分享

  现在再把flex-wrap: wrap 换成 flex-wrap: wrap-reverse, 可以看到 元素换行,且第一行在下面,对上面的图进行了反转

技术分享

  flex-flow: 它是上面两个属性的简写,flex-flow: flex-direction 的取值  flex-wrap 的取值, 如: flex-flow: row wrap, 这时就不介绍了。

  Justify-content: 它定义了flex items 在主轴上怎样进行排列。 Flex-start , flex-end, center, space-between, space-around

  Align-items 定义了flex items 在侧轴cross axis上怎么进行排列。 Flex-start , flex-end, center ,stretch, baseline.  默认取值 stretch. Baseline 

  Align-content: 只有在flex-warp: wrap  形成多行时才起作用。它和aling-item 设置,多行时,元素在侧轴上怎么排列。

 

用在单个flex 项目上的属性:Order || Flex-grow || Flex-shrink || Flex-basis
 
Order 顺序,重新排列每一个flex item 顺序。默认属性是0,也就是每一个flex items 按照它们在html中定义的结构进行排列。 

Just content 定义的元素在主轴上怎么排列,是在容器的左边,右边还是中间。

Align items 定义的项目在侧轴上怎么排列。它有两个值strech base。Strech 就默认属性,如果我们的item 没有设置高度或高度为auto, 那么它会在侧轴方向上进行提伸,占满整个侧轴的空间。

Baseline 主要指的是如是flex-item 中有p , p标签中的下面对齐, 如果没有p标签,则元素的底部对齐。

Align self: 主要对一个元素在侧轴上的对齐方式进行设置,默认属性是auto,所以不设置的话,它跟align-item属性一致。 如果进行设置,它不会覆盖掉align-item属性。

 

单个flex item 属性的设置

         Flex-basis:控制每一个flex-item默认尺寸大小,在其它属性之前,它和item的宽度或高度相互换,如果我们设置的主轴是水平方向flex-direction row, 它就和元素的宽度相互换,如果我们设置的主轴方向是垂直方向flex-direction column, 它就和元素的高度相互换。

Flex-grow: 它指的是当flex-item没有占满整个flex-contain 的空间时,每一个元素怎么变化,要不要变大去占据空间,grow 就是生长,长大的意思,它的默认值是0,不会进行变化。 这时我们把每一个flex-item的flex-grow值设为1, 可以看到它占满了整个flex container的空间, flex-grow 的值覆盖了width的值。 那么这个属性值1 代表什么呢/? 我们把所有的值都设为999, 它的形为和刚才设为1 没有什么区别。

         现在我们把其中一个flex-item的值改为flex-grow 改为2, 可以发现这个元素变大了,再改3, 它更大了,从这里可以看出它不是一个绝对值,它是相对值,是某个元素相对其化元素的比例。当设置每一个项目的flex-grow 为1时,一共有6 个元素,那么就是6,整个flex-container会被分成6份,每一个flex-item 各占一份,所以都相同。如果我们其中一个flex-flow设为2. 还是6个元素,那么整个flex container 就分成1+1+2+1+1+1 = 7份,其余5个各1/7, 而第三个占2/7,所以第三个就相对变大了, flex-grow 设置的某个或某些项目相对于其他项目的比例。

 

Flex-shrink : shrink 收缩,当每一个flex item 的宽度总和超过 flex-contaier容器的时候,每一个项目都会进行收缩。它的默认值是1, 表示每一个元素都会比例收缩。 如果把某个元素的flex-shrink 设为0, 它就不会进行收缩。 如果把它设置3,和flex-grow 一样,它也是比例,每一个flex item收缩1, 它收缩3, 它比别的项目收缩更严重。

Flex: 是上面三个属性简写,像边框border属性一样。 Flex: flex-grow flex-shrink flex-basis

它的默认取值为0 1 auto,这和我们平时没有设置这个属性表现一致,flex-basis: auto 表示,它和元素的宽度或高度保持一致,flex-grow等于0, 表示 如果父元素有剩余空间,它并不会扩大,

Flex-shrink, 如果父元素空间不足,它会进行收缩。

 

现在我们设置两个元素,一个是flex: 2 1 300px;  一个是1 2 300px;  父元素的宽度为640px;正好放下这个元素。

现在我们看一下flex-shrink是怎么工作的?当我们把容器宽度改为430px; 整个容器损失了210px的空间,由于第一个元素的flex-shrink 是1, 第二个shrink是2, 所以这损失的210px, 分成了3份,第一个元素占1份,也就是70px, 所以第一个元素损失了70px,宽度变为了300-70 =230px; 第二个元素占两份,也就是140px, 所以第二个元素损失了140px;宽度变为了300-140= 160px; flex-grow 的工作原理也是一样,当我们把容器宽度增大到940px;时, 它多获得了300px的空间,每一个元素都会增大,由于第一个是flex-flow是2, 第二个flex-flow是1, 所以这多出来的300px, 也是分成了3份,第一个项目占2份,200px, 宽度增大到300+200 =500px; 第二个占1份,100px, 宽度增大到300+100 =400px;



CSS3 ---flex box