CSS | CSS实现两栏布局和三栏布局方法详解

14 篇文章 1 订阅

一、背景

在日常布局中,无论是两栏布局还是三栏布局,使用的频率都非常高

两栏布局

两栏布局实现效果就是将页面分割成左右宽度不等的两列,宽度较小的列设置为固定宽度,剩余宽度由另一列撑满。

比如 Ant Design 文档,蓝色区域为主要内容布局容器,侧边栏为次要内容布局容器

这里称宽度较小的列父元素为次要布局容器,宽度较大的列父元素为主要布局容器

这种布局适用于内容上具有明显主次关系的网页

三栏布局

三栏布局按照左中右的顺序进行排列,通常中间列最宽,左右两列次之

大家最常见的就是 github

二、两栏布局

两栏布局非常常见,往往是以一个定宽栏和一个自适应的栏并排展示存在

参考:Web开发常用布局方式总结 - 烤地瓜的CSDN博客

(1) 浮动

float配合margin

  • 使用 float 左浮左边栏
  • 右边模块使用 margin-left 撑出内容块做内容展示(当然,不需要外边距也行,看需求)
<!DOCTYPE html>
<html>

<head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    html,
    body {
      height: 100%;
    }

    .box {
      height: 100%;
    }

    .left {
      float: left;
      width: 250px;
      background-color: gray;
      height: 100%;
    }

    .right {
      /* 左外边距要大于等于左侧栏容器的宽度 */
      margin-left: 260px;
      background-color: lightgray;
      height: 100%;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="left">左侧栏</div>
    <div class="right">右侧栏</div>
  </div>
</body>

</html>
(2) 浮动 + BFC

float配合overflow

实现思路也非常的简单:

  • 使用 float 左浮左边栏
  • 右边模块使用 margin-left 撑出内容块做内容展示(当然,不需要外边距也行,看需求)
  • 为父级元素添加BFC,防止下方元素飞到上方内容。

代码如下:

<!DOCTYPE html>
<html>

<head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    html,
    body {
      height: 100%;
    }

    .box {
      /* 添加BFC */
      overflow: hidden;
    }

    .left {
      float: left;
      width: 250px;
      background-color: gray;
      height: 100%;
    }

    .right {
      /* 左外边距要大于等于左侧栏容器的宽度,让左侧容器和右侧容器之间有一段10px的“呼吸”距离 */
      margin-left: 260px;
      background-color: lightgray;
      height: 100%;
    }
  </style>
</head>

<body>
  <div class="box">
    <div class="left">左边</div>
    <div class="right">右边</div>
  </div>
</body>

</html>

以上第二种方法,利用创建一个新的BFC(块级格式化剩下文)来防止文字环绕的原理来实现的。FC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。  

overflow 是 CSS 的简写属性,其设置了元素溢出时所需的行为——即当元素的内容太大而无法适应它的区块格式化上下文时。
参考:MDN | overflow:https://developer.mozilla.org/zh-CN/docs/Web/CSS/overflow

区块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视 CSS 渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
参考:MDN | 区块格式化上下文https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_display/Block_formatting_context

或者

通过将主栏和侧栏分别设置为左浮动和右浮动,可以实现两栏并排显示

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>两栏布局示例 - 浮动</title>
<style>
  .container {
    overflow: hidden; /* 清除浮动 */
  }
  .main {
    float: left;
    width: 70%;
    background-color: lightblue;
  }
  .sidebar {
    float: right;
    width: 30%;
    background-color: lightcoral;
  }
</style>
</head>
<body>
  <div class="container">
    <div class="main">主栏内容</div>
    <div class="sidebar">侧栏内容</div>
  </div>
</body>
</html>

在这个示例中,.main.sidebar分别设置为左浮动和右浮动,并分配了70%和30%的宽度。.container使用overflow: hidden来清除浮动,确保父容器包含浮动元素。 

或者 

.left{
  float: left;
  width: 50%; /* 或者指定宽度 */
}
 
.right {
  float: left;
  width: 50%; /* 或者指定宽度 */
}

/* 添加BFC */
.box::after {
  content: "";
  display: table;
  clear: both;
}

或者

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

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>两栏布局示例 - Flexbox</title>
  <style>
    .container {
      height: 300px;
    }

    .main {
      float: left;
      /* 定宽 */
      width: 200px;
      height: 100%;
      background-color: chartreuse;
    }

    .sidebar {
      /* 不设置宽度自适应 */
      height: 100%;
      /* 触发BFC条件 */
      overflow: hidden;
      background-color: coral;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="main">主栏内容</div>
    <div class="sidebar">侧栏内容</div>
  </div>
</body>

</html>

给正常元素添加BFC属性(BFC规则可以清除浮动),正常元素就不会被遮挡,且环绕浮动元素排开。

番外:清除浮动带来的影响的方法有哪些?


① 使用额外的空标签

父容器结尾插入空标签:在浮动元素的最后添加一个空的div,并设置clear属性为both。

<div style="clear: both;"></div>

② 利用CSS伪元素


在需要清除浮动的父元素上添加clearfix类即可。

.clearfix::before,
.clearfix::after {
  content: "";
 /* display: block; */
  display: table;
}
.clearfix:after {
  clear: both;
}
.clearfix {
  *zoom: 1; /* 兼容IE低版本 */
}

③ 使用overflow属性

在需要清除浮动的父元素上设置overflow属性为auto或hidden。

.parent {
  overflow: auto;
}

④ 将父容器形成BFC

BFC能清理浮动主要运用的是它的布局规则(这也是BFC的规则):

  • 内部的Box会在垂直方向,一个接一个的放置。就是我们平常div一行一行块级放置的样式。

  • box垂直方向的距离由margin决定。属于同一个BFC的两个相邻box的margin会发生重叠。

  • 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。就是元素左margin和包含块左border接触,即使存在浮动也是如此。左浮动就是靠左,右浮动就是靠右,

  • BFC的区域不会与float box重叠。应用于两列布局

  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。上下margin不影响,浮动不覆盖

  • 计算BFC的高度时,浮动元素也参与计算。如父元素高度塌陷,清除浮动。父元素高度由内部撑开,计算bfc高度,内部浮动的子元素也参加。

浮动清理利用的主要是第六条规则,只要将父容器触发为BFC,就可以实现包含的效果。


参考:请描述 BFC(Block Formatting Context) 及其如何工作

那么触发BFC有哪些方法?

‌CSS触发BFC(Block Formatting Context ——块格式化上下文)的方法主要包括以下几种‌:

  1. 根元素‌:根元素(即<html>元素)自身就是一个BFC。

  2. 浮动元素‌:当元素的float属性值不为none时,即设置为左浮动或右浮动,这样的元素会触发BFC。

  3. 绝对定位元素‌:当元素的position属性值为absolutefixed时,这样的绝对定位元素会触发BFC。

  4. 行内块元素‌:当元素的display属性值为inline-block时,这样的行内块元素会触发BFC。

  5. 表格单元格和表格标题‌:当元素的display属性值为table-celltable-caption时,这样的表格单元格和表格标题也会触发BFC。

  6. 弹性盒子容器‌:当元素的display属性值为flexinline-flexgridinline-grid时,这样的弹性盒子容器和网格容器会触发BFC。

  7. overflow属性‌:当元素的overflow属性值不为visible时,如设置为autoscrollhidden,这样的元素也会触发BFC。

这些方法涵盖了CSS中触发BFC的主要方式,包括通过元素的特定属性设置来创建BFC,从而影响布局和样式表现‌。

参考:请描述 BFC(Block Formatting Context) 及其如何工作

以下是两个实例: 

 示例1:浮动

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    html,
    body {
      height: 100%;
    }

    #left {
      /* 定宽 */
      width: 300px;
      height: 100%;
      float: left;
    }

    #right {
      height: 100%;
      margin-left: 300px;
      background-color: #eee;
    }
  </style>
