CSS-圣杯布局+双飞翼布局(传统方法+flex方法)

loading 2023年01月09日 132次浏览

其实两个布局实现的效果是一样的,两边定宽中间自适应,只不过用到的方法略有不同。

1. 双飞翼布局

先看html结构,和圣杯布局不同之处在于自适应元素内部又包了一个div,作用后序在代码中讲解:

    <div id="content">
        <!-- 自适应元素至于顶层,否则其他元素位置错乱,因为margin-left时必须按这个顺序 -->
        <div class="main">
            <div class="wrap">main</div>
        </div>
        <div class="aside">aside</div>
        <div class="extra">extra</div>
    </div>

再来看CSS代码,逐步分析

content设置个边框用于标识,不设置宽和高默认宽填满高为0。然后提前写好清除浮动代码。

    #content {
        border: 1px solid #999;
    }

    #content:after {
        content: '';
        display: block;
        clear: both;
    }

给三块区域都设置浮动,使得后面margin-left的盒子可以根据前一个浮动的盒子来移动,。

    .main,
    .aside,
    .extra {
        float: left;
    }

main区域设置宽度为100%占满一行,同时设置高度撑开content盒子(因为上面清除了浮动),再通过内部的wrap的margin值来撑开左右两边留给aside和extra进来。

    .main{
        width: 100%;
    }
    .wrap{
        background-color: lightskyblue;
        margin-left: 100px;
        margin-right: 100px;
        height: 300px;
    }

aside区域设置宽度要等于wrap之前margin出来的宽度,然后关键还是这个margin-left:-100%,因为这里的margin-left是相对于前一个浮动的盒子也就是main而言的,因此-100%对应的也是main的宽度,如图:

注意图中浅蓝色是wrap的宽度,main是占满整行的所以把aside和extra挤下来了

设置前

设置后

    .aside{
        width: 100px;
        height: 300px;
        background-color: aquamarine;
        margin-left: -100%;
    }

那么接下来要把extra移到右边空白处,此时extra前一个浮动的盒子还是main,那么只要移动自身的宽度就能放进去了,也就是-100px

    .extra{
        width: 100px;
        height: 300px;
        background-color: cornflowerblue;
        margin-left: -100px;
    }

2. 圣杯布局

先看html结构,相较于双飞翼简洁一点。

    <div id="content">
        <!-- 自适应元素至于顶层,否则其他元素位置错乱 -->
        <div class="main">main</div>
        <div class="aside">aside</div>
        <div class="extra">extra</div>
    </div>

再看CSS,首先从content开始就不一样了,这里的content需要通过padding流留出左右两块空白来放aside和extra,而且这里还需要设置min-width避免布局混乱,然后也要清除浮动。

如果不设置min-width,把整个页面的宽度收缩后,会出现布局错乱的效果,因为当页面收缩时,main因为是其父容器content的100%的宽度,所以main也会跟着收缩,当main收缩到比aside宽度还要小,这时候父容器ct的100%宽度<aside的宽度,就不能容纳aside,所以将其挤到了下一行。

    #content {
        border: 1px solid #999;
        padding-left: 100px;
        padding-right: 100px;
        min-width: 200px;
    }

    #content::after {
        content: '';
        display: block;
        clear: both;
    }

然后盒子全部浮动这里是一样的

    .main,
    .aside,
    .extra {
        float: left;
    }

然后先看main盒子,设置高度撑开盒子,然后设置宽度占满一行

    .main {
        background: lightskyblue;
        height: 300px;
        width: 100%;
    }

然后是aside盒子,这里设置margin-left:-100%前是这样的,和上面双飞翼布局有所差异,因为main盒子宽度不一样了:

设置margin后会发现位置不对

设置后

再通过定位的方式左移100px即可

    .aside {
        background: lightgreen;
        width: 100px;
        height: 300px;
        margin-left: -100%;
        position: relative;
        left: -100px;
    }

那么extra也是同理了,就不用再作过多解释

    .extra {
        background: yellow;
        width: 100px;
        height: 300px;
        margin-left: -100px;
        position: relative;
        left: 100px;
    }

3. flex

使用flex实现是最简单方便的,因为flex:1这个属性可以自动撑满剩余部分:

<body>
    <main>
        <div class="left">left</div>
        <div class="middle">middle</div>
        <div class="right">right</div>
    </main>
</body>
<style>
    main{
        display: flex;
        height: 500px;
    }
    .left , .right{
        width: 200px;
        background-color: lightgreen;
    }
    .middle{
        flex: 1;
        background-color: lightblue;
    }
</style>