CSS3 flexbox 布局 ---- flex 容器属性介绍

时间:2023-01-11 04:11:58

  flexbox布局是CSS3中新增的属性,它可以很轻松地帮我们解决掉一些常见的布局问题,比如导航栏。 我们用普通的方法写导航栏,通常会在ul, li 结构写好后,让li 元素左浮动,然后再给ul 清浮动。但用flex布局,直接给ul 一个display:flex 样式就可以了。如果不相信,可以试一试。新建一个文件夹flexbox, 然后再新建index.html ,在其中写一个ul li 列表,


<ul>
  <li>电脑</li>
  <li>手机</li>
  <li>平板</li>
</ul>

  然后在内嵌样式style标签中,写下 ul { display:flex}, 三个li 水平排列了,再也不用float:left了,更不用时时记着清浮动了。当然这只是flexbox 布局最简单的使用,但这也体现了flexbox布局的强大。

ul {
    display:flex
}

  CSS样式的学习,就是不停地实验其属性,然后看这个属性在浏览器中的表现形式,如果有一个工具,在我们更改样式后,它能自动刷新浏览器显示更改后的属性就好了,省得按F5了,还能直观地看到样式的变化。屏幕左边是浏览器,右边是编辑器,我们在编辑器中更改了样式,然后盯着浏览器,这时左手按一个ctrl +s 保存, 浏览器自动刷新,样式变化,我们可以清晰看到变化的过程,完美。幸好,我们有webpack 和gulp等构建工具,它们可以帮助我们。gulp+ browsersync 的搭配非常完美,gulp的官网有其使用介绍,webpack 自带的webpack-dev-server 也不错, 我们这里简单使用一个webpack.

  当使用webpack构建工具时,我们的代码就变成了node 项目。对于一个项目,node建议要有一个package.json 文件,记录项目的版本,开发时的依赖等。在flexbox文件夹中,按shift键,点击鼠标右键,在出现的右键菜单中点击“在此处打开命令窗口” ,出现cmd命令窗口,在其中输入npm init -y,  就可以快速创建package.json文件。刚才说了要用到webpack-dev-server, 使用它就要先安装它,在命令窗口中接着输入npm install webpack webpack-dev-server -D. 我们这里要写css 文件,而webpack 把css 也是看作一种资源,在js文件中引进,所以要用loader进行解析,npm install css-loader style-loader -D 安装loader.  在该文件夹下,再新建webpack.config.js 文件,它是webpack 的配置文件,webpack 进行打包的时候,就是依靠它里面的定义的规则进行打包。

webpack.config.js文件如下:

var path = require('path');
module.exports = {
    entry:'./index.js',
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    module: {
        rules: [
            {
                test:/\.css$/,
                use: ['style-loader','css-loader']
            }
        ]
    }
}

  最后就是如何启动webpack-dev-server 了,这时打开package.json文件,找到script 字段,然后改为如下内容:

"scripts": {
    "dev": "webpack-dev-server --open"
  },

  好了,在命令窗口中只要输入npm run dev就可以启动服务了,配置完成了。那我们先写一点内容,看看配置有没有问题。css书写之前,都是先清除元素的默认样式,新建一个reset.css 文件,

ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

  新建index.js 文件,引入reset.css,

require('./reset.css')

  再修改一下html 文件,body 标签最下面写 <script src="bundle.js"></script>,还要把内嵌的style 标签去掉

<body>
    <ul>
      <li>电脑</li>
      <li>手机</li>
      <li>平板</li>
    </ul>
    <script src="bundle.js"></script>
</body>

  在命令窗口中输入npm run dev, 可以看到它打开了浏览器,默认样式成功清除了,打开的浏览器是你平时上网用的默认浏览器。为了以后学习flexbox, 我们把样式调整好看一些,新建index.css

ul {
    width: 600px;
    height: 300px;
    border: 1px solid red;
}
li {
  width: 100px;
  height: 100px;
  background-color: #8cacea;
  margin: 8px;
}

  在index.js 中再引入它

require('./reset.css')
require('./index.css')

  按ctrl +s 保存后,浏览器自动刷新,变成如下样子,我们配置没有问题。样式不是太好看,嗯,就这样吧。

CSS3 flexbox 布局 ---- flex 容器属性介绍

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

<ul>
    <li>电脑</li>
    <li>手机</li>
    <li>平板</li>
</ul>
<span>测试ul 是行内元素还是块级元素</span>

  给ul添加dispaly: flex 属性,

ul {
    width: 600px;
    height: 300px;
    border: 1px solid red;
    display: flex;  /*增加 display: flex;属性*/
}

 页面如下展示,span 元素另起一行,可见ul仍是块级元素。

CSS3 flexbox 布局 ---- flex 容器属性介绍

   把ul 的display: flex 换成display:inline-flex