</head>

<body>
<div id="left">左侧栏</div>
<div id="right">右侧栏</div>
</body>

</html>

示例2:浮动 + BFC

原理:给正常元素添加BFC属性,正常元素就不会被遮挡,且环绕浮动元素排开。

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    html,
    body {
      height: 100%;
    }

    #left {
      width: 300px;
      height: 100%;
      float: left;
    }

    #right {
      height: 100%;
      overflow: hidden;
      background-color: #eee;
    }
  </style>
</head>

<body>
  <div id="left">左侧栏</div>
  <div id="right">右侧栏</div>
</body>

</html>

还有一种更为简单的使用则是采取:flex弹性布局

(3) Flexbox布局

Flexbox是CSS3中引入的一种强大的布局模型,非常适合实现两栏布局。

情况一:一侧容器定宽

<style>
    .box{
        display: flex;
    }
    .left {
        /* 左侧容器为定宽 */
        width: 100px;
    }
    .right {
        /* 如果主轴方向的空间有剩余,就去填充剩余空间 */
        flex: 1;
    }
</style>
<div class="box">
    <div class="left">左边</div>
    <div class="right">右边</div>
</div>

完整代码如下:

<!DOCTYPE html>
<html>
  <head>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      html,
      body {
        height: 100%;
      }

      .box {
        display: flex;
        /* height: 300px; */
        height: 100%;
      }

      .item {
        height: 100%;
        padding: 20px;
      }

      .left {
        /* 左侧容器为定宽 */
        width: 100px;
        /* 因为未脱离文档流,所以不用设置高度也行 */
        /* height: 100%  */
        background-color: gray;
      }

      .right {
        /* flex 属性是 flex-grow、flex-shrink 和 flex-basis 属性的简写属性。*/
        flex: 1;
        /* 不设置width,宽度会自适应 */
        /* 因为未脱离文档流,所以不用设置高度也行 */
        /* height: 100% */
        background-color: lightgray;
      }
    </style>
  </head>

  <body>
    <div class="box">
      <div class="item left">左侧栏</div>
      <div class="item right">右侧栏</div>
    </div>
  </body>
