float及postion缺点
对于两个div元素,其是相对独立的,如果在其中一个div元素中加入内容,将会使得两个元素的底部不能对齐,导致页面多出空白区域。
多栏布局
css3中加入了多栏布局,可以将一个元素中的内容分为两栏或者多栏显示,并且确保各栏中内容的底部对齐。
<style>
#div1 {
width: 500px;
column-count: 2;
-moz-column-count: 2;
-webkit-column-count: 2;
/* 给每栏设置宽度,但需要外部元素包裹*/
/*column-width: 200px;*/
/*-moz-column-width: 200px;*/
/*-webkit-column-width: 200px;*/
/*栏间距*/
column-gap: 10px;
-moz-column-gap: 1-px;
-webkit-column-gap: 10px;
/*间距线*/
column-rule: 3px solid red;
-moz-column-rule: 3px solid red;
-webkit-column-rule: 3px solid red;
}
#div3 {
width: 100%;
height: 200px;
background-color: #333;
}
</style>
<div id="div1">
<p>341343124312423143124231</p>
<p>341343124312423143124231</p>
<p>afewfew</p>
</div>
<div id="div3"></div>
使用多栏布局时,需要将元素的宽度设置为多栏的总宽度,使用float属性和position属性可以分别设置 。当然也可通过column-width
设置每一栏的宽度而不设置总宽度,此时需要元素外面单独设立一个容器元素,然后指定该容器的宽度。
盒布局
<style>
#container {
display: -moz-box;
display: -webkit-box;
}
#left, #right {
width: 200px;
background-color: yellow;
}
#content {
width: 1000px;
background-color: blue;
}
</style>
<div id="container">
<div id="left">
<p>1</p>
<p>2</p>
</div>
<div id="content">
<p>1</p>
</div>
<div id="right">
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
</div>
</div>
盒布局可以解决float导致底部不对齐的问题;同时可以很好的规避多栏布局宽度必须相等的问题以及解决多栏布局不能指定什么栏中显示什么内容的窘境。
Flex容器
使用Flex布局,元素的宽度和高度具有自适应性,即元素的宽度和高度可以根据排列方向的改变而改变。
不设置高度,自动撑开
曲线图和表格在同一行,给图表设置最小高度
:style={‘min-height‘: 300px}
,给表格设置最大高度:max-height="500"
,可以完美解决对齐问题!
问题:图片下面会有空白存在,这是由于vertical-align: baseline;
导致的。
<style>
.test {
background: red;
}
img {
width: 50px;
height: 50px;
}
span {
background: white;
}
</style>
<div class="test">
<img src="https://sfault-avatar.b0.upaiyun.com/344/542/3445428434-5631776c183b2_huge256" alt="">
<span>Xx</span>
</div>
上述问题,我们只需要将img的垂直对齐改为vertical-align: text-bottom
即可实现。
需要注意的是:当时设置 flex 布局之后,子元素的 float、clear、vertical-align 的属性将会失效。所以也不会出现上述问题!
.container {
display: flex | inline-flex; //可以有两种取值
}
容器的属性
改变元素排列方向
flex-direction:决定主轴的方向(即项目的排列方向)
- row(默认值):横向排列(主轴为水平方向,起点在左端)
- row-reverse:横向反向排列(主轴为水平方向,起点在右端)
- column:纵向排列,(主轴为垂直方向,起点在上沿)
- column-reverse:纵向反向排列(主轴为垂直方向,起点在下沿)
容器是否换行
flex-wrap:决定容器内项目是否可换行
- nowrap(默认值):不换行
- wrap:换行,第一行在上方
- wrap-reverse:换行,第一行在下方
flex-flow:flex-direction 和 flex-wrap 的简写形式,默认值为
row nowrap
对齐方式
术语 | 解释 |
---|---|
main axis(主轴) | 基准轴。横向布局时为水平轴;纵向布局时为垂直轴 |
main-start/main-end | 布局起点与布局终点。横向布局时为左端与右端;纵向布局时为顶端与底端 |
cross axis | 垂直交叉轴。横向布局时为垂直轴;纵向布局时为水平轴 |
cross-start/cross-end | 垂直交叉轴起点与终点。横向布局时为顶端与底端;纵向布局时为左端与右端 |
justify-content:定义了项目在主轴的对齐方式
- flex-start(默认值):左对齐,从main-start开始布局所有子元素
- flex-end:右对齐,从main-end开始布局所有子元素
- center: 居中
- space-between:将第一个子元素布局在main-start处,将最后一个元素布局在main-end处,将空白部分平均分配在所有子元素与子元素之间。
- space-around:每个项目两侧的间隔相等;所以,项目之间的间隔比项目与边框的间隔大一倍
align-items:定义了项目在交叉轴上的对齐方式
- flex-start:交叉轴的起点对齐
- flex-end:交叉轴的终点对齐
- center:交叉轴的中点对齐
- baseline: 如果子元素的布局方向与容器的布局方向不一致,则该值得作用等效于flex-start属性值的作用。如果子元素的布局方向与容器的布局方向一致,则所有子元素中的内容沿基线对齐。
注意:基线(base line)并不是汉字文字的下端沿,而是英文字母“x”的下端沿。 - stretch(默认值):同一行中的所有子元素高度被调整为最大。如果项目未设置高度或设为auto,将占满整个容器的高度
align-content:定义了多根轴线的对齐方式,如果项目只有一根轴线,那么该属性将不起作用
项目属性
改变排序顺序
order:定义项目在容器中的排列顺序,数值越小,排列越靠前,默认值为0,在不改变DOM结构的基础上实现重新排版!
<div id="container">
<div class="block">1</div>
<div class="block">2</div>
<div class="block">3</div>
<div class="block">4</div>
<div class="block">5</div>
<div class="block">6</div>
<div class="block">7</div>
<div class="block">8</div>
<div class="block">9</div>
</div>
<div id="container-copy">
<div class="block" style="order: 1">1</div>
<div class="block" style="order: 4">2</div>
<div class="block" style="order: 7">3</div>
<div class="block" style="order: 2">4</div>
<div class="block" style="order: 5">5</div>
<div class="block" style="order: 8">6</div>
<div class="block" style="order: 3">7</div>
<div class="block" style="order: 6">8</div>
<div class="block" style="order: 9">9</div>
</div>
定义项目缩放
-
flex-grow:定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大
<div id="container"> <div class="a">a</div> <div class="b">b</div> <div class="c">c</div> </div>
其中,container为flex布局,宽度1000px;a、b、c宽度都为100px;
此时设置flex-grow属性如下:.a, .c { flex-grow: 1; } .b { flex-grow: 3; }
剩余空间被均分5份:
(1000-3*100)/(1+3+1)=140
。a和c的宽度为:240,b的宽度为:520。注意:如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
-
flex-shrink:定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小
flex-shrink同flex-grow属性,当子元素宽度(或高度)大于父容器元素的宽度(或高度)时,将溢出的宽度(或高度)均分;按照flex-shrink值的占比情况进行缩放。需要注意的是,缩放不能缩小为0。
其中,container为flex布局,宽度1000px;a、b、c宽度都为1000px;.a, .c { flex-shrink: 1; } .b { flex-shrink: 3; }
溢出空间被均分5份:
(3*1000-1000)/(1+3+1)=400
。计算获得a和c的宽度为:600,b的宽度为:-200。实际宽度如下图:注意:如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
占据空间
-
flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间
注意:将它设为跟width或height属性一样的值,则项目将占据固定空间。flex:是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto;后两个属性可选
注意:该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。 align-self:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。不设置高度(或宽度),自动撑开的原因!!!
Flex示例
示例:一个页面上两个div左右铺满整个浏览器,要保证左边的div一直为500px,右边的div跟随浏览器大小变化(比如浏览器为1000,右边div为500,浏览器为2000,右边div为1500)
<div class="box">
<div class="left"></div>
<div class="right"></div>
</div>
.box {
display: flex;
flex-direction: row;
align-items: center;
height: 500px;
width: 1000px;
}
.left {
flex-basis: 500px;
height: 100%;
width: 500px;
background-color: red;
}
.right {
flex-grow: 1;
height: 100%;
background-color: blue;
}
calc()
calc()方法可以自动计算元素的宽度、高度等数值类型的样式属性值。
#container {
width: 1000px;
height: 50px;
background-color: #e4b9c0;
}
#content {
width: calc(50% - 100px);
height: 50px;
background-color: #00B7FF;
}
将子元素content的宽度设置为父元素container元素宽度的50%-100px。
注意: calc可以对各种不同的计数单位进行混合运算。