圣杯布局与双飞翼布局

作者: XJBT | 来源:发表于2019-05-22 22:28 被阅读2次

    圣杯布局和双飞翼布局的布局要求

    • 三列布局,两边宽度固定,中间宽度自适应
    • 中间栏在浏览器中要优先渲染 (这就对DOM结构有了要求,center的div必须在最上面)
    • 允许任意列的高度最高

    圣杯布局

    CSS布局

    body {
        // min-widthd的计算为 left-div-width * 2 + right-div-width
        // 因为在left-div之中采用了relative定位(也可以使用transform)
        // 200 * 2 + 150
        min-width: 550px;
    }
    
    // 或者也可在container上设置min-width
    
    #container {
        padding-left: 200px;
        padding-right: 150px;
    }
    #container::after {
        content: '';
        display: block;
        visibility: hidden;
        clear: both;
    }
    
    #container .column {
        float: left;
    
    }
    
    #center {
        width: 100%;
        background: yellow;
    }
    
    #left {
        width: 200px;
        margin-left: -100%;
        position: relative;
        left: -200px;
        background: aqua;
    }
    
    #right {
        width: 150px;
        margin-right: -150px;
        background: aqua;
    }
    
    #footer {
        clear: both;
    }
    

    DOM结构

    <body>
        <div id="header"></div>
        <div id="container">
            <div id="center" class="column">center</div>
            <div id="left" class="column">left</div>
            <div id="right" class="column">right</div>
        </div>
        <div id="footer"></div>
    </body>
    

    双飞翼布局

    双飞翼CSS代码

    body {
        // 对于双飞翼布局而言,min-width的计算只需要left-div-width + right-div-width即可
        // 此处为200 + 150
        // 但为了实际效果增加了一定的宽度
        min-width: 500px;
    }
    
    #container {
        width: 100%;
    }
    
    .column {
        float: left;
    }
    
    #center {
        margin-left: 200px;
        margin-right: 150px;
    }
    
    #left {
        width: 200px;
        margin-left: -100%;
    }
    
    #right {
        width: 150px;
        margin-left: -150px;
    }
    
    #footer {
        clear: both;
    }
    

    双飞翼DOM结构

    <body>
        <div id="header"></div>
        <div id="container" class="column">
            <div id="center"></div>
        </div>
        <div id="left" class="column"></div>
        <div id="right" class="column"></div>
        <div id="footer"></div>
    <body>
    

    使用box-sizing可以去掉container

    新的CSS布局

    body {
        min-width: 500px;
    }
    
    .column {
        float: left;
    }
    // 利用padding取代margin
    // 但是存在一个问题就是padding是可能有颜色的,若padding有颜色且两边的不足以盖掉padding的高度时会有缺陷
    #center {
        padding-left: 200px;
        padding-right: 150px;
        box-sizing: border-box;
        width: 100%;
    }
    
    #left {
        width: 200px;
        margin-left: -100%;
    }
    
    #right {
        width: 150px;
        margin-left: -150px;
    }
    
    #footer {
        clear: both;
    }
    

    新的DOM结构

    <body>
        <div id="header"></div>
        <div id="center" class='column'></div>
        <div id="left" class="column"></div>
        <div id="right" class="column"></div>
        <div id="footer"></div>
    <body>
    

    使用flex布局

    flex布局的CSS代码

    #container {
        display: flex;
    }
    
    #center {
        flex: 1;
    }
    
    #left {
        // flex: flex-grow flex-shrink flex-basis
        flex: 0 0 200px;
        // order属性用于改变div的顺序
        order: -1;
    }
    
    #right {
        flex: 0 0 150px;
    }
    

    flex布局的DOM结构

    <div id="container">
        <div id="center"></div>
        <div id="left"></div>
        <div id="right"></div>
    </div>
    

    使用绝对定位来进行布局

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>实现三栏水平布局之绝对定位布局</title>
        <style type="text/css">
        .container{
            position: relative;
        }
        .main,.right,.left{
            top: 0;
            height: 130px;
        }
        .main{
            margin: 0 300px 0 200px;
            background-color: blue;
        }
        .right{
            position: absolute;
            width: 300px;
            right: 0;
            background-color: red;
        }
        .left{
            position: absolute;
            width: 200px;
            background-color: green;
            left: 0;
        }
        </style>
    </head>
    <body>
    // 注意此处会出现问题,因为此处的main区块并没有使用float或是绝对定位,所以在main之前的空格字符会占据一行,此时的三栏顶部是不对齐的,可以将空格去掉或是将父元素的字体大小设为0来解决这个问题。
    <div class="container">
      <div class="main">main</div>
      <div class="left">left</div>
      <div class="right">right</div>
    </div>
    </body>
    </html>
    

    利用BFC原理来实现圣杯布局

    BFC原理中指出,BFC块不与外部float的块有重叠部分,所以可以让左右两栏float,且宽度固定,中间栏是一个BFC,实现中间栏自适应

    总结

    对比双飞翼布局和圣杯布局可以发现,圣杯布局的DOM结构更易理解,但是所需的min-width较大,这是由于左边的div采用了margin-left和relative的结果,导致在计算min-width时需要计算两边左边div的宽度。
    若不考虑兼容性问题,那么使用border-box和flex两者是最简单的

    相关文章

      网友评论

        本文标题:圣杯布局与双飞翼布局

        本文链接:https://www.haomeiwen.com/subject/cbgpzqtx.html