</html>

在这个示例中,我们使用了简单的CSS样式来设置每个项目的背景颜色,以区分左右两栏。你可以根据自己的需要添加额外的样式来美化你的布局。 

情况二:容器不定宽,但左右容器宽度保持一定的比例,如下:左侧和右侧容器宽度保持1:2

<style>
    .box{
        display: flex;
    }
    .left {
        /* flex: 1 表示如果主轴方向的空间有剩余,就去填充剩余空间 */
        flex:1 /* 或者指定flex比例 */
    }
    .right {
        /* flex: 1 表示如果主轴方向的空间有剩余,就去填充剩余空间 */
        flex: 2; /* 或者指定flex比例,比如flex:2 */
    }
</style>
<div class="box">
    <div class="left">左边</div>
    <div class="right">右边</div>
</div>

完整代码如下:

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>两栏布局示例 - Flexbox</title>
  <style>
    .container {
      display: flex;
    }

    .main {
      flex: 70%;
      background-color: lightblue;
    }

    .sidebar {
      flex: 30%;
      background-color: lightcoral;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="main">主栏内容</div>
    <div class="sidebar">侧栏内容</div>
  </div>
</body>

</html>

通过将容器设置为display: flex,并调整主栏和侧栏的flex属性,可以轻松实现两栏布局。

在这个示例中,.container设置为display: flex.main.sidebar分别设置为flex: 70%flex: 30%,实现了两栏布局。 

flex可以说是最好的方案了,代码少,使用简单。

注意的是,flex容器的一个默认属性值:align-items: stretch;

这个属性导致了列等高的效果。 为了让两个盒子高度自动,需要设置: align-items: flex-start

示例:flex布局

利用弹性布局(Flexbox)实现两栏布局的方法主要包括以下几个步骤:

1‌、创建HTML结构‌:首先,创建一个包含两个列的容器元素。可以使用<div>元素作为容器,并为其添加一个类名,例如container

<div class="container">
    <div class="column1">Column 1</div>
    <div class="column2">Column 2</div>
</div>

2、设置Flexbox布局‌:在CSS中,为容器元素添加display: flex;属性,以启用Flexbox布局。

.container {
    display: flex;
}

‌3、设置列的宽度‌:默认情况下,Flexbox会根据内容自动调整列的宽度。如果要指定特定的宽度,可以使用flex-basis属性。例如,第一列的宽度为30%,第二列的宽度为70%。

.column1 {
    flex-basis: 30%;
}
.column2 {
    flex-basis: 70%;
}

4‌、设置其他Flexbox属性‌:根据需要,可以使用其他Flexbox属性来调整布局,例如justify-content用于水平对齐,align-items用于垂直对齐等。例如,可以设置列之间的空间均匀分布,并且列内容垂直居中对齐。

.container {
    display: flex;
    justify-content: space-between; /* 列之间的空间均匀分布 */
    align-items: center; /* 列内容垂直居中对齐 */
}

通过上述步骤,可以轻松地使用Flexbox实现两栏布局,并且可以根据需要进行灵活的调整和优化‌

(4) grid布局
.box {
  display: grid;
  /* 两列相同宽度 */
  grid-template-columns: 1fr 1fr;
}

.left {
  /* 内容 */
}

.right {
  /* 内容 */
}

完整代码如下:

<!DOCTYPE html>
<html>
  <head>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      .box {
        display: grid;
        /* 两列相同宽度 */
        grid-template-columns: 1fr 1fr;
        /* 两列不同宽度 */
        /* grid-template-columns: 70% 30%; */
        height: 100%;
      }

      .left {
        /* 内容 */
        height: 100%;
        background-color: gray;
      }

      .right {
        /* 内容 */
        height: 100%;
        background-color: lightgray;
      }
    </style>
  </head>

  <body>
    <div class="box">
      <div class="left">左侧栏</div>
      <div class="right">右侧栏</div>
    </div>
  </body>
</html>
 (5) 绝对定位布局
.container {
  position: relative;
}
 
.column1 {
  position: absolute;
  width: 50%; /* 或者指定宽度 */
  left: 0;
}
 
.column2 {
  position: absolute;
  width: 50%; /* 或者指定宽度 */
  right: 0;
}
  (6) 表格布局(已废弃,但仍可用)
.container {
  display: table-row;
}
 
.column1 {
  display: table-cell;
  width: 50%; 
  /* 或者指定宽度 */
  /* width: 200px; */
  /* 因为未脱离文档流,所以不用设置高度也行 */
  /* height: 100% */
}
 
.column2 {
  display: table-cell;
  width: 50%; /* 或者指定宽度 */
  /* 因为未脱离文档流,所以不用设置高度也行 */
  /* height: 100% */
}

 完整代码如下:

<!DOCTYPE html>
<html>
  <head>
    <style>
      /* table布局:(display:table-cell后)子级容器默认是自动平分宽度沾满父级容器; */
      .container {
        width: 100%;
        display: table;
        height: 300px;
      }

      .left {
        display: table-cell;
        /* 定宽 */
        width: 200px;
        /* 因为未脱离文档流,所以不用设置高度也行 */
        height: 100%;
        background-color: chartreuse;
      }

      .right {
        /* 因为未脱离文档流,所以不用设置高度也行 */
        /* height: 100% */
        display: table-cell;
        background-color: coral;

      }
    </style>
  </head>

  <body>
    <div class="container">
      <div class="left">左侧栏</div>
      <div class="right">右侧栏</div>
    </div>
  </body>
</html>

table布局只需要给父元素添加display:table属性,以及给两个子元素添加display: table-cell属性即可 。

根据需求和上下文,选择最适合的布局方法。如今,Flexbox 和 Grid 布局是最流行且功能强大的两种方法。 

参考:CSS实现两栏布局,左侧固定宽,右侧自适应的多种方法_脚本之家


参考:使用CSS实现两栏布局:多种方法与最佳实践 _ CSS两栏布局-CSDN博客

小结:以上脱离文档流的方式(如浮动定位),他们的大体思路都是: 先让左侧定宽元素脱离文档流,这样可以右列正常能够与左列脱离文档流的元素站成一排,此时左列元素还覆盖着右列元素,最后,我们只需要调整一下右列元素的外边距啊、定位啊什么的就可以完成啦~ 

应用场景

两栏布局在以下场景中非常有用:

  1. 博客和新闻网站:主栏用于展示文章内容,侧栏用于展示相关文章、广告或导航链接。
  2. 电子商务平台:主栏用于展示商品列表或详情,侧栏用于展示分类、筛选选项或购物车。
  3. 文档和教程网站:主栏用于展示文档内容,侧栏用于展示目录或导航链接。

注意事项

  1. 响应式设计:确保在不同设备和屏幕尺寸下,两栏布局仍然美观且实用。可以使用媒体查询来调整布局。
  2. 内容优先级:主栏通常包含主要内容,侧栏包含次要内容。确保内容布局符合用户阅读习惯。
  3. 浏览器兼容性:虽然Flexbox和Grid布局非常强大,但在使用前应检查目标浏览器的支持情况。

总结:

通过合理使用浮动、Flexbox和Grid布局,可以轻松实现两栏布局。每种方法都有其优势和适用场景,开发者可以根据具体需求选择合适的方法。 

三、三栏布局

参考:Web开发常用布局方式总结 - 烤地瓜的CSDN博客

实现三栏布局中间自适应的布局方式有:

  • 两边使用 float,中间使用 margin
  • 两边使用 absolute,中间使用 margin
  • 两边使用 float 和负 margin
  • display: table 实现
  • flex实现
  • grid网格布局
(1) 两边使用 float,中间使用 margin

需要将中间栏的内容放在html结构的最后,否则右侧会沉在中间内容的下方

实现代码如下:

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

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  ​
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .wrap {
      background: #eee;
      /* 生成BFC,计算高度时考虑浮动的元素 */
      overflow: hidden;
      padding: 20px;
      height: 400px;
    }

    .left {
      width: 200px;
      height: 400px;
      float: left;
      background: coral;
    }

    .right {
      width: 120px;
      height: 400px;
      float: right;
      background: lightblue;
    }

    .middle {
      /* 左外边距比左侧栏的width多出20px,用于隔开左侧栏和中间栏,让2者有段20px的“呼吸”距离 */
      margin-left: 220px;
      height: 400px;
      background: lightpink;
      /* 右外边距比右侧栏的width多出20px,用于隔开左侧栏和中间栏,让2者有段20px的“呼吸”距离 */
      margin-right: 140px;
    }
  </style>
  ​
</head>

<body>
  <div class="wrap">
    <div class="left">左侧</div>

    <div class="right">右侧</div>

    <div class="middle">中间</div>
  </div>
</body>

</html>

原理如下:

  • 两边固定宽度,中间宽度自适应。
  • 利用中间元素的margin值控制两边的间距。
  • 宽度小于左右部分宽度之和时,右侧部分会被挤下去。

    注:随着浏览器的宽度小于左侧容器和右侧容器宽度之和时,右侧容器会被挤下去,因为浏览器的一行里已经放不下了,如下图所示:

这种实现方式存在缺陷

  • 主体内容是最后加载的。
  • 右边在主体内容之前,如果是响应式设计,不能简单的换行展示。
(2)两边使用 absolute,中间使用 margin

基于绝对定位的三栏布局:注意绝对定位的元素脱离文档流,相对于最近的已经定位的祖先元素进行定位。无需考虑HTML中结构的顺序。

<style>
  .container {
    position: relative;
  }
  
  .left,
  .right,
  .main {
    height: 200px;
    line-height: 200px;
    text-align: center;
  }

  .left {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    background: green;
  }

  .right {
    position: absolute;
    top: 0;
    right: 0;
    width: 100px;
    background: green;
  }

  .main {
    margin: 0 110px;
    background: black;
    color: white;
  }
</style>

<div class="container">
  <div class="left">左边固定宽度</div>
  <div class="right">右边固定宽度</div>
  <div class="main">中间自适应</div>
</div>

完整代码如下:

​
<style>
  .container {
    position: relative;
  }

  .left,
  .right,
  .main {
    height: 200px;
    /* 元素内文字垂直居中 */
    line-height: 200px;
    /* 元素内文字水平居中 */
    text-align: center;
  }

  .left {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    background: green;
  }

  .right {
    position: absolute;
    top: 0;
    right: 0;
    width: 100px;
    background: green;
  }

  .main {
    margin: 0 110px;
    background: black;
    color: white;
  }
</style>

<div class="container">
   <div class="left">左边固定宽度</div>
   <div class="right">右边固定宽度</div>
   <div class="main">中间自适应</div>
</div>

效果图和动态演示如下:

 

实现流程:

  • 左右两边使用绝对定位,固定在两侧。
  • 中间占满一行,但通过 margin和左右两边留出10px的间隔
(3)两边使用 float 和负 margin
<style>
  .left,
  .right,
  .main {
    height: 200px;
    line-height: 200px;
    text-align: center;
  }

  .main-wrapper {
    float: left;
    width: 100%;
  }

  .main {
    margin: 0 110px;
    background: black;
    color: white;
  }

  .left,
  .right {
    float: left;
    width: 100px;
    margin-left: -100%;
    background: green;
  }

  .right {
    margin-left: -100px; /* 同自身宽度 */
  }
</style>

<body>
  <div class="main-wrapper">
    <div class="main">中间自适应</div>
  </div>
  <div class="left">左边固定宽度</div>
  <div class="right">右边固定宽度</div>
</body>

完整代码如下:

<!DOCTYPE html>
<html>
  <head>
    ​
    <style>
      .left,
      .right,
      .main {
        height: 200px;
        line-height: 200px;
        text-align: center;
      }

      .main-wrapper {
        float: left;
        width: 100%;
      }

      .main {
        margin: 0 110px;
        background: black;
        color: white;
      }

      .left,
      .right {
        float: left;
        width: 100px;
        margin-left: -100%;
        background: green;
      }

      .right {
        margin-left: -100px;
        /* 同自身宽度 */
      }
    </style>
  </head>

  <body>
    <div class="main-wrapper">
      <div class="main">中间自适应</div>
    </div>
    <div class="left">左边固定宽度</div>
    <div class="right">右边固定宽度</div>
  </body>
</html>

效果图和动态演示如下:

实现过程:

这个方法涉及到负边距对浮动元素位置的影响 | CSS | 强大的margin负边距

首先,左浮动后,布局结构为div.main、div.left紧挨其后、div.right紧挨其后,因为div.main宽度=父元素div.main-wrapper的宽度=body的宽度,所以此时div.left左边线与div.main-wrapper左边线以及body左边线是重合的(此时div.left已跑出浏览器左边100px即一个div.left距离,同样div.right紧随div.left之后是跑出浏览器200px)。

然后div.left通过margin-left:-100%即向左移动了一个body的宽度,也就是父元素body的100%宽度,因为中间部分的宽度=父元素div.main-wrapper的宽度=body的宽度,所以div.left元素margin-left:-100%后左边线与body左边线重合,此时,div.right紧随在div.main-wrapper右边线之后,即跑出浏览器右边线100px的距离,所以div.right通过使用负 margin-left:-100px,相当于向左走一个自身宽度即可让自己的最右边紧挨浏览器最右边线。

  • 中间部分使用了双层标签,外层是浮动的,以便左中右能在同一行展示
  • 左边部分通过使用负 margin-left:-100%,相当于中间的宽度,所以向上偏移到左侧
  • 右边部分通过使用负 margin-left:-100px,相当于自身宽度,所以向上偏移到最右侧

方案缺点:

  • 增加了 .main-wrapper 一层,结构变复杂。
  • 使用负 margin,调试也相对麻烦。

关于负marginCSS | 强大的margin负边距

负边距是可以影响浮动元素的位置的,所以网页布局中的圣杯布局、双飞翼布局什么的,都是利用这个原理实现的。也就是说某个元素虽然是在网页布局结构上把代码写在了前面或是后面,但可以通过负边距让它在浏览器中显示的时候展示在其他位置

(4) 使用 display: table 实现

<table> 标签用于展示行列数据,不适合用于布局。但是可以使用 display: table 来实现布局的效果

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
        height: 200px;
        /* 元素内文字垂直居中 */
        line-height: 200px;
        /* 元素内文字水平居中 */
        text-align: center;
        display: table;
        table-layout: fixed;
        width: 100%;
      }

      .left,
      .right,
      .main {
        display: table-cell;
      }

      .left,
      .right {
        width: 100px;
        background: green;
      }

      .main {
        background: black;
        color: white;
        width: 100%;
      }
    </style>

    <div class="container">
      <div class="left">左边固定宽度</div>
      <div class="main">中间自适应</div>
      <div class="right">右边固定宽度</div>
    </div>
  </head>

  <body></body>
