一个重要的CSS考点---三列布局

引言:总是在一些学长面试贴的CSS考点里看到三列布局,觉得这个东西应该蛮重要,刚好老师最近讲到这,就写一篇随堂贴记录一下,加深印象。同时也做分享,希望能与大家互相探讨。

想要实现三列布局的效果,我们可以使用经典的浮动属性和定位属性达到效果(但二者可能有些缺点),也可以使用圣杯布局和双飞翼布局两种巧解。接下来我将一一讲解这几种布局的实现以及各种的特点。

注:本段为编者写完正文的补充:写完之后丰富了一下封面图,相当于全文的思维导图吧,希望能帮助读者阅读。本文使用导图较多,花费时间较长,可能写的时候思维疲惫。如果有什么地方出错,还望各位指出!拜谢!

QQ图片20210427103604.png

几种实现三列布局的方法

浮动布局(float)

具体实现

这是CSS样式

*{
    margin: 0;
    padding: 0;
}
body{
    min-width: 600px;
    
}
#left,#right{
    width: 200px;
    height: 200px;
    background: red;
}
#middle{
    height: 200px;
    background: green;
}
#left{
    float: left;
}

#right{
    float: right;
}

CSS没啥需要特别讲的,但是需要注意一下HTML

    <div id="left">
        left
    </div>
    <div id="right">
        right
    </div>
    <div id="middle">
        middle
    </div>

注意:这里将middle放在最后,是因为左右设置浮动属性之后,脱离了文档流。如果将middle放在中间,会成这样:

QQ图片20210427105016.png

float布局的缺陷:

通过之前的学习我们知道,float属是用来实现文字环绕图片的。如果有大量的文本出现,布局就会乱,整体页面就会很难看,像这样:

QQ图片20210427111007.png

QQ图片20210427111010.png
我们可以看到:middle未浮动,left和right浮动了;middle被上面的文本挤下去了。

小结

因为float的特性,我们一般不用它

定位布局(position)

具体实现

被我同划分在经典布局下,思路与浮动布局差不多,只不过使用了position属性

具体实现:

  1. 左右两边固定宽度,设置边距,并设置绝对定位;
  2. 中间元素自适应,并且设置margin为左右元素的宽度;
<div id="left">
        left
    </div>
    <div id="middle">
        middle
    </div>
    <div id="right">
        right
    </div>

然后是CSS样式:

*{
    margin: 0;
    padding: 0;
}
body{
    width: 100%;
    height: 500px;

}

#left,#right{
    width: 200px;
    height: 100%;
    background: pink;
}
#left{
    position: absolute;
    left: 0;
    top: 0;
}
#right{
    position: absolute;
    right: 0;
    top: 0;

}
#middle{
    margin: 0px 200px;
}

定位布局的缺点

当因出现滚动条时,内容区在滚动条后边显示,内容区会被压缩,像这样:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OOUhpYHh-1619502783791)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/27aa1aa0349e4f228a858c31b2dec48c~tplv-k3u1fbpfcp-watermark.image)]

小结

由于滚动条的问题,不推荐使用这种方法实现三列布局

圣杯布局

圣杯布局呢,只要我们做到中间内容自适应、中间内容优先渲染、两边固定 就差不多啦。

不过圣杯布局倒是有很多细节的地方需要注意!

具体实现

<div class="wrap">
        <div id="header">
            header
        </div>
        <div id="content">
            <div id="middle">
                <p>middle</p>
                <p>middle</p>
                <p>middle</p>
            </div>
            <div id="left">
                left
            </div>
            <div id="right">
                right
            </div>
        </div>
        <div id="footer">
            footer
        </div>
    </div>

HTML的盒子分布如上。这里就注意middle放在了前面,提前渲染

然后设置外围样式:

*{
    margin: 0;
    padding: 0;
}

.wrap{
    min-width: 600px;
}

#header,#footer{
    height: 50px;
    width: 100%;
    background: grey;
}

接下来设置内部样式:

这里从效果上给大家看看高度坍塌怎么用overflow: hidden;解决的啊

我先设置左中右为向左浮动,效果是这样的:

QQ图片20210427114222.png

可以看到content的下面的元素向上移动了。

然后,我给content(左中右的容器)设置overflow: hidden;

 #middel,#left,#right{
    float: left;
}
#content{
    overflow: hidden;
    padding: 0  200px;
}

现在是这样的:

