【面试】css两栏布局、三栏布局

243 阅读6分钟

css两栏布局

例如我们有一个dom结构

    <div class="outer">
        <div class="left">float布局</div>
        <div class="right"></div>
    </div>

实现双列布局:

image.png

实现方式主要总结了以下4种方式:

1. 浮动方式

left设置float,并且设置宽度,right设置margin-left:左边的宽度

    <!-- float 左边宽度200,右边margin-left:200px,宽度auto -->
    <div class="outer">
        <div class="left">float布局</div>
        <div class="right"></div>
    </div>

 /* float布局 */
        .outer {
            height: 100px;
        }
        .left {
            float: left;
            width: 200px;
            height: 100px;
            background-color: tomato;
        }
        .right {
            margin-left: 200px;
            height: 100px;
            background-color: gold;
        }

2. float+overflow:hidden

左侧float,和上一种的区别是right通过添加overflow:hidden触发bfc,清除浮动,这个涉及都了BFC(块级格式上下文),清除浮动也是BFC的一个主要应用。BFC学习文章

BFC是一个独立的布局环境,里面元素的布局不受外面布局的影响,也不会影响外部元素。可以通过以下方式创建:

  1. 根元素:body
  2. float:left/right
  3. overflow:hidden、auto、scroll
  4. display: inline-block/table-cell/grid/flex
  5. position: absolute/fixed

设置了以上属性的元素就会触发BFC,BFC特性有:

  1. BFC中上下相邻的两个容器margin会重叠
  2. BFC高度的计算会包括浮动元素的计算
  3. BFC区域不会与浮动容器发生重叠 这个就是利用的这个特性
  4. 容器内部元素不会影响外部元素
  5. 每个元素的左margin和容器的左border相接触
  <!-- float布局:左侧固定大小,左浮动,右侧设置overflow:hidden,触发BFC,BFC区域不会与浮动元素发生重叠 -->
    <div class="outer1">
        <div class="left1">float+overflow</div>
        <div class="right1"></div>
    </div>

/* float+overflow */
.outer1 {
    height: 200px;
}
.left1 {
    float: left;
    width: 200px;
    height: 200px;
    background-color: aliceblue;
}
.right1 {
    height: 200px;
    overflow: hidden;
    background-color: saddlebrown;
}

3. 绝对布局

父元素relative,左侧absolute,右侧设置margin-left,和第一种也很像,只是这种方式left是absolute定位方式。

 <!-- 绝对定位:负元素releative,左边设置absolute,固定宽度200,右边margin-left:200px -->
<div class="outer2">
    <div class="left2">absolute</div>
    <div class="right2"></div>
</div>
/* absolute */
.outer2 {
    position: relative;
    height: 100px;
}
.left2 {
    position: absolute;
    width: 200px;
    height: 100px;
    background-color: tomato;
}
.right2 {
    margin-left: 200px;
    height: 100px;
    background-color: gold;
}

4. flex布局

flex大法好,最简单清晰,父元素设置flex,左边设置宽度,右边设置flex:1 即可。

这里需要知道flex:1代表的含义。flex是以下三个属性的缩写:

  • flex-grow:如果有剩余空间,是否扩大,默认为0,不扩大。
  • flex-shrink:如果剩余空间不够,是否缩小,默认是1,默认缩小。
  • flex-basis: 主要是在有剩余空间时,计算剩余空间时每个item的大小。浏览器根据这个属性计算主轴是否有剩余空间。默认值是auto,就是设置为宽度,就是说你如果不设置,就是项目的宽度,如果设置了就得按照这个计算剩余空间值。但同时这个值受限于maxwidth,minwidth。
/**  有剩余空间时放大,没空间时缩小,
    flex-grow: 1; 
    flex-shrink: 1;
    flex-basis: 0%;
**/
flex: 1;

/**
    有剩余空间时不放大,没有剩余空间时缩小
    flex-grow: 0;
    flex-shrink: 1;
    flex-basis: 0%;
**/
flex: 0;

/**
    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: auto;
**/
flex: auto;

/**
    flex-grow: 0;
    flex-shrink: 0;
    flex-basis: auto;
**/
flex: none;

想具体了解的话可以参考下面的文章:

<!-- flex布局:左边设置固定宽度200,右边flex:1 -->
<div class="outer4">
    <div class="left4">flex</div>
    <div class="right4"></div>
</div>
// flex布局,右侧设置flex1flex-grow1flex-basis默认是0,所以剩余空间是100%-200right直接占据右侧所有内容。
.outer4 {
    height: 200px;
    display: flex;
}
.left4 {
    width: 200px;
    background-color: aqua;
}
.right4 {
    flex: 1; // 自动伸展
    background-color: rebeccapurple;
}

总结:还是flex好,现在开发一般都用flex了,掌握flex很重要啊‼️

css三栏布局

image.png

对于三栏布局,dom放置的位置就有讲究了,下面列一下常见的实现方式:

1. float布局

左右float,中间margin