</html>

效果图和动态演示如下:

实现原理:

  • 最外层通过 display: table设置为表格,设置 table-layout: fixed 表示列宽由自身宽度决定,而不是自动计算。
  • 内层的左中右通过 display: table-cell设置为表格单元。
  • 左右设置固定宽度,中间设置 width: 100% 填充剩下的宽度
(5) 使用flex实现

利用flex弹性布局,可以简单实现中间自适应

代码如下:

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

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style type="text/css">
    .wrap {
      display: flex;
      justify-content: space-between;
    }

    .left,
    .right,
    .middle {
      height: 100px;
    }

    .left {
      width: 200px;
      background: coral;
    }

    .right {
      width: 120px;
      background: lightblue;
    }

    .middle {
      background: #555;
      width: 100%;
      margin: 0 20px;
    }
  </style>
</head>

<body>
  <div class="wrap">
    <div class="left">左侧</div>
    <div class="middle">中间</div>
    <div class="right">右侧</div>
  </div>
</body>

</html>

实现过程:

  • 仅需将容器设置为display:flex;,
  • 盒内元素两端对其,将中间元素设置为100%宽度,或者设为flex:1,即可填充空白
  • 盒内元素的高度撑开容器的高度

优点:

  • 结构简单直观
  • 可以结合 flex的其他功能实现更多效果,例如,使用 order属性调整显示顺序,让主体内容优先加载,但展示在中间
(6) grid网格布局

跟flex弹性布局一样的简单

代码如下:

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

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .wrap {
      display: grid;
      width: 100%;
      grid-template-columns: 300px auto 300px;
    }

    .left,
    .right,
    .middle {
      height: 100px;
    }

    .left {
      background: coral;
    }

    .right {
      background: lightblue;
    }

    .middle {
      background: #555;
    }
  </style>
  <div class="wrap">
    <div class="left">左侧</div>
    <div class="middle">中间</div>
    <div class="right">右侧</div>
  </div>
</head>

<body>

</body>

</html>

参考文献

—— Web开发常用布局方式总结 _ 烤地瓜的CSDN博客 ——

—— CSS | CSS中强大的margin负边距 _ 烤地瓜的CSDN博客 ——

—— 一文了解,前端网页布局常用的几种方式 _ 烤地瓜的CSDN博客 ——

—— 实现响应式布局有几种方法_ 烤地瓜的CSDN博客 ——

CSS || 三栏布局,两边固定,中间自适应

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值