CSS常见布局的几种实现方式(面试常考)

213 阅读4分钟

布局在前端开发中必不可少,本文将介绍面试中常考的一些CSS布局:

  • 两栏布局(左边固定右边自适应)
  • 三栏布局(左右固定中间自适应)
    • 流体布局(浮动)
    • BFC三栏布局
    • 双飞翼布局
    • 圣杯布局
    • flex
    • table布局
    • 绝对定位布局
    • 网格布局(Grid布局)

一、两栏布局

左边固定,右边自适应

image.png

1.通过设置浮动实现。

需要两个div实现,一个div设置浮动,并设置宽度,另一个div可以不用设置任何东西

如果要给右边块设置什么的话下面两种方法也行:

  • left左浮动并设置宽度right设置margin-left为left的宽度也能实现
  • left设置左浮动并和宽度right,right设置over-flow:hidden也能实现
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>两栏布局——float</title>
    <style>
            div{
                    height:300px;
            }
            .left{
                    width:200px;
                    background-color:gray;
                    float:left;
            }
            .main{
                    background-color:pink;
                    /* margin-left:200px; */
                    /* 或者overflow:hidden; */
            }
    </style>
</head>
<body>
    <div class = 'left'></div>
    <div class = 'main'></div>
</body>
</html>

2. 通过相对定位和绝对定位实现。

需要三个div,其中一个div是父容器,包含两个子元素。
两个子元素设置相对定位,给上边的子元素设置宽度,下边的子元素设置left,值为上边子元素的宽度,再设置right:0。
给父容器设置相对定位是因为可以让其设置绝对定位的子元素相对它进行移动;给上边的子元素设置绝对定位可以让下边的子元素跟它在同一行。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>两栏布局——absolue</title>
    <style>
            .outer{
                    position:relative;
                    height:300px;
            }
            .left{
                    position:absolute;
                    width:300px;
                    background-color:blue;
                    height:100%;
            }
            .main{
                    background-color:yellow;
                    position:absolute;
                    left:300px;
                    right:0;
                    height:100%;

            }
    </style>
</head>
<body>
    <div class = 'outer'>
            <div class = 'left'></div>
            <div class = 'main'></div>
    <div>
</body>
</html>

3.通过弹性盒子flex实现

需要三个div,其中一个div是父容器,包含两个子元素。
父元素设置display:flex;上边子元素设置宽度,下边子元素设置flex:1

    div{
        height:300px;
    }
    .parent{
        display:flex;
    }
    .left{
        flex:0 0 100px;
    }
    .right{
        flex:1 1 auto;
    }

二、三栏布局

左右固定,中间自适应

image.png

1.流体布局(浮动)

原理: 左右模块各自向左右浮动,并设置中间模块的margin值使中间模块宽度自适应

缺点: 主要内容无法最先加载,当页面内容较多时会影响用户体验

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三栏布局——float</title>
    <style>
        div {
            height: 200px;
        }

        .left {
            float: left;
            width: 100px;
        }

        .right {
            float: right;
            width: 100px;
        }

        .center {
            margin-left: 100px;
            margin-right: 100px;
        }
    </style>
</head>

<body>
    <div class="left" style="background-color:rgb(6, 235, 44)"></div>
    <div class="right" style="background-color:rgb(9, 134, 236)"></div>
    <div class="center" style="background-color:red"></div>
</body>

</html>

2.BFC 三栏布局

原理: BFC规则有这样的描述:BFC 区域不会与浮动元素重叠, 因此我们可以利用这一点来实现 3 列布局

缺点: 主要内容模块无法最先加载,当页面中内容较多时会影响用户体验。因此为了解决这个问题,有了下面要介绍的布局方案双飞翼布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三栏布局——BFC</title>
    <style>
        div {
            height: 200px;
        }

        .left {
            float: left;
            width: 100px;
        }

        .right {
            float: right;
            width: 100px;
        }

        .center {
            overflow: hidden;
        }
    </style>
</head>

<body>
    <div class="left" style="background-color:rgb(6, 235, 44)"></div>
    <div class="right" style="background-color:rgb(9, 134, 236)"></div>
    <div class="center" style="background-color:red"></div>
</body>

</html>

3.双飞翼布局

原理:给center添加一个容器元素container,设置center的margin值避开侧边栏,让left、right飘在两边

