三栏布局

Clloz · · 291次浏览 ·

前言

三栏布局是应用最广泛的布局之一,一般是左右两侧固定宽度,中间自适应的方式。下面介绍几种三栏布局的解决方案和细节。

基础HTML结构和样式

不同的方法HTML结构顺序会有不同,但是基本都是左中右三个部分,能够提取的样式主要是背景色,字体,宽高,内边距,盒模型。样式如下:

.wrap {
    height: 250px;
    margin-top: 30px;
    position: relative;
    font-size: 30px;
    color: white;
}
.wrap .left, .wrap .right {
    width: 200px;
    height: 200px;
}
.wrap .left {
    background-color: pink;
}
.wrap .right {
    background-color: lightblue;
}
.wrap .middle {
    background-color: lightgreen;
    padding: 10px;
    box-sizing: border-box;
    height: 100%;
}

float方案

左右侧元素float,中间元素用margin给两侧元素预留空间。需要注意的是HTML结构需要是左右中的顺序,流内元素无法感知浮动元素,但是浮动元素可以感知流内元素,如果中间的流内元素先渲染好了,那么最后的浮动元素将会渲染在下一行,因为该行已经没有空间了。HTML结构如下:

<div class="wrap eg1">
    <div class="left"></div>
    <div class="right"></div>
    <div class="middle">例一:左右元素float,中间元素margin</div>
</div>

样式如下:

/* eg1 */
.eg1 .left {
    float: left;
}
.eg1 .right {
    float: right;
}
.eg1 .middle {
    margin: 0 210px;
}

绝对定位方案

和float类似,最好也采取左右中的结构,如果采取其他结构,注意定位属性top:0要加上。另外由于绝对定位元素完全脱离文档流,需要给父元素加上position: relative,并且限定高度。HTML结构如下:

<div class="wrap eg2">
    <div class="left"></div>
    <div class="right"></div>
    <div class="middle">例二:左右元素绝对定位,中间元素margin</div>
</div>

样式如下:

/* eg2 */
.eg2 .left {
    position: absolute;
    left: 0;
}
.eg2 .right {
    position: absolute;
    right: 0;
    top: 0;
}
.eg2 .middle {
    margin: 0 210px;
}

flex布局

flex布局是最简单也是代码量最少的,兼容性也还不错。唯一的问题就是CSS3的新特性ie6-9不支持。HTML结构如下:

<div class="wrap wrap-flex eg3">
    <div class="left"></div>
    <div class="middle">例三:中间元素flex-grow为1,自动放大</div>
    <div class="right"></div>
</div>

样式如下:

/* eg3 */
.wrap-flex {
    display: flex;
}
.eg3 .middle {
    flex: 1;
    margin: 0 10px;
}

table方案

用表格布局来实现该需求,三个部分相当于三个单元格,display: table-cell。使用表格布局会使得三个部分高度统一,三个部分之间的缝隙需要用属性border-collapse border-spacing来设置,每个单元格的左右都会预留。在浏览器窗口宽度变化的时候,适应性较好,不会出现结构改变的现象。HTML结构如下:

<div class="wrap wrap-table eg4">
    <div class="left"></div>
    <div class="middle">例四:table布局,三栏高度一致,元素之间的缝隙只能通过border-collapse和border-spacing属性设置</div>
    <div class="right"></div>
</div>

样式如下:

/* eg4 */
.wrap-table {
    display: table;
    width: 100%;
    border-collapse: separate; 
    border-spacing: 10px 0px;
}
.eg4 .left, .eg4 .middle, .eg4 .right {
    display: table-cell;
}

inline-block和calc函数

和两栏布局时一样,inline-blockcalc函数也是一种解决方案,设置三个部分的display: inline-block,中间元素的宽度用calc函数计算。同样需要注意inline-block的缝隙问题,设置父元素的font-size: 0,因为三个部分的字体大小以及内边距可能有所不同,所以最好用vertical-align来确保三个元素的顶端对齐。HTML结构如下:

<div class="wrap wrap-inline eg5">
    <div class="left"></div>
    <div class="middle">例五: inline-block+calc函数和负margin</div>
    <div class="right"></div>
</div>

样式如下:

/* eg5 */
.wrap-inline {
    margin-left: -10px;
    font-size: 0;
}
.wrap-inline div {
    display: inline-block;
    margin-left: 10px;
    vertical-align: top;
    font-size: 30px;
}
.wrap-inline .middle {
    width: calc(100% - 430px);
}

圣杯布局

圣杯布局的原理其实就是利用的float元素生成的BFC从左到右依次排列,利用宽度、负margin和定位来解决该问题。对于wrap元素,用padding预留出左右两个元素的空间,middle元素第一个渲染,占满父元素,left和right元素依次排在第二行。left设置margin: -100%则左边界和middle的左边界对齐,再利用position: relative的定位属性left在确定left元素的位置。right元素用同样的原理,设置margin: -(自身宽度),再利用定位属性确定位置。圣杯布局有一个问题就是当middle的宽度小于左边元素的宽度时,就没有足够的空间排列三个元素,left和right会被渲染到下一行。HTML结构如下:

<div class="wrap eg6">
    <div class="middle">例六: 圣杯布局</div>
    <div class="left"></div>
    <div class="right"></div>
</div>

样式如下:

/* eg6 */
.eg6 {
    padding: 0 210px;
}
.eg6 div {
    float: left;
}
.eg6 .middle {
    width: 100%;
}
.eg6 .left {
    margin-left: -100%;
    position: relative;
    left: -210px;
}
.eg6 .right {
    margin-left: -200px;
    position: relative;
    left: 210px;
}

双飞翼布局

双飞翼布局是为了解决圣杯布局中middle宽度过小排列不下结构发生变化的问题。圣杯布局之所以会产生这种问题,本质上是因为我们在父元素上用padding给两边的元素预留空间,导致父元素的content区域变小,如果我们两侧的元素宽度比较大,那么父元素的padding就比较大,留下的空间自然就很小,可能无法排列三个元素了。双飞翼布局不再用padding来改变父元素内容的宽度,而是在middle中嵌套一层div.content,这层divmargin来给左右元素预留空间,这样的话父元素和middle元素都有整个body的宽度,不会发生因为宽度不够而导致的结构改变的问题。同时因为父元素宽度未被限制,left和right元素不再需要用定位属性来修改相对位置。HTML结构如下:

<div class="wrap eg7">
    <div class="middle">
        <div class="content">例七: 双飞翼布局</div>
    </div>
    <div class="left"></div>
    <div class="right"></div>
</div>

样式如下:

/* eg7 */
.eg7 > div {
    float: left;
}
.eg7 .middle {
    width: 100%;
    padding: 0;
    background-color: transparent;
}
.eg7 .middle .content {
    margin: 0 210px;
    background-color: lightgreen;
    height: 100%;
    padding: 10px;
    box-sizing: border-box;
}
.eg7 .left {
    margin-left: -100%;
}
.eg7 .right {
    margin-left: -200px;
}

本文示例代码查看页面

本博客所有内容采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可

转载文章请注明:三栏布局 - https://www.clloz.com/programming/front-end/css/2018/08/30/colum/

分类: CSS

Clloz

人生をやり直す

发表评论

电子邮件地址不会被公开。 必填项已用*标注

我不是机器人*

EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00