<!-- float布局注意布局的前后顺序,main放在最后 -->
<div class='container'>
    <div class="left">float基础布局</div>
    <div class="right"></div>
    <div class="main"></div>
</div>
/* float布局:左右float中间margin */
.container {
    height: 200px;
}
.left {
    float: left;
    width: 200px;
    height: 200px;
    background-color: aliceblue;
}
.right {
    float: right;
    width: 200px;
    height: 200px;
    background-color: aqua;
}
.main {
    margin: 0 200px;
    height: 200px;
    background-color: beige;
}

2. float升级+overflow

用了BFC的特性,清除浮动

    <!-- float布局升级,左右float,中间main overflow形成BFC -->
    <div class='container1'>
        <div class="left1">float升级布局布局</div>
        <div class="right1"></div>
        <div class="main1"></div>
    </div>

.left1 {
    float: left;
    width: 200px;
    height: 200px;
    background-color: rgb(125, 139, 151);
}
.right1 {
    float: right;
    width: 200px;
    height: 200px;
    background-color: rgb(255, 0, 225);
}
// 和上一个的区别在于main的样式,加上hidden触发bfc,bfc不会与浮动区域发生重叠
.main1 {
    height: 200px;
    overflow: hidden;
    background-color: rgb(193, 193, 51);
}

3. 圣杯布局、双飞翼布局

圣杯布局和双飞翼布局都是main在前面,区别是设置main内容遮挡的策略不一样。

  • 圣杯布局通过设置父元素padding留出左右两栏的空间,然后left和right再加上relative定位来放到内容区外面
  • 双飞翼布局通过多添加一个div的方式,设置内部元素的margin来处理内容遮挡

这里涉及到一个知识点是:margin负值的理解

    <!-- 圣杯:三个都float:left,父元素设置padding留出左右两栏宽度,中间设置父元素100%,左栏margin-left:-100%,右栏margin-left:-宽度,保证同一行,并且绝对定位完成左右两边移动 -->
    <div class='container2'>
        <div class="main2">圣杯布局</div>
        <div class="left2"></div>
        <div class="right2"></div>
    </div>
    <!-- 双飞翼布局:三个都float:left,中间设置100%,左右2栏margin-left:-100%,保证同一行 -->
    <div class='container3'>
        <div class="main3">
            <!-- 通过增加一个父元素设置和左右两栏的边距 -->
            <div class="main3-inner">双飞翼布局</div>
        </div>
        <div class="left3"></div>
        <div class="right3"></div>
    </div>
// 圣杯布局
.container2 {
    padding: 0 200px;
    overflow:hidden;// 包含浮动元素
}
.left2 {
    position: relative;
    left: -200px;
    float: left;
    margin-left: -100%;
    width: 200px;
    height: 200px;
    background-color: aliceblue;
}
.right2 {
    position: relative;
    right: -200px;
    float: left;
    margin-left: -200px;
    width: 200px;
    height: 200px;
    background-color: aquamarine;
}
.main2 {
    float: left;
    width: 100%;
    height: 200px;
    background-color: bisque;
}

// 双飞翼布局
.container3 {
    overflow:hidden;// 包含浮动元素
}
.left3 {
    float: left;
    margin-left: -100%;
    width: 200px;
    height: 200px;
    background-color: rgb(65, 81, 95);
}
.right3 {
    float: left;
    margin-left: -200px;
    width: 200px;
    height: 200px;
    background-color: rgb(14, 140, 98);
}
.main3 {
    float: left;
    width: 100%;
    height: 200px;
    background-color: rgb(220, 128, 14);
}
.main3-inner {
    margin: 0 200px;
}

4. 绝对定位

直接看吧。

 <!-- 绝对定位 -->
    <div class='container4'>
        <div class="left4"></div>
        <div class="main4">绝对定位</div>
        <div class="right4"></div>
    </div>
.container4 {
    position: relative;
    border: 1px solid #000;
}
.left4 {
    position: absolute;
    left: 0;
    top: 0;
    width: 200px;
    height: 200px;
    background-color: blanchedalmond;
}
.right4 {
    position: absolute;
    right: 0;
    top: 0;
    width: 200px;
    height: 200px;
    background-color: azure;
}
.main4 {
    height: 200px;
    margin: 0 200px;
    background-color: blueviolet;
}

5. flex布局

到了flex布局就会想,会啥还需要上面的布局,直接用这个就好呢,上面又复杂又绕,现在flex的兼容性已经很好了,大部分情况下都可以用了。所以还是flex香啊。

flex实现2栏、3栏布局都很简单,都是利用flex:1来实现。真好。

<!-- flex定位 -->
<div class='container5'>
    <div class="left5"></div>
    <div class="main5">flex定位</div>
    <div class="right5"></div>
</div>
.container5 {
    display: flex;
}
.left5,
.right5 {
    width: 200px;
    height: 200px;
    background-color: rgb(30, 218, 218);
}
.main5 {
    flex:1;
    background-color: blanchedalmond;
}

以上相关代码git链接:github.com/muyudou/int…

ps:好好写一篇文章果然很累。这css的知识点也好多好多啊啊啊啊