雙飛翼佈局(聖盃佈局)介紹-始於淘寶UED

仔細分析各種佈局的技術實現,可以發現下面三種技術被經常使用:

  • 浮動 float
  • 負邊距 negative margin
  • 相對定位 relative position

這是實現佈局的三個最基本的原子技術。只要巧妙組合,並加以靈活運用,就能“拼”出各種佈局的實現方案。

嘗試之路考慮以下DOM結構:

<div id="page">    
      <div id="hd"></div>    
         <div id="bd">        
              <div class="main"></div>        
              <div class="sub"></div>        
              <div class="extra"></div>    
         </div>   
      <div id="ft"></div>
</div>

利用浮動元素的負邊距來定位:

.main {        
           float: left;       
           width: 100%;   
 }  
.sub {       
           float: left;        
           width: 190px;        
           margin-left: -100%;    
}   
.extra {        
             float: left;        
             width: 190px;        
             margin-left: -190px;   
 }

這樣我們得到了第一個嘗試頁面 點擊這裏查看效果
可以看出,通過簡單的負邊距,已經讓sub和extra定位到正確的位置。剩下的問題是如何讓main也定位到正確的位置。
一個自然的想法是,給main的容器#bd添加padding:

#bd {        
          padding: 0 230px 0 190px;   
 }

點擊這裏查看效果

這樣能讓main定位到正確的位置,但sub和extra的位置不對了。這是一個思考的關卡。既然sub和extra的位置不對,那就想辦法調整到正確的位置。相對定位隆重登場:

.sub {        
           float: left;        
           width: 190px;        
           margin-left: -100%;        
           position: relative;        
           left: -190px;    
}  
  .extra {        
             float: left;        
             width: 230px;        
             margin-left: -230px;        
             position: relative;        
             right: -230px;    
}

點擊這裏查看完成頁面 

很明顯,這就是聖盃佈局!
在不增加任何額外標籤的假設上,我嘗試了各種想法,但始終都沒找到完美的佈局實現(聖盃佈局是我覺得所有想法中最接近完美的)。
既然不添加額外標籤時,完美佈局的實現如此困難,那如果允許添加一個額外標籤呢?在淘寶UED內部的探討中,給main增加了一層包裹:

<div id="main" class="column">   
 
<div id="main-content">#main</div>

</div>

裏層main-content的作用就是將main定位到合適的位置,並方便設置padding等屬性。想到此處,就像牛頓被蘋果砸傻了一樣,原來的main定位問題迎刃而解:

<div id="page">    
 
               <div id="bd">        
 
               <div class="main"></div>
 
               </div>
 
</div>

CSS僅需增加一行:

.main-wrap {    margin: 0 230px 0 190px;}

想看example4效果點這裏
一切如此簡單!除了添加了一個額外標籤,其它各方面,表現都很完美(試了下IE5.5, 也沒任何問題)。目前只用到了浮動和負邊距,如果再引入相對定位,還可以實現三欄佈局的各種組合

.extra {        
            float: left;        
            width: 230px;        
            margin-left: -100%;        
            position: relative;        
             left: 190px;    
         }    
.main-wrap {        
                  margin-left: 430px;   
                 }

點擊這裏查看example5效果

仔細查看example5和example4的源代碼,可以發現DOM結構是完全一樣的,僅僅CSS稍有不同。這意味着HTML結構和CSS佈局在一定程度上解耦了,我們開發HTML代碼時,從內容出發即可,無需過多的考慮佈局。這正是漸進增強在前端工作流程上的體現。
如果把三欄佈局比作一隻大鳥,可以把main看成是鳥的身體,sub和extra則是鳥的翅膀。這個佈局的實現思路是,先把最重要的身體部分放好,然後再將翅膀移動到適當的地方。因此請容許我給這個佈局實現取名爲雙飛翼佈局(Flying Swing Layout).
就如上圖中的鳥有各種姿勢一樣,利用雙飛翼佈局,我們也可以實現各種佈局。這裏有個嘗試頁面,利用雙飛翼,實現了一套柵格化佈局系統

優點

  • 實現了內容與佈局的分離,即Eric提到的Any-Order Columns.
  • main部分是自適應寬度的,很容易在定寬佈局和流體佈局中切換。
  • 任何一欄都可以是最高欄,不會出問題。
  • 需要的hack非常少(就一個針對ie6的清除浮動hack:_zoom: 1;)
  • 在瀏覽器上的兼容性非常好,IE5.5以上都支持。

不足

  • main需要添加一個額外的包裹層。
  • 等待你的發現與反饋。

雙飛翼的佈局非常靈活,只要調整css代碼就可以搞定一切。最近在一個論壇項目中準備嘗試使用這個佈局。希望大家有更好的佈局方法一定要多多分享。

<html><head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">    
<title>PE Layout Example 4</title>
<style type="text/css">
    body { font: 22px/1.5 Georgia, sans-serif; color: #333; min-width: 500px; }
    a { outline: none; text-decoration: none; color: #8CD0D3; }
    a:visited { color: #8CD0D3; }
    pre { font: 12px 'Courier New', monospace; }

    .main { background: #D6D6D6; }
    .sub { background: #E79F6D; }
    .extra { background: #77BBDD; }

    #hd, #ft {
        height: 50px;
        background: #666; color: #eee;
        text-align: center;
    }
    #ft { height: 40px; }

    /* core layout css */
    .main {
        float: left;
        width: 100%;
    }
    .sub {
        float: left;
        width: 190px;
        margin-left: -100%;
    }
    .extra {
        float: left;
        width: 230px;
        margin-left: -230px;
    }
    .main, .sub, .extra {
        padding-bottom: 5000px;
        margin-bottom: -5000px;
    }

    .main-wrap {
        margin: 0 230px 0 190px;
    }
    

    #bd { overflow: hidden; _zoom: 1; }

</style>
</head>
<body>

<div id="page2">
    <div id="hd">
        <p>Header</p>
    </div>
    <div id="bd">
        <div class="main">
            <div class="main-wrap">
                <p>Main</p>
                <pre>.main {
    float: left;
    width: 100%;
}
.main-wrap {
    margin: 0 230px 0 190px;
}
                </pre>
            </div>
        </div>
        <div class="sub">
            <p>Sub</p>
            <pre>.sub {
    float: left;
    width: 190px;
    margin-left: -100%;
}
            </pre>
        </div>
        <div class="extra">
            <p>Extra</p>
            <pre>.extra {
    float: left;
    width: 230px;
    margin-left: -230px;
}
            </pre>
        </div>
    </div>
    <div id="ft">
        <p>Footer</p>
    </div>
</div>



</body></html>
轉載:http://www.cnblogs.com/cobby/archive/2012/05/09/2491812.html

發佈了101 篇原創文章 · 獲贊 14 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章