CSS3:flex布局详解

475 阅读8分钟

这是我参与新手入门的第2篇文章

flex 属性

flex属性可分为两类,一类写在父元素上,一类写在子元素上

其中作用于父元素身上的属性有:

justify-content:设置子元素在主轴(默认为横轴)方向上的对齐方式 适用于单行

justify-content:默认值为flex-start
可设置的属性有:
flex-start:与主轴起始行对齐
flex-end:与主轴结束位置对齐
center:居中对齐 flex-start=flex-end
space-between:第一个元素与主轴起始行对其,最后一个元素与主轴结束位置对其,中间元素平分剩余空白部分,并且两两空白之间距离相等
space-around:元素均匀分布,并确保两两之间的空白空间相等,同时第一个元素前的空间以及最后一个元素后的空间为其他空白空间的一半。

html代码:

        <p>flex-start</p>
        <div class="box1">
            <div class="content"></div>
            <div class="content"></div>
            <div class="content"></div>
        </div>
        <p>flex-end</p>
        <div class="box2">
            <div class="content"></div>
            <div class="content"></div>
            <div class="content"></div>
        </div>
        <p>center</p>
        <div class="box3">
            <div class="content"></div>
            <div class="content"></div>
            <div class="content"></div>
        </div>
        <p>space-between</p>
        <div class="box4">
            <div class="content"></div>
            <div class="content"></div>
            <div class="content"></div>
        </div>
        <p>space-around</p>
        <div class="box5">
            <div class="content"></div>
            <div class="content"></div>
            <div class="content"></div>
        </div>

css代码:

    .box1,.box2,.box3,.box4,.box5{
    width:100px;
    height: 100px;
    border: 1px solid red;
    box-sizing: border-box;
    display: flex;
    align-self: center;
}
.content{
    width: 20px;
    height: 20px;
    box-sizing: border-box;
    border: 1px solid green;
}
.box1{
    justify-content: flex-start;
}
.box2{
    justify-content: flex-end;
}
.box3{
    justify-content: center;
}
.box4{
    justify-content: space-between;
}
.box5{
    justify-content: space-around;
}

运行结果: justify-content

align-items:设置子元素在交叉轴上(垂直于主轴) 的对其方式

align-itmes:默认值为stretch
可设置属性有:
stretch
baseline
flex-start:子元素的交叉轴起始位置的边界紧靠住该行的交叉轴起始边界
flex-end:子元素的交叉轴结束位置的边界紧靠住该行的交叉轴结束边界
center:子元素在该行的交叉轴上居中放置

css代码:

.box1,.box2,.box3,.box4,.box5{
    width:100px;
    height: 100px;
    border: 1px solid red;
    box-sizing: border-box;
    display: flex;
    align-self: center;
}
.content{
    width: 20px;
    height: 20px;
    box-sizing: border-box;
    border: 1px solid green;
}
.box1{
    align-items: stretch;
}
.box2{
   align-items: flex-start;
}
.box3{
    align-items: flex-end;
}
.box4{
    align-items: baseline;
}
.box5{
   align-items: center;
}

运行结果: align-items

flex-wrap:设置子元素为单行展示还是多行展示

flex-wrap:默认为nowrap
可设置属性有:
nowrap:不允许换行
wrap:允许换行,当子元素内容超出父容器的大小时
wrap-reverse:将wrap内容反转

html代码:

        <p>nowrap</p>
        <div class="box1">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>wrap</p>
        <div class="box2">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>wrap-reverse</p>
        <div class="box3">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>

css代码:

.box1,.box2,.box3{
    width:100px;
    height: 100px;
    border: 1px solid red;
    box-sizing: border-box;
    display: flex;
    align-self: center;
}
.content{
    width: 50px;
    height: 20px;
    box-sizing: border-box;
    border: 1px solid green;
}
.box1{
    flex-wrap: nowrap;
}
.box2{
    flex-wrap: wrap;
}
.box3{
    flex-wrap: wrap-reverse;
}

运行结果: flex-wrap

align-content:设置子元素在主轴(默认为横轴)方向上的对齐方式 适用于多行

align-content:默认值为stretch
与justify-content相似,不同之处在于align-content作用于多行元素
可设置的属性有:
flex-start,flex-end,center,space-between,space-around,stretch