QQ图片20210427114424.png
给父元素设置了overflow:hidden,解决了高度塌陷并能实现高度自适应的方法(遵循BFC的显示原则) 弊端:只要里面的内容或者元素超出父元素以外,就会被隐藏;

思路被耽搁了一下,继续啊。继续设置左中右的样式

#middel{
    width: 100%;        
    background: green;
}
#left,#right{
    width: 200px;
    height: 200px;
    background: pink;
}

现在就会是这样的:

QQ图片20210427115437.png

然后将左右放到对应位置

#left{
    margin-left: -100%;
    position: relative;
    left: -200px;
}
#right{
    margin-left: -200px;
    position: relative;
    right: -200px;
} 

实现最终效果

QQ图片20210427115639.png

这里用left版块举例细讲一下最终效果怎么来的(注意啊兄弟们,因为position: relative;,margin-left和left都是按照原来的位置移动的):

QQ图片20210427125423.png

再放一份完整的CSS代码

*{
    margin: 0;
    padding: 0;
}

.wrap{
    min-width: 600px;
}

#header,#footer{
    height: 50px;
    width: 100%;
    background: grey;
}
#middel,#left,#right{
    float: left;
}
#content{
    overflow: hidden;/*BFC容器*/
    padding: 0  200px;
}
#middel{
    /* 继承conten宽度的100% */
    width: 100%;        
    background: green;
}
#left,#right{
    width: 200px;
    height: 200px;
    background: pink;
}
#left{
    /* 移到content的最左边 */
    margin-left: -100%;
    /* 相对定位不会脱离文档流 */

    /* left本来不能设置left属性,但是有定位属性后就可以 */
    position: relative;
    left: -200px;
}
#right{
    /* left版块是被挪动了,但是right在HTML里的写法是跟在left的后面,所以会出现在content的右边 */
    margin-left: -200px;
    position: relative;
    right: -200px;
}

注意

圣杯布局下,如果某一列内容过多,文字会溢出。

image.png
用等高布局解决

#middel,#left,#right{
    float: left;
    padding-bottom: 10000px;
    margin-bottom: -10000px;
}

然后就是这样:

QQ图片20210427130519.png

小结

在我看来圣杯布局没啥太大问题,注意内容过多情况就好

双飞翼布局

具体实现

先放HTML:

<body>
    <div class="wrap">
        <div id="header">
            header
        </div>
        <div id="content">
            <div id="middle">
                <div class="middle-inner">
                    middel
                </div>
            </div>
            <div id="left">
                left
            </div>
            <div id="right">
                right
            </div>
        </div>
        <div id="footer">
            footer
        </div>
    </div>

可以看出,双飞翼布局和圣杯布局的大体是差不多的。但是!注意到middle-inner这个容器,待会儿可以看到它的特殊用处。

然后是CSS:

*{
    margin: 0;
    padding: 0;
}
.wrap{
    min-width: 600px;
}
#header,#footer{
    height: 50px;
    width: 100%;
    background: grey;
}
#left,#right{
    width: 200px;
    height: 200px;
    background: green;
}
#middle{
    background: blue;
    width: 100%;
    height: 200px;
    float: left;

}
#content{
    overflow: hidden;
}
#left{
    float: left;
    /* 盖在了middle的身上。在页面的左前端 */
    margin-left: -100%;
}
#right{
    float: left;
    margin-left: -200px;
}
.middle-inner{
    margin: 0 200px;
}

因为方法和圣杯布局差不多,所以就不细分了。

这里我通过双飞翼布局的思想提几点:双飞翼布局据说是玉伯大佬提出来的,就是先放好鸟的身体(middle部分),再将翅膀(left和right部分)放到合适的位置。

然后我用两个图简单说说:

QQ图片20210427131826.png

QQ图片20210427132238.png

然后你们会发现,middle里的内容不见了

QQ图片20210427132329.png
是因为现在middle还是横向铺满的,所以我们最后设置了middle-inner的margin属性,让它“空出”那么多位置。

QQ图片20210427132542.png

这样就成功了!

小结

双飞翼方法我好像没发现啥缺点,兄弟们可以优先考虑这种三列布局(或者说你们知道有啥要考虑的点,可以在评论区告诉我)

总结

写了这么久,我终于将这几种实现三列布局的方法写完了。总的来说:前两种经典布局有各自的缺陷,使用时应千万小心,而后两种相对来说会是优解,优先使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值