ul {
    width: 600px;
    height: 300px;
    border: 1px solid red;
    display: inline-flex;  /*增加 display: inline-flex;属性*/
}

  页面展示效查如下,display: inline-flex , 确实使ul变成了一个行内元素,在水平方向上进行排列。

CSS3 flexbox 布局 ---- flex 容器属性介绍

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

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

CSS3 flexbox 布局 ---- flex 容器属性介绍

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

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

  row: 主轴为水平方向,起点为容器的左侧。

ul {
    width: 600px;
    height: 300px;
    border: 1px solid red;
    display: flex;
    flex-direction: row;
}

  页面展示如下,可以看到和没有设置这个属性之前表现一致,因为这是它的默认属性, 甚至我们不设置这个属性,它的值也是row.

CSS3 flexbox 布局 ---- flex 容器属性介绍

  row-reverse: 主轴方向为水平方向,不过起点为容器的右侧。flex-direction属性值改为 row-reverse, flex项目在水平方向上从右向左排列

CSS3 flexbox 布局 ---- flex 容器属性介绍

  column: 主轴为垂直方向,起点为容器的顶部。

CSS3 flexbox 布局 ---- flex 容器属性介绍

  column-reverse: 主轴为垂直方向,不过起点为容器的底部。元素从下从上排列了,

CSS3 flexbox 布局 ---- flex 容器属性介绍

  在依次设置这四个属性值的时候,请注意第一个元素(电脑)的位置。

  设置了主轴方向后,flex项目就按照主轴的方向进行排列,比如我们这里设置了flex-direction:row,元素默认从左边向右排列,这时我们想让元素进行居中显示或靠右显示, flex布局能不能做到? 能, 这里要用到just-content 属性, 它就是定义flex 项目在主轴上怎样排列, 有五个属性值: flex-start , flex-end, center, space-between, space-around,现在依次给 ul 设置这五个属性值。

ul {
    width: 600px;
    height: 300px;
    border: 1px solid red;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
}

  flex-start: 从主轴的起点开始排列,由于flex-direction:row ,主轴的起点在左侧,所以它从左向右显示, 这也是它的默认属性,也解释了只设置flex-direction:row时,元素从左向右显示.

  flex-end: 从主轴的终点开始排列,起点在左侧,从左向右, 那么终点就是右侧,flex容器的右侧, flex 项目从右向左排列.

CSS3 flexbox 布局 ---- flex 容器属性介绍

  flex-center: 在主轴的中间进行排列.

CSS3 flexbox 布局 ---- flex 容器属性介绍

 space-between: 当主轴方向有剩余空间时, 整个剩余空间在三个flex项目之间进行平分.

CSS3 flexbox 布局 ---- flex 容器属性介绍

  space-around: 也是当主轴方向上有剩余空间时, 剩余容间要包围flex 项目,和space-between 相比,第一个元素和第三个元素与flex容器的两侧有空间。如查你仔细测量的话,它的距离是 两个flex项目之间的距离的1/2.

  CSS3 flexbox 布局 ---- flex 容器属性介绍

  现在我们一直在水平方向上进行操作,垂直方向上呢? 垂直方向上能不能操作, 这又是另外一个属性align-items了, 它就规定了flex 项目在侧轴上怎么排列,在我们这里就垂直方向上怎么排列,它也有5个属性: flex-start ,flex-end center, stretch, baseline

  flex-start, flext-end, center 和just-content 一样,只不过这里指的是侧轴的起点,终点,和中间位置. 简单用图片展示一下,为了更为明显地看到垂直方向上的排列,我们把li 三个元素的高度设为都不一样, 同时给ul 添加 align-items 属性, 先从flex-start 开始

ul {
    width: 600px;
    height: 300px;
    border: 1px solid red;
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: flex-start;
}
li {
    width: 100px;
    margin: 8px;
    padding: 4px;
    background-color: #8cacea;
}
li:nth-child(1) {
    height: 30px;
}
li:nth-child(2) {
    height: 60px;
}
li:nth-child(3) {
    height: 90px;
}

  flex-start:  在侧轴的起始点对齐, flex项目顶部对齐

CSS3 flexbox 布局 ---- flex 容器属性介绍

  flex-end: 在侧轴的终点处对齐, fllex项目底部对齐。

CSS3 flexbox 布局 ---- flex 容器属性介绍

  center: 在侧轴的中间对齐, flex项目中心点在侧轴的中心上。

CSS3 flexbox 布局 ---- flex 容器属性介绍

  stretch: 在英文中它有拉伸的意思, 在这里主要指, 如果flex项目没有设置高度,或高度为auto的话,那么它会在侧轴方向上进行拉伸,占满整个侧轴的空间。现在把第一个li(电脑)的高度去掉, 就可以看到效果. 它是align-items的默认属性, 只不过,我们在一开始的时候就设置了高度把它覆盖掉了.

