三欄佈局的n種實現

weixin_33720956發表於2016-06-15

本文主要討論左右邊欄固定寬度,中間欄填滿其餘空間的佈局。至於其他型別,基本上也就是半斤和八兩。每一種佈局都會有個Demo,個人依然認為文章裡帖程式碼並沒有Demo來的直接。所以正文負責解釋,原始碼參見Demo。其中討論了這麼多種(6種)佈局,有以下理由:1是每種佈局也都有他的毛病,沒有十全十美的,每種佈局也都有人在用。2是雖然有相對優秀的方案,但是不優秀的方案也有有用的東西在裡邊,可能會啟發其他的思路補充遺漏的知識點。

1. 利用絕對定位特點

左右兩欄採用絕對定位抽離文件流,分別固定於頁面的左右兩側,中間欄用左右margin值撐開可以容納左右邊欄的距離。這個很簡單不多解釋。 Demo:absoluteLayout

2. 利用兩側浮動都不佔據文件流

左欄左浮動,右欄右浮動,中間欄左右margin值等於左右欄寬度。html中,中間欄要放在左右邊欄的後邊。道理上和絕對定位差不多,就是不佔文件流了其他元素就填充上了,只要把兩邊留出空間不導致重合即可。 Demo:twoSidesFloatLayoutDemo

3. 利用浮動和margin負值的特點

標籤順序為<middle></middle> <left></left> <right></right> middle 寬度 100%,sub 左右 margin 為左右欄留出空間,其中 sub 元素不要浮動,否則會包裹裡面的內容而不會撐滿空間,其他元素全部左浮動。left 的 margin-left 為-100%,right 的margin-left為sub的負的margin-right 。浮動的特點就是緊跟著前一個元素,放不下了就換行,本來middle元素佔滿了第一行,sub元素的margin留出的空間並不會給其他的浮動元素,左欄被迫換行,處於第二行最左側,相當於緊跟著第一行後邊,100%的負margin-left會讓他從緊跟著第一行變成第一行最左邊,這時左欄和sub元素的margin-left留出的空間重合,達到目的,此時右欄在原來左欄的位置,再用類似的處理方式,達到最終效果。其中sub的margin可以換為padding,相同的原理和效果。此處如果不需要撐滿空間(有內容撐滿sub)可以不要父元素(即middle)。Demo:floatLayoutDemo。說的有點亂其實就是這個樣子:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title></title>
        <style media="screen">
        *{margin: 0;padding: 0;height: 100%;}
          .l,.r,#main{
            text-align: center;
            float:left;
          }
          #main{
            width: 100%;
          }
          .l{
            width: 100px;
            margin-left: -100%;
            background-color: #aaaaaa;
          }
          .c{
            text-align: center;
            margin-left: 100px;
            margin-right: 200px;
            background-color: #555555;
          }
          .r{
            width: 200px;
            margin-left: -200px;
            background-color: #aaaaaa;
          }
        </style>
      </head>
      <body>
        <div id="main">
          <div class="c">
            我中間
          </div>
        </div>
        <div class="l">
          我左邊
        </div>
        <div class="r">
          我右邊
        </div>
      </body>
    </html>

4. 利用inline-block特點

父元素包含左中右欄:(子元素順序中,左,右)父元素設定padding為左右欄留出空間,然後中欄寬度100%佔據除padding外的空間,左右欄利用margin-left等於自身寬的負值使其與中欄右邊界重合,再調節left,左欄left為-100%右欄left為右欄寬度。左中右欄全部為子元素,所以margin-left無法佔據padding空間,需要左右邊欄相對定位後調解left值達到目標狀態。其中注意父元素設定font-size: 0; letter-spacing: -4px; 子元素再重置這兩個屬性。 Demo:inlineBlockLayoutDemo。說的有點亂,其實就是這個樣子:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title></title>
        <style media="screen">
        *{margin: 0;padding: 0;height: 100%;}
          .l,.c,.r{
            display: inline-block;
            font-size: 16px;
            letter-spacing: normal;
          }
          .l{
            width: 100px;
            margin-left: -100px;
            position: relative;
            left: -100%;
          }
          .c{
            width:100%;
            background-color: #555555;
          }
          .r{
            position: relative;
            width: 200px;
            margin-left: -200px;
            left: 200px;
          }
          #box{
            text-align:center;
            padding-left: 100px;
            padding-right: 200px;
            background-color: #aaaaaa;
            font-size: 0;
            letter-spacing: -4px;
          }
        </style>
      </head>
      <body>
        <div id="box">
          <div class="c">
            我中間
          </div>
          <div class="l">
            我左邊
          </div>
          <div class="r">
            我右邊
          </div>
        </div>
      </body>
    </html>

5. 利用calc屬性和inline-block特點

父元素設定(同樣是父元素包含左中右欄):  text-align:center;    font-size: 0;      letter-spacing: -4px; 左中右欄再重置:  font-size: 16px;      letter-spacing: normal; 左右欄固定寬度,  html中元素順序為:左,中,右    ,假設左右欄寬度和300px;中間攔:  width:calc(100% - 300px); 百分比與固定寬度混合佈局使用,支援ie9+,注意+-*/號兩邊留空格 Demo:useCalcLayoutDemo

6. 利用flex佈局

flex佈局我認為是最先進而方便的佈局,非常靈活不過內容也不少,只可惜相容ie10+。不在這多廢話,推薦阮一峰老師的教程:flex教程。 父元素display:flex; ,左右兩欄設定flex-basis 預置寬度,中間欄flex-grow: 1;自動伸展。完活。 Demo:flexLayoutDemo

相關文章