html代码:

        <p>stretch</p>
        <div class="box1">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>flex-start</p>
        <div class="box2">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>flex-end</p>
        <div class="box3">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>center</p>
        <div class="box4">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>space-between</p>
        <div class="box5">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>space-around</p>
        <div class="box5">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>

css代码:

box1,.box2,.box3,.box4,.box5,.box6{
    width:100px;
    height: 100px;
    border: 1px solid red;
    box-sizing: border-box;
    display: flex;
    align-self: center;
    flex-wrap: wrap;
}
.content{
    width: 50px;
    height: 20px;
    box-sizing: border-box;
    border: 1px solid green;
}
.box1{
   align-content: stretch;
}
.box2{
    align-content: flex-start;
}
.box3{
    align-content: flex-end;
}
.box4{
    align-content: center;
}
.box5{
   align-content: space-between;
}
.box6{
    align-content: space-around;
}

运行结果: align-content

flex-direction:设置主轴方向

flex-direction:默认值为row
可设置的属性:
row:横向从左到右排列(左对齐)
row-reverse:于row相反
column:纵向从上往下排列(顶对齐)
column-reverse:于column相反

html代码:

        <p>row</p>
        <div class="box1">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>row-reverse</p>
        <div class="box2">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>column</p>
        <div class="box3">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>
        <p>column-reverse</p>
        <div class="box4">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>

css代码:

.box1,.box2,.box3,.box4{
    width:100px;
    height: 100px;
    border: 1px solid red;
    box-sizing: border-box;
    display: flex;
    align-self: center;
}
.content{
    width: 50px;
    height: 20px;
    box-sizing: border-box;
    border: 1px solid green;
}
.box1{
   flex-direction: row;
}
.box2{
    flex-direction: row-reverse;
}
.box3{
    flex-direction: column;
}
.box4{
    flex-direction: column-reverse;
}

运行结果: flex-direction

作用于子元素的属性:

order:填写数字,数值越小,就优先展示在前面,可以为负数

order: 填写数字,数值越小,就优先展示在前面,可以为负数,默认值为0

html代码:

    <div class="wrapper">
        <div class="content">1</div>
        <div class="content">2</div>
        <div class="content">3</div>
    </div>

css代码:

.wrapper{
   width:600px;
   height: 400px;
   border: 1px solid red;
   box-sizing: border-box;
   display: flex;
}
.content{
   width: 200px;
   height: 200px;
   box-sizing: border-box;
   border: 1px solid green;
}
.content:nth-of-type(1){
   order: 5;
}
.content:nth-of-type(2){
   order: 0;
}
.content:nth-of-type(3){
   order: -5;;
}

运行结果: order

align-self:设置子元素在交叉轴上的对其方式

align-self:默认值为auto
可设置属性有:
auto | flex-start | flex-end | center | baseline | stretch

css代码:

.box1,.box2,.box3,.box4,.box5,.box6{
    width:100px;
    height: 100px;
    border: 1px solid red;
    box-sizing: border-box;
    display: flex;
    align-self: center;
}
.content{
    width: 20px;
    height: 20px;
    box-sizing: border-box;
    border: 1px solid green;
}
.box1 .content{
   align-self: auto;
}
.box2 .content{
   align-self: flex-start;
}
.box3 .content{
    align-self: flex-end;
}
.box4 .content{
    align-self: center;
}
.box5 .content{
   align-self: baseline;
}
.box6 .content{
    align-self: stretch;
}

运行结果: align-self

flex-basis:相当于width,定义了子元素的宽度

flex-basis:默认值为auto
可设置具体数值与百分比定义元素的宽度
如果所有子元素的基准值之和大于剩余空间,则会根据每项设置的基准值,按比率伸缩剩余空间

html代码:

        <div class="box1">
            <div class="content">1</div>
            <div class="content">2</div>
            <div class="content">3</div>
        </div>

css代码:

