「面试高频」三栏布局,实现一个两边固定宽度,中间自适应并且先渲染的布局?(圣杯+双飞翼)

179 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

三栏布局的实现

三栏布局:两侧宽度固定,中间宽度自适应的

1、浮动 + margin

<style>
    .container,.left,.right,.center{
        height: 200px;
    }
    .left{
        float: left;
        width: 100px;
        background-color: aqua;
    }
    .right {
        float: right;
        width: 100px;
        background-color: antiquewhite;
    }
    .center{
        margin-left: 100px;
        margin-right: 100px;
        background-color: red;
    }
</style>
</head>

<body>
    <div class="container" >
        <div class="left"></div>
        <div class="right"></div>
        <div class="center"></div>
    </div>
</body>

image-20220405161741056

2、浮动 + BFC

通过左右浮动,中间开启BFC来环绕浮动实现

<style>
    .header,.footer{
        background-color: blueviolet;
        height: 100px;
        line-height: 100px;
        text-align: center;
    }
    .container,.left,.right,.center{
        height: 200px;
    }
    .left{
        float: left;
        width: 100px;
        background-color: aqua;
    }
    .right {
        float: right;
        width: 100px;
        background-color: antiquewhite;
    }
    .center{
        /*使用BFC来消除左右边距*/
        overflow: hidden;
        background-color: red;
    }
</style>

<body>
    <div class="header">header</div>
    <div class="container" >
        <div class="left"></div>
        <div class="right"></div>
        <div class="center"></div>
    </div>
    <div class="footer">footer</div>
</body>

3、flex

左右定宽,中间flex系数1

<style>
    .header,.footer{
        background-color: blueviolet;
        height: 100px;
        line-height: 100px;
        text-align: center;
    }
    .left,.right,.center{
        height: 200px;
    }
    .container{
        display: flex;
    }
    .left{
        width: 100px;
        background-color: aqua;
    }
    .right {
        width: 100px;
        background-color: antiquewhite;
    }
    .center{
        flex: 1;
        background-color: red;
    }
</style>
</head>

<body>
    <div class="header">header</div>
    <div class="container" >
        <div class="left"></div>
        <div class="center"></div>
        <div class="right"></div>
    </div>
    <div class="footer">footer</div>
</body>

image-20220405162121409

4、table

给容器设置table,并且width100%,

给子元素设置table-cell,左右固宽

<style>
    .left,.right,.center{
      height: 200px;
    }
    .container{
      display: table;
      width: 100%;
    }
    .left{
      width: 100px;
      background-color: aqua;
      display: table-cell;
    }
    .right {
      width: 100px;
      background-color: antiquewhite;
      display: table-cell;
    }
    .center{
      background-color: red;
      display: table-cell;
    }
  </style>
</head>

<body>
  <div class="container" >
    <div class="left"></div>
    <div class="center"></div>
    <div class="right"></div>
  </div>
</body>

5、定位

给容器设置相对定位,给左右设置绝对定位并贴边,随后再通过margin清楚两边固定宽

<style>
    .left,.right,.center{
        height: 200px;
    }
    .container{
        position: relative;
    }
    .left{
        width: 100px;
        background-color: aqua;
        position: absolute;
        left: 0;
    }
    .right {
        width: 100px;
        background-color: antiquewhite;
        position: absolute;
        right: 0;
    }
    .center{
        margin: 0 100px;
        background-color: red;
    }
</style>
</head>

<body>
    <div class="container" >
        <div class="left"></div>
        <div class="right"></div>
        <!--注意放最后-->
        <div class="center"></div>
    </div>
</body>

image-20220405163011698

两边固宽度,中间自适应并且先渲染

6、圣杯布局

利用的是浮动元素 margin 负值的应用

将中间要渲染的元素设置为首行

三个元素设置浮动,中间宽度为百分百,左右为固定宽度

给容器设置两个margin为固宽元素

随后给左元素设置margin-left为-100%让它垂直向上移动

给右元素设置margin-left为-100px让它覆盖到右边

随后给左右元素设置相对定位,然后移动到左右两边,

最后给footer设置clear:both;清除浮动的影响

<style>
    .header,.footer{
        background-color: blueviolet;
        height: 100px;
        line-height: 100px;
        text-align: center;
        /*清除浮动影响*/
        clear: both;
    }
    .left,.right,.center{
        height: 200px;
    }
    .container{
        margin: 0 100px;
    }
    .left{
        float: left;
        width: 100px;
        margin-left: -100%;
        position: relative;
        left: -100px;
        background-color: aqua;
    }
    .right {
        float: left;
        width: 100px;
        margin-left: -100px;
        position: relative;
        right: -100px;
        background-color: green;
    }
    .center{
        float: left;
        width: 100%;
        background-color: red;
    }
</style>
</head>

<body>
    <div class="header">header</div>
    <div class="container" >
        <!--中间先渲染-->
        <div class="center"></div>
        <div class="left"></div>
        <div class="right"></div>
    </div>
    <div class="footer">footer</div>
</body>

image-20220405171229254

7、双飞翼布局

与圣杯布局很像,但多了一层div嵌套

<style>
    .header,.footer{
        background-color: blueviolet;
        height: 100px;
        line-height: 100px;
        text-align: center;
        clear: both;
    }
    .left,.right,.center{
        height: 200px;
    }
    .left{
        width: 100px;
        float: left;
        margin-left: -100%;
        background-color: aqua;
    }
    .right {
        width: 100px;
        float: left;
        margin-left: -100px;
        background-color: green;
    }
    /*用一个容器包裹住center然后设置浮动宽度百分百*/
    .content{
        width: 100%;
        float: left;
    }
    /*在中心中设置左右margin就不会影响正常的左右元素*/
    .center{
        margin: 0 100px;
        background-color: red;
    }
</style>

<body>
    <div class="header">header</div>
    <div class="container" >
        <div class="content">
            <div class="center"></div>
        </div>
        <div class="left"></div>
        <div class="right"></div>
    </div>
    <div class="footer">footer</div>
</body>

圣杯布局与双飞翼的区别

双飞翼布局其实和圣杯布局的精髓是一样的,都是通过设置负margin来实现元素的排布,不同的就是html结构,双飞翼是在center元素内部又设置了一层inner-center的元素并设置它的左右margin,而非,圣杯布局的padding,来排除两边元素的覆盖。所以这两种布局原理基本一样,关键就是在于设置负margin的技巧,和元素浮动的相对定位技巧来实现。