今天看啥  ›  专栏  ›  Taec0123

负margin和三栏布局的实现

Taec0123  · 简书  ·  · 2021-01-26 13:20

想到3栏布局首先就是圣杯布局和双飞翼布局,他们都遵循如下要点

两侧宽度固定,中间宽度自适应
中间部分在DOM结构上优先,以便先行渲染
允许三列中的任意一列成为最高列
只需要使用一个额外的<div>标签

圣杯布局和双飞翼布局的区别

圣杯布局和双飞翼布局在html结构上就有明显的区别,圣杯布局3栏在同一个盒子内,双飞翼布局是3个独立的盒子,不过中间盒子还需要内嵌一个盒子来放内容
圣杯布局

<div id="container">
      <div id="center">center</div>
      <div id="left">left</div>
      <div id="right">right</div>
</div>

双飞翼布局

<body>
  <div id="center2">
    <div id="inside"></div>
  </div>
  <div id="left2"></div>
  <div id="right2"></div>
<body>

使用负margin完成

假设完成下图的布局



要使center为自适应,宽度就设置为100%,left的宽度200排序,right宽度150px,下面的css会用到浮动和定位两个方法,具体可以看注释

圣杯布局

是3个同层级的盒子,

   #container{
      /* padding是上左下右的排序,分别给右侧200px和左侧150px的预留空间 */
      padding: 0 150px 0 200px;
   }
   #center{
      /* 设置left浮动 */
      float: left;
      /* 宽度为100%,表示自动宽度 */
      /* 减去左padding150px和右侧padding200px的剩余的全部空间 */
      width: 100%;
      height: 500px;
      background:blue;
   }
   #left{
      float:left;
      width:200px;
      height:500px;
      /* 全部设置浮动的情况,因为center已经长度为100%了,left和right会被迫到下一行 */
      /* 这个时候要用到负margin,选择和浮动方向一样的margin来设置负margin */
      /* -100%的意思是向左移动100%的container的宽度,这里会让left的左边距和center的左边距对齐 */
      margin-left:-100%;
      background: #0c9;
      /* 通过定位,相对定位是相对当前的定位*/
      position: relative;
      /* left-200px是将当前的盒子往定位前的位置往左移动200px */
      /* 这样left就进入了container的左padding内,不会覆盖center */
      left: -200px;
   }
   #right{
      float: left;
      width: 150px;
      height: 500px;
      /* 负margin设定为和宽度一致的同时,可以理解为right的宽度为0 */
      /* right的右边距会和center的右边距贴合 */
      margin-left: -150px;
      background: #0c9;
      /* 定位的原理和left相同 */
      position: relative;
      right: -150px;
   }

关键点在于:

  1. container 内用 padding left right 留下了空间
  2. center 设置 width:100% ,实现 center 宽度自适应
  3. left right 都用了负margin来实现和 center 并排
  4. left right 使用定位将盒子放入 container padding 预留的空间内

圣杯布局:为了让中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。

双飞翼布局

3个独立盒子,center盒子内包裹内容盒子

   #center2{
      /* 布局的center */
      float:left;
      /* 宽度设置为当前页面宽度 */
      width:100%;
      height:100px;
      background:blue;
   }
   #inside{
      /* center的内部显示区域,用margin去除被遮挡的区域 */
      margin:0 200px 0 180px;
      height:100px;
   }
   #left2{
      float:left;
      width:200px;
      height:100px;
      /* 用负100%让left贴合center的左侧 */
      margin-left:-100%;
      background:#0c9;
   }
   #right2{
      float:left;
      width:150px;
      height:100px;
      /* 用和宽度一样的负margin,让right盒子在浮动情况下和center并排 */
      margin-left:-150px;
      background:#0c9;
   }

关键点是

  1. 全体浮动left之后,因为浮动的原理会是center一排,left和right一排
  2. 使用-100%的margin让left的左侧和center的左侧贴合
  3. 使用负right宽的margin让right的右侧和center的右侧贴合
  4. 那么center左右会被left和right遮挡,inside就用margin把这两个区域隔出来,内容写在inside内,就可以避免遮挡。

双飞翼布局:为了让中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,在该div里用
margin-left和margin-right为左右两栏div留出位置。

使用flex完成

既然能用定位和浮动完成,当然用flex也能完成,只要注意flex的几个参数即可。flex布局不记得了可以参考下这个文章 Flex 布局教程:语法篇 ,这里只需要专注于接下来这个参数
order :属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
html结构

  <body>
    <div class="flex_container">
      <div class="flex_center">flex的center</div>
      <div class="flex_left">flex的left</div> 
      <div class="flex_right">flex的right</div>
    </div>
  </body>

css代码

   .flex_container {
      /* container容器内采用flex布局 */
      display: flex;
      height: 200px;
   }
   .flex_center {
     /* flex1代表占用剩余空间  */
     flex: 1;
     background-color: blue;
   }
   .flex_right {
      /* order表示在这个flex中所处位置 */
      order: 1;
      width: 150px;
      background:#0c9;
   }
   .flex_left {
      order: -1;
      width: 200px;
      background:#0c9;
   }

flex:1 = flex-grow:1; flex-shrink:1;flex-basis: 0%


更详细的解释可以看之前写的文章 手写圣杯布局 ,写到这里也发现了之前文章的一点漏洞,既然是圣杯布局,就要遵循center先加载的要求,所以要把center放在中间,这篇文章里面就没有这么做。

参考文章

  1. 圣杯布局和双飞翼布局的理解和区别



原文地址:访问原文地址
快照地址: 访问文章快照