CSS3 flexbox 布局 ---- flex 容器属性介绍

  baseline:主要指的是如果flex项目中有内容 , 它会按照内容中的第一行文字的底部进行对齐. 如果没有内容,则按项目的底部对齐。我们这时正好有内容, 所以它就会按这三个字的底部进行对齐.现在恢复第一个体li 的高度为30px , 我们没有看到太大变化,像flex-start, 这是给第三个li 设一个line-height:90px,

li:nth-child(1) {
    height: 30px;
}
li:nth-child(2) {
    height: 60px;
}
li:nth-child(3) {
    height: 90px;
    line-height: 90px;
}

   现在看到变化了,内容第一行文字底部对齐。

CSS3 flexbox 布局 ---- flex 容器属性介绍

  现在把文字去掉,

<ul>
        <li></li>
        <li></li>
        <li></li>
 </ul>

可以看到它们按照底部对齐.

CSS3 flexbox 布局 ---- flex 容器属性介绍

  现在是我们只有三个flex项目,flex 容器一行内就可以把它们全放下,但如果项目增多怎么办,比如5个,8个,一行有可能放不下,放不下之后怎么办,是在一行显示,还是在多行显示, 这就到了flex-wrap属性。flex-wrap: 定义了当我们的flex项目非常多时,在flex容器中一行放不下时,元素怎么排列,到底换不换行。 它有三种属性值: nowrap, wrap 和wrap-reverse。

  现在我们先增加几个li再说,先增加3个,这里把所有的li高度都调成了一样100px, 看到它们仍在一行显示,但每一个项目的宽度似乎变小了. 这里要注意,在html 中增加元素,浏览器并不会自动刷新, 在这里需要手动刷新一下, webpack-dev-server 并没有监测html的变化。

<ul>
        <li>电脑</li>
        <li>手机</li>
        <li>平板</li>
        <li>平板</li>
        <li>平板</li>
        <li>平板</li>
 </ul>

  再增加3个li, 一共9个li

<ul>
        <li>电脑</li>
        <li>手机</li>
        <li>平板</li>
        <li>平板</li>
        <li>平板</li>
        <li>平板</li>
        <li>手机</li>
        <li>手机</li>
        <li>手机</li>
    </ul>

  可以看到它们仍在一行,不过宽度确实变窄了, 这就是 flex-wrap 的默认值no-wrap在起作用,nowrap 表示不换行,这么多项目始终在一行排列,这就导致了所有的项目都要进行缩小处理。这时给ul 添加 flex-wrap: nowrap,可以看到没有什么变化,默认值本来就是这样。

CSS3 flexbox 布局 ---- flex 容器属性介绍

  现在把nowrap 换成wrap, 同时把flex容器 ul的高度调高,其它属性设置默认样式,就是不设置其他属性

ul {
    width: 600px;
    height: 700px;
    border: 1px solid red;
    display: flex;
    flex-wrap: wrap;
}

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

CSS3 flexbox 布局 ---- flex 容器属性介绍

  wrap-reverse , 可能你已经猜到了,它也是表示可以换行,不过方向和wrap相反而已。在wrap 中的第一行在顶部,到了wrap-reverse下就到了底部,相当于围绕横轴旋转180度,可以自己试一下。

  当有多行显示的时候,我们发现一行和一行的之间的距离太大了,有没有办法调节一下行与行之间的距离? 这就要考虑align-content 的属性了。align-content: 就是控制当flex 项目进行多行显示时,且在侧轴上有剩余空间时,行与行之间怎么排列。它的取值有6个, flex-start, flex-end, center, stretch, space-between,space-around.

  我们给ul设置align-content: stretch, 可以看到没有什么变化,这是它的默认属性。这个属性里有两个意思:

  1. 如果flex项目有高度时,行与行之间的距离相等,均分了侧轴的剩余空间, 如上图所示,我们可以在ps中测量一下,第一行和第二行的距离 与第二行和第三行的距离相等

CSS3 flexbox 布局 ---- flex 容器属性介绍

  2. 如果flex项目没有高度或高度为auto时,项目进行拉伸,占满整个侧轴。去掉li的高度

CSS3 flexbox 布局 ---- flex 容器属性介绍

  flex-start, flex-end, center, space-around, space-between 和 justify-content 调整主轴之间的剩余空间表现一致,这里就不再展示了. 这里注意的时,align-content起作用的前提: 1,  在侧轴上必须在多行显示, flex-wrap: wrap , 如果只有一行是不起作用的, 2, 在侧轴上必须有剩余空间.

  还有最后一个属性flex-flow 就完事了, flex-flow: 它是flex-direction 和flex-wrap 两个属性的简写,flex-flow: flex-direction 的取值  flex-wrap 的取值, 如: flex-flow: row wrap, 它和分开写没有什区别, 就是 border 属性一样, 可以分开写,也可以合在一起写, 这也就不介绍了,