css布局篇——两/三栏布局(无废话版)

88 阅读5分钟

两栏布局

核心思路

一般两栏布局指的是左边一栏宽度固定,右边一栏宽度自适应

第一种方法

  • 浮动 + margin-left(将左边元素宽度设置为200px,并且设置向左浮动。将右边元素的margin-left设置为200px)
<body>
  <div class = "box">
    <div class = "left"></div>
    <div class = "right"></div>
  </div>
  我是文字
</body>
<style>
    .left{
        width: 200px;
        height: 400px;
        background-color: orange;
        float :left;
  }
    .right{
        height: 300px;
        margin-left: 200px;
        background-color: yellowgreen;
    }
</style>

image.png

oh my god 下面的其他内容怎么跑上去了? 是因为我们使用了浮动

啥是浮动?

浮动会导致元素脱离原来普通的文档流。元素可以向左或者向右浮动,直到碰到父容器或其他浮动元素才停下。在原来的文档流里,它就像被 “删掉” 了一样,不占位置。这样一来,父元素就会因为没东西撑着,高度变成 0,出现高度塌陷,后面的内容也会自动往上跑,跟浮动元素叠在一起。

解决办法:

  • BFC,块级格式化上下文,BFC 规定了内部的块级元素的布局方式。常见的做法是为父元素添加:
overflow:hidden;

啥是BFC

块格式化上下文(Block Formatting Context,BFC),是Web页面的可视化CSS渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。

BFC的特点

  • 垂直方向上,自上而下排列,和文档流的排列方式一致。
  • 在BFC中上下相邻的两个容器的margin会重叠
  • 计算BFC的高度时,需要计算浮动元素的高度
  • BFC区域不会与浮动的容器发生重叠
  • BFC是独立的容器,容器内部元素不会影响外部元素
  • 每个元素的左margin值和容器的左border相接触

叽里咕噜说啥呢,给我二百块钱

人话

BFC就是一个独立的布局容器,内部元素自己玩自己的,不跟外面互相干扰,还能把浮动元素 “包住”,解决高度塌陷。

创建BFC的条件

  • 根元素:body;
  • 元素设置浮动:float 除 none 以外的值;
  • 元素设置绝对定位:position (absolute、fixed);
  • display 值为:inline-block、table-cell、table-caption、flex等;
  • overflow 值为:hidden、auto、scroll;

创建BFC后的效果

回归正题,我们实现两栏布局只需要为.box 元素添加样式:

overflow:hidden;

image.png

第二种方法

  • 利用flex布局,将左边元素设置为固定宽度200px,将右边的元素设置为flex:1。
<style>
    .box{
        display: flex;
    }
    .left{
        width: 200px;
        height: 400px;
        background-color: orange;    
  }
    .right{
        flex: 1;
        height: 300px;
        background-color: yellowgreen;
    }
</style>

三栏布局

核心思路

和两栏布局类似,换汤不换药,左右两栏宽度固定,中间自适应的布局

第一种方法

  • position + margin

人话

父元素相对定位,通过绝对定位将左右两栏固定,再通过 margin 设置左右边距,留出内容块,实现:

HTML部分

<body>
  <div class = "box">
    <div class = "left"></div>
    <div class = "middle"></div>
    <div class = "right"></div>
  </div>
</body>

css部分

<style>
    .box{
        position: relative;
    }
    .left{
        width: 200px;
        height: 200px;
        background-color: orange;    
        position: absolute;
        left: 0;
        top: 0;
    }
   .middle{
        background-color: yellowgreen;
        height: 200px;
        margin-left: 200px;
        margin-right: 200px;
   }
   
    .right{
        width: 200px;
        height: 200px;
        background-color: orange;
        position: absolute;
        right: 0;
        top: 0;
    }
</style>

效果

image.png

第二种方法

  • float 浮动+ margin

人话

左右两栏使用 float 浮动到相应位置,中间栏通过 margin 属性撑开。实现: 只修改css部分:

<style>
    .box{
        overflow: hidden;
    }
    .left{
        width: 200px;
        height: 200px;
        background-color: orange;    
        float: left;

    }
    .middle{
        height: 200px;
        background-color: yellowgreen;
        margin-left: 200px;
        margin-right: 200px;
   }
 
    .right{
        width: 200px;
        height: 200px;
        background-color: orange;
        float: right;
    }

</style>

效果

image.png ......咋成这样了

问题及解决办法

这个问题是因为浮动元素的排列顺序导致的:在原始的 HTML 结构中,.middle写在了.right的前面,而浮动元素是 “从当前位置开始浮动” 的,所以.right会被.middle挤到下方,只需要调整 HTML 的顺序,把.right放到.middle的前面即可。

第三种方法

  • flex :1大王

利用flex布局,左右两栏设置固定大小,中间一栏设置为flex:1,不再废话了。

圣杯布局

核心思路

  • 利用浮动和负边距来实现。
  • 父级元素设置左右的 padding,三列均设置向左浮动,中间一列放在最前面,
  • 宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行,通过设置 margin 负值将其移动到上一行,再利用相对定位,定位到两边。
<div class = "box">
    <div class = "middle"></div>
    <div class = "left"></div>
    <div class = "right"></div>
  </div>
<style>
    .box{
        padding: 0 200px;
        overflow: hidden;
    }
    .left{
        width: 200px;
        height: 200px;
        background-color: orange;    
        float: left;
        margin-left: -100%;
        position: relative;
        left: -200px;
    }
    .middle{
        height: 200px;
        background-color: yellowgreen;
        float: left;
        width: 100%;
   }
 
    .right{
        width: 200px;
        height: 200px;
        background-color: orange;
        float: left;
        margin-left: -200px;
        position: relative;
        right: -200px;

    }

</style>

效果

image.png

双飞翼布局

核心思路

相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的,而不是通过父元素的 padding 来实现的。

人话

本质上来说,也是通过浮动和外边距负值来实现的。依旧换汤不换药。

  • 左中右三个元素分别左浮动;
  • 中间元素width为100%;
  • 左元素设置左边距为-100%,右元素设置左边距为自身宽度的负值;
  • 设置中间元素的子元素左右边距为左右元素留空位。
<body>
  <div class = "box">
    <div class="middle">
        <div class="content"></div>
    </div>
    <div class = "left"></div>
    <div class = "right"></div>
  </div>
</body>
<style>
    .box{
        overflow: hidden;
    }
    .left{
        width: 200px;
        height: 200px;
        background-color: orange;    
        float: left;
        margin-left: -100%;
    }
    .middle{
        float: left;
        width: 100%;
    }
    .middle .content{
        height: 200px;
        background-color: yellowgreen;
        margin: 0 200px;
   }
 
    .right{
        width: 200px;
        height: 200px;
        background-color: orange;
        float: left;
        margin-left: -200px;
    }

</style>

效果

image.png

对比圣杯布局和双飞翼布局

相同

  • 两思路都是左右栏固定宽度,中间栏自适应,用浮动和负边距使左右栏与中间栏并排。

不同

  • 圣杯布局是给父元素设置边距,左右元素设置相对定位。
  • 双飞翼布局在中间采用嵌套子元素方法,通过设置子元素外边距来展示。