优点: 主要内容模块可以优先加载,当页面中内容较多时不会影响用户体验。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>三栏布局——双飞翼</title>
    <style>
        .container {
            float: left;
            width: 100%;
        }

        .center {
            margin-left: 100px;
            margin-right: 100px;
            height: 100px;
        }

        .right {
            float: left;
            margin-left: -100px;
            /*自身宽度*/
            width: 100px;
            height: 100px;
        }

        .left {
            float: left;
            margin-left: -100%;
            /*基于父元素百分比的外边距*/
            width: 100px;
            height: 100px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="center" style="background-color:red"></div>
    </div>
    <div class="left" style="background-color:rgb(6, 235, 44)"></div>
    <div class="right" style="background-color:rgb(9, 134, 236)"></div>
</body>

</html>

4.圣杯布局

和与双飞翼布局的区别: 与双飞翼布局很像,有一些细节上的区别,相对于双飞翼布局来说,HTML 结构相对简单,但是样式定义就稍微复杂,也是优先加载内容主体。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>三栏布局——双飞翼</title>
    <style>
        .container {
            margin-left: 100px;
            margin-right: 100px;
        }

        .center {
            float: left;
            width: 100%;
            height: 100px;
        }

        .left {
            float: left;
            margin-left: -100%;
            position: relative;
            left: -100px;
            width: 100px;
            height: 100px;
        }

        .right {
            float: left;
            margin-left: -100px;
            position: relative;
            right: -100px;
            width: 100px;
            height: 100px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="center" style="background-color:rgb(9, 134, 236)"></div>
        <div class="left" style="background-color:red"></div>
        <div class="right" style="background-color:rgb(6, 235, 44)"></div>
    </div>
</body>

</html>

5.flex

原理: 设置父元素 display:flex;再设置子元素的flex

flex 属性是 flex-grow、flex-shrink 和 flex-basis 属性的简写属性:

  • flex-grow:项目将相对于其他灵活的项目进行扩展的量
  • flex-shrink:规定项目将相对于其他灵活的项目进行收缩的量
  • flex-basis:项目的默认长度

优点:可以先写center,让他先加载,然后用order属性,把他排到中间的位置

.container{
    display:flex;
    width:100%;
    height:100px;
}
.left{
    flex:0 0 100px;
    order: 0 /*默认为0*/
}
.right{
    flex:0 0 100px;
    order:2
}
.center{
    flex:1 1 auto;
    order:1
}

<div class="container">
        <div class="center" style="background-color:rgb(9, 134, 236)"></div>
    <div class="left" style="background-color:red"></div>
    <div class="right" style="background-color:rgb(6, 235, 44)"></div>
</div>

6. table布局

缺点:无法设置栏间距

.container{
    display:table;
    width:100%;
}
.left,.center,.right{
    display:table-cell;
}
.left{
    width:100px;
    height:100px;
}
.right{
    width: 100px;
    height:100px;
}

<div class="container">
    <div class="left" style="background-color:red"></div>
    <div class="center" style="background-color:rgb(9, 134, 236)"></div>
    <div class="right" style="background-color:rgb(6, 235, 44)"></div>
</div> 

7.绝对定位布局

优点: 简单实用,并且主要内容可以优先加载。

.container{
    position:relative;
}
.center{
    margin-left:100px;
    margin-right:100px;
    height:100px;
}
.left{
    position:absolute;
    left:0;
    top:0;
    width:100px;
    height:100px;
}
.right{
    position:absolute;
    right:0;
    top:0;
    width:100px;
    height:100px;
}

<div class="container">
    <div class="left" style="background-color:red"></div>
    <div class="center" style="background-color:rgb(9, 134, 236)"></div>
    <div class="right" style="background-color:rgb(6, 235, 44)"></div>
</div> 

8.网格布局(Grid布局)

grid-template-columns: 100px auto 100px;
用于设置网格容器的列属性 其实就相当于列的宽度 当我们需要几列展示时
就设置几个值 这个属性可以接收具体数值比如100px 也可以接收百分比值
表示占据容器的宽度
需要注意的是: 当给容器设定了宽度时 grid-template-columns设定的百分比值是以容器的宽度值为基础计算的
如果未设置宽度时 会一直向上追溯到设置了宽度的父容器 直到body元素。
grid-template-rows: 100px;
用于设置网格容器的行属性 其实就相当于行的高度
其特性与grid-template-columns属性类似

.container{     
    display: grid;            
    grid-template-columns: 100px auto 100px;                     
    grid-template-rows: 100px;                
    }    

     <div class="container">
    <div class="left" style="background-color:red"></div>
    <div class="center" style="background-color:rgb(9, 134, 236)"></div>
    <div class="right" style="background-color:rgb(6, 235, 44)"></div>
</div>

总结

我个人还是更喜欢使用flex布局,感觉用起来很方便,基本上的布局都能够完成。