一、弹性盒模型(伸缩布局)
flxible box
前言:
弹性布局,用来为盒子提供灵活性。就像是当把浏览器缩小的的时候,不会像float属性会依然往下掉,灵活性不好。而且当布局盒装模型的时候依赖于float+position+display,例如实现垂直居中就很不方便了。
一)语法
{display: flex;} /*作为块级伸缩盒子显示*/
{display: inline-flex;} /*作为内联块级伸缩盒子显示:行内的元素也能使用*/
是不是感觉很熟悉呢?这就类似于 block 和 inline-block 。
注意:
1.任何的元素都能设置flex ;
2.兼容: {display: -webkit-flex;display: flex;} ;
3.当 {display:flex;} 后float、.clearfix 、vertical-align全部都失效;
4.要在 {display:flex;} 的盒子上设置宽度max-width:;而不是width这样浏览器才能按比例去伸缩’;
5.关于p{flex:1;}:子元素即使有宽也没有什么卵用了,因为 {flex:1;} 会自动将div平均分配。
按照下面的套路,每个的p标签的 width:100px;
div>p*6
span>a*6
div{display: flex;max-width: 600px;}
div > p{flex: 1;}
/*任何元素都可以*/
span{display: flex;max-width: 600px;}
span > a{flex: 1;}
二)基本概念
采用flex布局的元素,称为”容器“(父元素flex-contain);
它的所有子元素自动成为容器的成员,称为”flex项目“(子元素flex-item)。
注意:以下这些全给 父级 加的样式
1)定义:flex-direction属性决定主轴的方向(即项目的排列方向)
div{
flex-direction: row; /*水平:默认*/
flex-direction: row-reverse; /*反向水平*/
flex-direction: column; /*垂直*/
flex-direction: column-reverse; /*反向垂直*/
}
2)伸缩流的方向:分为 主轴(x轴main axis)和 交叉轴(y轴cross axis)。
为了更好地去让你明白,我用了同一个的例子: 首先,我用了一个div容器(父级)来包裹着6个p项目(子元素)。。然后div设置主轴为x轴并且正向;
div>p*6
span>a*6
div{display: flex;max-width: 600px;height: 600px;border: 1px solid #000;
flex-direction: row; /*水平:默认*/
flex-direction: row-reverse; /*反向水平*/
}p{height: 100px;width: 100px;}
p:nth-child(1){background: red;}
p:nth-child(2){background: green;}
p:nth-child(3){background: blue;}
p:nth-child(4){background: yellow;}
p:nth-child(5){background: gray;}
p:nth-child(6){background: orange;}
于是,效果图:
注意:主轴方向规定后,在主轴方向上,是不会溢出的。交叉轴方向则会溢出。
1)定义:如果一条轴线排不下,如何换行。
div{ flex-wrap: nowrap; /*默认:不换行*/
flex-wrap: wrap ; /*换行,第一行在上方*/
flex-wrap: wrap-reverse; /*反向换行,第一行在下方*/
}
2)条件:
- 固定容器(父元素);
- 项目(子元素)总宽度的和 > 容器的最大宽度max-width
验证:我在容器div上添加了 {flex-wrap: wrap;} 然后,把项目的宽度 p{width: 200px;} ,之后
效果:
发现如果硬性让项目的宽度 p{width: 200px;} ,然后硬性不换行 {flex-wrap: nowrap;} ,那么项目的宽度就会变为容器的总宽度自动平分后的宽度,在这例子里,也就是100px;
1)定义: flex-decoration和flex-wrap的复合的写法
{flex-flow: row wrap;} /*根据伸缩流方向是否换行*/
1)定义:规定伸缩项目(子元素)在伸缩容器(父元素)主轴(x/y)的对齐方式
div{
justify-content: flex-start; /*默认:左对齐*/justify-content: flex-end; /*右对齐*/
justify-content: center; /*居中*/
justify-content: space-between; /*两端对齐,项目之间的间隔都相等,中间的距离平均分配*/
justify-content: space-around; /*相当于加了左右的margin*/
}
其他的好理解,为了避免混淆主流主轴的方向 {flex-direction: row-reverse;} 关于内容是否反向的问题。。在此验证 {justify-content: flex-end; } ,为了验证方便,我把容器的宽度变为:
div{width: 700px;}
1)定义:规定交叉轴的项目的对齐方式
/*下面假设交叉轴的方向为从上往下*/
div{
align-items: flex-start; /*交叉轴的起点对齐*/ align-items: flex-end; /*交叉轴的终点对齐*/
align-items: center; /*交叉轴的中点对齐*/
align-items: baseline; /*项目的第一行文字的基线对齐 字与字的基线对齐 可以用line-heigh来判断*/
align-items: stretch; /*注意:默认 如果不设置高度或者设为auto 项目将占满容器(父级)的高度*/
}
1)定义:定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
div{
align-content: stretch; /* 默认 和上面的align-item不一样 注意 它和space-between不一样*/
align-content: flex-start;
align-content: flex-end;
align-content: center;
align-content: space-between; /*间隔空间 意思就是上下之间的距离是除他们所占距离外的全部空间 就是他们靠边*/
align-content: space-around;
}
注意:以下这些全给 项目 加的样式
1)定义:定义项目的排列顺序。
p{
order: 0; /*默认值*/
}
注意:
- 默认值为0;
- 支持负值;
- 数值越小越靠前;
- 不支持小数点。
为说明这个属性,我决定简单的说说就好,例子:让他们的排列顺序反向
用笨方法快速理解,其实你懂得:
p{height: 100px;width: 100px;}
p:nth-child(1){background: red;order:5;}
p:nth-child(2){background: green;order:4;}
p:nth-child(3){background: blue;;order:3;}
p:nth-child(4){background: yellow;;order:2;}
p:nth-child(5){background: gray;;order:1;}
p:nth-child(6){background: orange;;order:-1;}
效果图:
1)定义:定义项目的放大比例
p{
flex-grow: 0; /*默认值*/
}
2)注意:
- 默认为0;(如果有剩余的空间,子元素也不会放大)
- 数值越大,放大越厉害;
- 不支持负值;
关于公式:
子元素的增加/放大的宽度 = 父级剩余空间的尺寸 * 元素box-grow占子元素全部和的比
子元素的宽度 = 原有的宽度 + 子元素的增加/放大的宽度
注意:当只有一个子元素 {flex-grow: 1;} ,其他的 {flex-grow: 0;} 的时候,根据公式有1/0=无穷,所以余下的空间都由放大的子元素全占。
1)定义:定义了项目的缩小比例
p{
flex-shrink: 1; /*默认值*/
}
2)注意:
- 默认为1;
- 数值越大,缩小越厉害;数值越小,缩小的越不厉害;
- 不支持负值;
关于公式:
元素收缩的宽度 = 超出的宽度 * 元素flex-shrink占子元素全部和的比
子元素的宽度 = 原有的宽度 - 子元素的收缩的宽度
注意:当只有一个子元素 {flex-grow: 0;}时,其它子元素 {flex-grow: 1;} 的时候,在不断缩小时,根据公式有0/6=0,所以 {flex-grow: 0;} 的子元素的宽度不变 。
1)定义:定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
p{
flex-basis: auto; /* 默认值 auto = 项目的本来大小 */
flex-basis: content; /* 没有width时,默认基于内容自动计算宽度 */
flex-basis: 200px;
}
注意:它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。
关于一丢丢的小发现:为了方便实验,我增大了容器的宽度 div{width: 800px;} (由原来的600px变为800px),而其他全部不变。
当我的项目的宽度 p{width: 100px;} 的时候,我定义了 p1{flex-basis: 300px;} ,当缩小盒子的时候,发现 p1{width: 255px;} , p{width: 75px;} ,所以引发我的好奇心。。
因为 超出的宽度:800px-600px=200px, 每1/8缩小的宽度:200px * 1/8 = 25px;(基于flex-shrink的默认值都为1)
所以。。。。就这样。。。
1)定义:是flex-grow 、flex-shrink 、 flex-basis的复合
基于最后一个值flex-basis值特殊,没有宽度的默认值: {flex-basis: content;} (基于内容自动计算宽度)。
p{
flex: 0 1 auto; /*默认值:只会缩小,不会放大,以内容分配宽度,不分配剩下的空间*/
}
p{
width: 100px;
flex: 0 1 auto; /*默认值:当设定了宽度后,则只会缩小,不会放大,不以内容分配宽度,不分配剩下的空间*/
}
以下值是可以简写复合的:
前提:项目的宽度 = 容器的平均分配后的宽度
p{flex: 1;} /*自动平均分配空间,width没有用了*/p{width: 100px; flex: 0 1 auto;}
p{flex: auto;}
p{flex: 1 1 auto;} /*一起放大,一起缩小,会先让内容撑开,然后在分配剩下的空间*/
/*不放大,不缩小,会溢出,内容撑开宽度,不分配剩下的宽度*/
p{flex: none;}p{flex: 0 0 auto;}
实在没法想象flex:none的效果,所以。。。
1)定义:允许单个项目与其它项目(子元素)不同的排列方式,可覆盖align-items属性。
p{
align-self: auto ; /*默认值,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch*/
align-self: stretch; /*占满容器的高度*/
align-self: flex-start;
align-self: flex-end ;
align-self: center;
align-self: baseline;
}
注意:项目都有可能分别取这6个值,除了auto,其他都与align-items属性完全一致。