.box1{
    width:400px;
    height: 100px;
    border: 1px solid red;
    box-sizing: border-box;
    display: flex;
    align-self: center;
}
.content{
    height: 50px;
    box-sizing: border-box;
    border: 1px solid green;
}
.box1 .content:nth-of-type(1){
    flex-basis: 20%;
}
.box1 .content:nth-of-type(2){
    flex-basis:50%
}
.box1 .content:nth-of-type(3){
    flex-basis: 200px;
}

运行结果:

flex-basis

当设置了width,同时设置了basis且小于width,那么真实的宽在basis < realWIdth < width
在不设置width的时候,设置basis,元素真实的宽为min-width,当不换行内容撑开超过内容区时,会撑开容器
无论什么情况下,被不换行撑开的容器,不会被压缩计算

flex-grow:设置扩张因子,当父容器有剩余空间时,按照设置的扩张因子进行扩张

flex-grow:默认值为1
用数值来定义扩展比率。不允许负值
根据子元素所设置的扩展因子作为比率来分配剩余空间
剩余宽度=父容器的内容区(content区)减去子元素所占的宽度
计算公式:自身元素宽度+剩余宽度/总扩展因子*自身所占扩展因子

例如:

.box1{
    width:400px;
    height: 100px;
    background-color: aqua;
    display: flex;
    align-self: center;
    border: 1px solid red;
    box-sizing: border-box;
}
.content{
    width: 50px;
    height: 50px;
    box-sizing: border-box;
    border: 1px solid green;
}
.box1 .content:nth-of-type(1){
    flex-grow: 0;
    background-color: black;
}
.box1 .content:nth-of-type(2){
   flex-grow: 2;
   background-color: red;
}
.box1 .content:nth-of-type(3){
    flex-grow: 3;
    background-color: green;
}
根据公式,我们可以得出
剩余空间=398-50*3=248px
因为设置了1px的border,所以父容器的内容区为400-1*2=398px,子元素的内容区为50-1*2=48px
我们将剩余空间分成了5份,0:2:3
所以第一个所占宽度为:50+248/5*0=50px
第二个元素所占宽度为:50+248/5*2=149.2px
第三个元素所占宽度为:50+248/5*3=198.8px

运行结果:

flex-grow

当没有设置border时 css代码:

.box1{
    width:400px;
    height: 100px;
    background-color: aqua;
    display: flex;
    align-self: center;
  
}
.content{
    width: 50px;
    height: 50px;

}
.box1 .content:nth-of-type(1){
    flex-grow: 0;
    background-color: black;
}
.box1 .content:nth-of-type(2){
   flex-grow: 2;
   background-color: red;
}
.box1 .content:nth-of-type(3){
    flex-grow: 3;
    background-color: green;
}
根据公式,剩余空间=400-150*3=250px
第一个元素所占宽度为:50+250/5*0=50px
第二个元素所占宽度为:50+250/5*2=150px
第三个元素所占宽度为:50+250/5*3=200px

运行结果为:

flex-grow22

flex-shrink:设置收缩因子,当子元素的内容区宽度或高度超过父容器定义的宽度或高度时,根据收缩因子进行压缩

flex-shink:默认值为1
用数值来定义收缩比率。不允许负值
根据子元素所设置的收缩因子作为比率来收缩空间
计算公式:元素所占宽度=元素自身内容区-元素自身内容区*压缩因子/加权值 * 溢出量
加权值=元素1自身内容区*元素1所占收缩因子+元素2自身内容区*元素所占收缩因子+···+元素n自身内容区*元素n所占收缩因子

例如:

   .box1{
   width:400px;
   height: 100px;
   background-color: aqua;
   display: flex;
   align-self: center;
  
 
}
.content{
   width: 200px;
   height: 50px;
   

}
.box1 .content:nth-of-type(1){
  flex-shrink: 1;
   background-color: black;
}
.box1 .content:nth-of-type(2){
  flex-shrink: 3;
  background-color: red;
}
.box1 .content:nth-of-type(3){
   flex-shrink: 4;
   background-color: green;
}
根据公式,可以得出:
溢出量=200*3-400=200px
加权值=200*1+200*3+200*4=1600px
第一个元素被压缩后大小为:200-200*1/1600*200=200-25=175px
同理第二个为:200-200*3/1600*200=200-75=125px
第三个为:200-200*4/1600*200=200-100=100px;

运行结果: flex-shrink