css面试题1:双飞翼布局和圣杯布局

177 阅读1分钟

为什么会有双飞翼布局和圣杯布局

如果一些项目比较老或者需要兼容IE浏览器无法用到新的css属性(比如无法使用flex),那么网页的三拦布局就需要这两种布局方式来实现。

三栏布局是左右两侧固定宽度,中间内容区域宽度自适应,并且要求中间内容区域优先加载,因为内容区域一般是网页的核心,比较重要。

网页效果如下:

image.png

这两者的相同之处:

  • 都是使用float浮动布局,
  • 左右两侧都是使用margin属性来实现和中间的div内容并排实现左、中、右三拦布局

这两者的区别:

两者的区别在于处理中间遮挡区域的方式不同

  • 双飞翼布局:中间div设置了padding-left和padding-right来为左、右侧的显示让出位置,左右侧使用相对定位position:relative,配合left、right属性把左右侧固定到正确的位置
  • 圣杯布局: 直接在中间div里新建了一个子div,并且子div设置了margin-left和margin-right属性来解决中间内容被遮挡的问题

双飞翼布局代码演示:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta name="format-detection" content="telephone=no"/>
        <title>双飞翼布局</title>
        <style>
            /* 中间一栏的宽度其实是100%,但是中间内容区域的宽度不是100%,因为中间内容区域有margin属性*/
            body {
                min-width: 700px;
            }
            header {
                background-color: wheat;
            }
            footer {
                background-color: bisque;
            }
            .float {
                float: left;
            }
            .center {
                width: 100%;
                background-color: #d8d8d8;
            }
            .left {
                width: 100px;
                background-color: red;
                margin-left: -100%;
            }
            .right {
                width: 150px;
                background-color: green;
                margin-left: -150px;
            }
            .center-wrap {
                /*给内部div添加margin,把内容放到中间栏,其实整个背景还是100%*/ 
                margin: 0 150px 0 100px;
            }
        </style>
    </head>
    <body>
        <header>header</header>
        <div class="center float">
            <div class="center-wrap">
                center
            </div>
        </div>
        <div class="left  float">left</div>
        <div class="right  float">right</div>
        <footer>footer</footer>
    </body>
</html>

圣杯布局代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta name="format-detection" content="telephone=no"/>
        <title>圣杯布局</title>
        <style>
            /* 圣杯布局在页面宽度很小的时候,center会被挤下去,页面很丑,所以要定义一个最小宽度 ,圣杯布局下中间一栏的的宽度不是100%*/
            body {
                min-width: 500px;
            }
            header,footer {
                background-color: bisque;
            }
            footer {
                clear: both;
            }
            .float {
                float: left;
            }
            .container {
                /* 摆正中间栏的位置 */
                padding-left: 100px;
                padding-right: 150px;
            }
            .center {
                width: 100%;
                background-color: #d8d8d8;
            }
            .left {
                width: 100px;
                background-color: darkkhaki;
                margin-left: -100%;
                /*摆正中间栏位置后,左侧一栏也相应的向右移动了,所以需要向左边矫正*/
                position: relative;
                left: -100px;
            }
            .right {
                width: 150px;
                background-color:darksalmon ;
                margin-left: -150px;
                position: relative;
                /*摆正中间栏位置后,右侧一栏也相应的向左移动了,所以需要向右边矫正*/
                right: -150px;
            }
        </style>
    </head>
    <body>
        <header>header</header>
        <div class="container">
            <div class="center float">center</div>
            <div class="left float">left</div>
            <div class="right float">right</div>
        </div>
        <footer>footer</footer>
    </body>
</html>

其实在支持flex的浏览器中,也可以用flex布局实现

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta name="format-detection" content="telephone=no"/>
        <title>flex实现三拦布局</title>
        <style>
            * {
                margin: 0;
                padding:0;
            }
            body {
                min-width: 500px;
            }
            header,footer {
                background-color: bisque;
                height: 50px;
                line-height: 50px;
            }
            .container {
                display: flex;
            }
            .left {
                width: 100px;
                background-color: darksalmon;
                order:-1;// 把left排到前面
            }
            .center {
                flex:1;
                background-color: #d8d8d8;
            }
            .right {
                width: 150px;
                background-color: darksalmon;
            } 
        </style>
    </head>
    <body>
        <header>header</header>
        <div class="container">
            <div class="center">center</div>
            <div class="left">left</div>
            <div class="right ">right</div>
        </div>
        <footer>footer</footer>
    </body>
</html>