css 实现三列布局(圣杯,双飞翼)

221 阅读4分钟

已知

<!DOCTYPE html>
<html>
<head>
    <title>三列布局</title>
    <style>
        body{
            margin: 0;
            padding: 0;
        }
        .outer{  
           
        }
        .inner{
            height: 300px;
        }
        .left{
            width: 100px;
            background-color: yellowgreen; 
        }
        .center{ 
            background-color: gainsboro; 
        }
        .right{
            width: 100px;
            background-color: burlywood; 
        }
    </style>
</head>
<body>
    <div class="outer">
        <div class="inner left"></div>
        <div class="inner center"></div>
        <div class="inner right"></div>
    </div>
</body>
</html>

实现 左右left和right固定,中间自适应。 image.png

1.使用flexbox

.outer{  
    display: flex;
}
.inner{
    height: 300px;
}
.left{
    width: 100px;
    background-color: yellowgreen; 
}
.center{ 
    flex: 1; /*通过设置flex:1 分配剩余空间*/
    background-color: gainsboro; 
}
.right{
    width: 100px;
    background-color: burlywood; 
}

2.绝对布局 左右absolute + 中间margin: 0 100px

.left{
    width: 100px;
    background-color: yellowgreen;
    position:absolute;
    top: 0;
    left: 0;
}
.center{   
    background-color: gainsboro;
    margin:0 100px;
}
.right{
    width: 100px;
    background-color: burlywood; 
    position:absolute;
    top: 0;
    right: 0;
}

3. 绝对布局absolute ,中间也使用absolute

.left{
    width: 100px;
    background-color: yellowgreen;
    position:absolute;
    top: 0;
    left: 0;
}
.center{   
    background-color: gainsboro;
    position:absolute;
    top: 0;
    left: 100px;
    right: 100px;
}
.right{
    width: 100px;
    background-color: burlywood; 
    position:absolute;
    top: 0;
    right: 0;
}

同理fixed也是可以实现。

缺点:中间会出现单独的滚动条 image.png

4. 浮动float:left+right

需要改变dom结构 把center放在right后边,如果在前面right会换行在center下面显示。

    <style> 
        .outer{ 
            
        }
        .inner{
            height: 300px;   
        }
        .left{
            background-color: yellowgreen; 
            width: 100px;  
            float: left;
        }
        .center{
            background-color: gainsboro;
            margin:0 100px;
        }
        .right{
            background-color: burlywood; 
            float: right;
            width: 100px; 
        }
    </style>
</head>
<body> 
    <div class="outer"> 
        <div class="inner left"></div>
        <div class="inner right"></div>
        <div class="inner center"></div>
    </div>
</body> 

缺点:由于float是为了实现文字环绕效果,所以需要会出现outer内容寄出center内容的情况

image.png

5. 浮动float:left + 计算宽度: calc(100%-两边宽度)

三个box都float:left ,中间宽度使用 calc(100%-两边宽度)

.outer{
}
.inner{
    height: 300px;   
    float: left;
}
.left{
    background-color: yellowgreen; 
    width: 100px;  
}
.center{
    background-color: gainsboro; 
    width: calc(100% - 200px);
}
.right{
    background-color: burlywood;  
    width: 100px; 
}

6. display: table

 .outer{ 
    width: 100%;
    display: table;
}
.inner{
    display: table-cell; 
    height: 300px;   
}
.left{
    background-color: yellowgreen; 
    width: 100px;
}
.center{
    background-color: gainsboro; 
}
.right{
    background-color: burlywood; 
    width: 100px;
}

7.圣杯布局

圣杯(Holy Grail)布局:来自由 Matthew Levine 在 2006 年写的一篇文章 《In Search of the Holy Grail》。 
在西方,圣杯是表达“渴求之物”的意思,表达页面渲染的渴望。 

image.png

image.png

看起来就像一个工子,跟圣杯有那么一点点像。

定义

左右两边固定,中间内容自适应,同时中间内容优先渲染显示。

布局要求

  • header和footer各自占领屏幕所有宽度,高度固定。
  • 中间的content是一个三列布局。
  • 三列布局两侧宽度固定不变,中间部分自动填充整个区域。
  • 中间部分的高度是三列中最高的区域的高度。

这里忽略上下header和footer的布局,只关注中间content的实现。

概念

  1. margin-left负百分之百:当margin为负数时候,会反向移动到上一层的位置,当margin-left: -100%;则代表上移一行

实现

由于浏览器是流式加载,所以center要放在left和right标签前。

    <div class="outer">  
        <div class="inner center"></div><!--这里把center移到前面优先渲染 -->
        <div class="inner left"></div>
        <div class="inner right"></div>
    </div> 

样式实现

 .outer{ 
    padding: 0 100px 0 100px; /*压缩左右两边的距离给 left right预留空间 */
    overflow: hidden; /*格式化上下文*/
    min-width: 600px;
}
.inner{
    height: 300px; 
    float: left;
    position: relative;   /*默认static,需要设置relative, 子元素才能用 left right 重新定位 */
    word-break: break-all;
}
.left{
    background-color: yellowgreen;
    margin-left: -100%;  /* 由于父容器格式化上下文,这里默认是换行显示,通过负margin 实现上移一行 */
    left: -100px; /*由于父容器设置了 padding-left,所以需要反向减去-100px显示,这里的left 不受float 影响,left是根据postion:relative 做对应的父容器的偏移 */
    width: 100px;
}
.center{
    background-color: gainsboro; 
    width: 100%;
}
.right{
    background-color: burlywood;
    margin-left: -100px; /* 由于父容器格式化上下文,这里默认是换行显示,通过负margin 自己的宽度, 实现上移到上一行的最后一个位置 */
    right: -100px;/*由于父容器设置了 padding-right,所以需要反向减去-100px显示 */
    width: 100px;
}

8.双飞翼布局

双飞翼是在圣杯布局的基础上做优化,通过在center 新增的content内容去控制左右两边的布局。

image.png 需要修改dom结构,在center里面新增content内容区域。

    <div class="outer">  
        <div class="inner center">
            <div class="content"></div>
        </div>
        <div class="inner left"></div>
        <div class="inner right"></div>
    </div> 

样式部分

body{
    margin: 0;
    padding: 0;
}
.outer{  
    overflow: hidden; /*格式化上下文*/ 
}
.inner{
    float: left; /*设置浮动*/ 
    height: 300px; 
    word-break: break-all;
}
.left{
    background-color: yellowgreen;
    margin-left: -100%;
    width: 100px;
}
.center{
    background-color: gainsboro;
    width: 100%;
    height: 100%;
}
.right{
    background-color: burlywood;
    margin-left: -100px;
    width: 100px;
}
/* 新增内容区域 */
.content {
    margin: 0 100px 0 100px;
    height: 300px;
    word-break: break-all;
}