CSS布局(IFC/BFC/FFC/GFC)|青训营笔记

196 阅读4分钟

这是我参与「第四届青训营」笔记创作活动的的第4天。

常规流 Normal Flow

在没有用任何CSS样式来改变网页布局,正常情况下网页会排版再一个常规流布局之中。

  • 根元素、浮动和绝对定位的元素会脱离常规流
  • 其它元素都在常规流之内(in-flow)
  • 常规流中的盒子,在某种排版上下文中参与布局

image.png

块级 vs. 行级

块级元素行级元素
生成块级盒子生成行级盒子或内容分散在多个行盒 (line box) 中
body、article、div、main、section、h1-6、p、ul、li 等span、em、strong、cite、code 等
display: blockdisplay: inline
不和其它盒子并列摆放和其它行级盒子一起放在一行或拆开成多行
适用所有的盒模型属性盒模型中的width、height不适用

display 属性

block块级盒子
inline行级盒子
inline-block本身是行级,可以放在行盒中;可以设置宽高;作为一个整体不会被拆散成多行
none排版时完全被忽略

IFC(行级排版上下文)

  • Inline Formatting Context (IFC)
  • 只包含行级盒子的容器会创建一个IFC
  • IFC 内的排版规则
    • 盒子在一行内水平摆放
    • 一行放不下时,换行显示
    • text-align 决定一行内盒子的水平对齐
    • vertical-align 决定一个盒子在行内的垂直对齐
    • 避开浮动(float)元素,float元素会优先排列

例子:多行文本垂直居中 当一个块要在环境中水平居中时,设置其为inline/inline-block则会在外层产生IFC,通过text-align则可以使其水平居中,然后设置父级元素的"行高等于盒子的高",即可使其垂直居中。

<style>
    .text_container {
        text-align: center;
        width: 100%;
        height: 300px;
        background-color: aquamarine;
        line-height: 300px;
    }
    p {
        display: inline-block;
        background-color: antiquewhite;
    }
</style>

<body>
    <div class="text_container">
        <p>
            东风夜放花千树,更吹落,星如雨。宝马雕车香满路。凤箫声动,玉壶光转,一夜鱼龙舞。蛾儿雪柳黄金缕,笑语盈盈暗香去。
            <strong>众里寻他千百度,蓦然回首,那人却在,灯火阑珊处。</strong>
        </p>
    </div>
</body>

image.png 或 给父元素设置display:table-cell;vertical-align: middle;

    .text_container {
        text-align: center;
        width: 100%;
        height: 63px;
        background-color: aquamarine;
        /* line-height: 63px; */
        display: table-cell;
        vertical-align: middle;
    }

image.png

注意:vertical-align属性只对行内元素有效,对块内元素无效!

BFC(块级排版上下文)

  • Block Formatting Context (BFC)
  • 某些容器会创建一个BFC
    • 根元素
    • 浮动、绝对定位、inline-block
    • Flex子项和Grid子项
    • overflow 值不是 visible 的块盒
    • display: flow-root;

BFC 内的排版规则

  • 盒子从上到下摆放
  • 垂直 margin 合并
  • BFC 内盒子的 margin 不会与外面的合并
  • BFC 不会和浮动元素重叠

例子:解决高度塌陷的问题(inline-block可以设置宽高)

<style>
    .box {
        float: left;
        width: 180px;
        height: 180px;
        background: cornflowerblue;
        margin: 60px;
    }
    
    .outer_box {
        display: inline-block;
        background: lightblue;
    }
</style>

<body>
    <div class="outer_box">
        <div class="box">moly</div>
        <div class="box">edwin</div>
    </div>
</body>

父级盒子加display: inline-block;前: image.png 后: image.png

FFC(弹性格式化上下文)

当 display 的值为 flex 或 inline-flex 时,将生成弹性容器(Flex Containers), 一个弹性容器为其内容建立了一个新的弹性格式化上下文环境(FFC)

FFC布局规则

  • 设置为 flex 的容器被渲染为一个块级元素。
  • 设置为 inline-flex 的容器被渲染为一个行内元素。
  • 弹性容器中的每一个子元素都是弹性项目。它可以控制子级盒子的:
    • 摆放的流向 ( → ← ↑ ↓ )
    • 摆放顺序
    • 盒子宽度和高度
    • 水平和垂直方向的对齐
    • 是否允许折行

⚠️注意:FFC布局中,float、clear、vertical-align属性不会生效。 Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。

FFC应用场景

(1)装填子弹

<style>
    .container {
        display: flex;
        border: 2px solid #966;
    }
    
    .a,
    .b,
    .c {
        text-align: center;
        padding: 1em;
    }
    
    .a {
        background: #fcc;
    }
    
    .b {
        background: #cfc;
    }
    
    .c {
        background: #ccf;
    }
</style>

<body>
    <div class="container">
        <div class="a">A</div>
        <div class="b">B</div>
        <div class="c">C</div>
    </div>
</body>

image.png

(2)flex-grow

<style>
    .container {
        display: flex;
    }
    
    .a,
    .b,
    .c {
        width: 100px;
    }
    
    .a {
        background: #fcc;
        flex-grow: 2;
    }
    
    .b {
        background: #cfc;
        flex-grow: 1;
    }
    
    .c {
        background: #ccf;
    }
</style>

<body>
    <div class="container">
        <div class="a">A</div>
        <div class="b">B</div>
        <div class="c">C</div>
    </div>
</body>

image.png

(3)flex-shrink

<style>
    .container {
        display: flex;
    }
    
    .a,
    .b,
    .c {
        width: 400px;
    }
     
    .a {
        flex-shrink: 0;
        background: #fcc;
    }
    
    .b {
        background: #cfc;
    }
    
    .c {
        background: #ccf;
    }
</style>

<body>
    <div class="container">
        <div class="a">A</div>
        <div class="b">B</div>
        <div class="c">C</div>
    </div>
</body>

image.png

其他属性:

  • flex-direction
  • justify-content
  • align-items
  • order
  • Flexibility

flex简写

flex: 1flex-grow: 1
flex: 100pxflex-basis: 100px
flex: 2 1flex-grow: 2; flex-shrink: 1
flex: 1 100pxflex-grow: 1; flex-basis: 100px
flex: 2 0 100pxflex-grow: 2; flex-shrink: 0; flex-basis: 100px
flex: autoflex: 1 1 auto
flex: noneflex: 0 0 auto

GFC(栅格格式化上下文)

GFC布局规则

  • display: griddisplay: inline-grid 使元素生成一个块级的 Grid 容器
  • 使用 grid-template 相关属性将容器划分为网格
  • 设置每一个子项占哪些行/列

image.png

GFC应用场景

例1:划分网格

<style>
    .a {
        background: orchid;
    }
    
    .b {
        background: orange;
    }
    
    .c {
        background: blue;
    }
    
    .d {
        background: lightcoral;
    }
    
    .e {
        background-color: lightgreen;
    }
    
    .box {
        border-radius: 5px;
        margin: 5px;
    }
    
    .wrapper {
        display: grid;
        grid-template-columns: 100px 100px 200px;
        grid-template-rows: 100px 100px;
        height: 300px;
        width: 500px;
        border: black solid 1px;
    }
</style>

<body>
    <div class="wrapper">
        <div class="box a">A</div>
        <div class="box b">B</div>
        <div class="box c">C</div>
        <div class="box d">D</div>
        <div class="box e">E</div>
    </div>
</body>

image.png

grid-template-columns: 30% 30% auto;
grid-template-rows: 100px auto

image.png

grid-template-columns: 100px 1fr 1fr;
grid-template-rows: 100px 1fr

image.png