淺談CSS三欄佈局(包括雙飛翼佈局和聖盃佈局)

CSS三欄佈局

寫在正文以前

  • PS:真想說一句,寫博客,真香!(雖然我知道根本沒人看)

三欄佈局的概念

  • 三欄佈局概念聽起來很簡單,就是讓三列從左到右排列,左邊區域和右邊區域定寬,而中間內容區域寬度自適應。就像下圖這樣:
    在這裏插入圖片描述
    固然要注意:咱們這裏所說的中間部分寬度自適應就是隨着屏幕的大小改變而本身適應的過程。這也是三欄佈局產生的緣由。簡單的來講呢,就是兩邊欄固定,中間欄自適應。這種佈局很古老,但依舊很是經典,由於有好多地方都存在它的身影,包括一些大廠面試的時候仍是很喜歡問這個問題的。

三欄佈局的具體實現及原理分析

第一種:浮動三欄佈局

  • 先給出html部分代碼:
    <div class="wrapper">
      <div class="left">left</div>
      <div class="right">right</div>
      <div class="content">content</div>
    </div>
    複製代碼
  • 下面是css部分代碼:
    .wrapper {
         text-align: center;
         color: #fff;
         overflow: hidden;/* 這裏清除浮動,由於觸發了BFC */
         line-height: 200px;
    }
    
    .left {
         float: left;
         width: 200px;
         height: 200px;
         background-color: red;
    }
    
    .right {
         float: right;
         width: 200px;
         height: 200px;
         background-color: blue;
    }
    
    .content {
         height: 200px;
         margin: 0 200px;
         background-color: lime;
    }
    複製代碼
    • 效果以下:
      在這裏插入圖片描述
    • 那麼這種方法是很簡單的,相信各位瞬間就能看懂。不過也有一些須要注意的細節點:
    1. 這種方法裏面,DOM節點中的 left, right, content 這三個塊是不能換順序的,也就是說這種方法的缺點很明顯:瀏覽器自上而下解析代碼渲染DOM樹,那麼content內容區域不能被優先渲染出來。
    2. 至於爲何不能換順序,你們也很清楚:由於咱們要讓他們在一行內展現,那麼必須讓左右這兩個塊漂浮起來不佔原來的位置了,才能讓content區域躋身而入,固然浮動的問題我就不須要再多說。。。
    • 因此總結起來就是:能夠實現效果,可是不完美,由於不能優先渲染content區域

第二種:定位三欄佈局

  • html代碼:
    <div class="wrapper">
    	<div class="content">content</div>
     	<div class="left">left</div>
    	<div class="right">right</div>
    </div>
    複製代碼
  • css代碼:
    .wrapper {
      width: 100%;
      line-height: 200px;
      color: #fffdef;
      text-align: center;
      position: relative;
    }
    
    .content {
      margin: 0 200px;
      background-color: lime;
      height: 200px;
    }
    
    .left {
      position: absolute;
      top: 0;
      left: 0;
      width: 200px;
      height: 200px;
      background-color: red;
    }
    
    .right {
      position: absolute;
      top: 0;
      right: 0;
      width: 200px;
      height: 200px;
      background-color: blue;
    }
    複製代碼
  • 效果以下:
    在這裏插入圖片描述
  • 好吧,其實效果跟前面是同樣的,這種方法也相對比較簡單,實現原理和前面的浮動實現也差很少。不過他的盒子高度靠content去撐起來,而它的優勢就是content此次能夠被優先渲染出來了,由於它被排在了第一位。真是可喜可賀!

第三種:用BFC原理作三欄佈局

  • BFC特性有一點是觸發了BFC的盒子不會和浮動的盒子重疊,也就是說觸發BFC的盒子不會被浮動的盒子蓋住,那麼問題解決一半了,咱們看一下具體的實現:
  • html代碼:
    <div class="wrapper">
    	<div class="left">left</div>
    	<div class="right">right</div>
    	<div class="content">content</div>
      </div>
    複製代碼
  • css代碼:
    .wrapper {
      text-align: center;
      color: #fffdef;
      width: 100%;
      line-height: 200px;
      font-size: 40px;
    }
    
    .left {
      float: left;
      width: 200px;
      height: 200px;
      background-color: red;
    }
    
    .right {
      float: right;
      width: 200px;
      height: 200px;
      background-color: blue;
    }
    
    .content {
      height: 200px;
      background-color: lime;
      /* 這會造成BFC區域,不會與浮動的元素重疊 */
      overflow: hidden;
    }
    複製代碼
    效果圖以下:
    在這裏插入圖片描述
    好吧,效果又是同樣的,不過本着僞裝本身認真的原則又上傳了一下。。。不過這個多了一個 overflow: hidden,沒有了 margin: 0 200px 了呢。在這裏是這樣的,overflow: hidden 是會觸發BFC的,那麼此時content區域就是一個BFC區域了,那麼他不會被浮動的元素蓋住,因此,它的content的寬度就是從不被left蓋住的位置開始到被right蓋住的區域以前這段寬度,不用再像方法一那樣把margin給左右的值空出來這個區域,因此也造成了寬度自適應,搞定!不過它的缺點也顯而易見,和方法一的同樣:不能優先渲染content區域。

方法四:聖盃佈局(重點)

  • 咱們終於等到了重頭戲之一:聖盃佈局。其實所謂聖盃佈局只不過比起三欄佈局多了一個需求:要求content區域優先渲染。那你們可能比較疑惑:爲啥叫聖盃佈局?由於它長得像聖盃啊,看下圖:
    在這裏插入圖片描述
    聖盃的兩隻手就像佈局中的左邊欄和右邊欄同樣,杯子主體就像content內容區域同樣。具體的實現以下:
  • html代碼:
    <div class="main clearfix">
    	<div class="content">content</div>
    	<aside class="sidebar-left">left</aside>
    	<aside class="sidebar-right">right</aside>
    </div>
    複製代碼
  • css代碼:
    .main {
      padding: 0 200px 0 150px;
    }
    
    body {
      color: #fff;
      font-size: 40px;
      background-color: #666;
      font-family: Arial;
      text-align: center;
    }
    
    .content,
    .sidebar-left,
    .sidebar-right {
      float: left;
      position: relative;
      height: 400px;
      line-height: 400px;
    }
    
    .content {
      width: 100%;
      background-color: #f5c531;
    }
    
    .sidebar-left {
      width: 150px;
      background-color: #a0c263;
      margin-left: -100%;
      left: -150px;
    }
    
    .sidebar-right {
      background-color: #a0c263;
      width: 200px;
      margin-right: -200px;
      /*margin-left: -200px;*/
      /*right: -200px;*/
    }
    複製代碼
    看下效果圖:
    在這裏插入圖片描述
    左邊欄150px,右邊欄200px,中間content自適應寬度,完美解決,這就是所說的聖盃佈局,那麼這個原理是什麼呢?其實就是基於兩條:1. 浮動 2. margin負值。 咱們如今看代碼:
    1. 首先給他們的父級元素main一個左padding值和右padding值,留出來給左右邊欄的地方。
    2. 給這三個元素浮動起來,而後直接給content元素寬度100%,寬度全都給content了,那left和right就會掉下去。
    3. 先給content寬度100%的時候,確實left和right是要掉下去的,就像下面這樣:
      在這裏插入圖片描述
      那咋把left和right這兩個煩人的玩意弄到他們的位置上呢?這裏就要用到margin的負值,結合浮動使用,那麼咱們知道浮動起來的幾個元素會拍成一行內,而寬度不夠纔會掉下去,這裏就是這種狀況,可是若是我給left塊一個margin-left負值到一個界限,他就會回到上一行,由於它會向左走,左邊沒地方了,並且給的是margin值,那麼他就會貼到上一行,由於他們是一塊兒浮動的,上一行一樣可以接納他(這裏我這樣想:好比說寬度足夠的時候,那麼我給它margin-left負值,它不是同樣要往左走嗎?同樣的道理,它在下一行往左走到沒地方走的時候天然就回到了上一行了,由於他們是一塊兒浮動的),這裏我給了它margin-left: -100%,因此它就到了這個位置
      在這裏插入圖片描述
      由於margin的百分比的值是父級盒子寬度的百分比,給了-100%,天然向左走一個父級的寬度,就到了這,那麼這個位置不是咱們想要的,咱們要他在左邊的空出來的地方待着,那很簡單:left: -150px搞定:
      在這裏插入圖片描述
      如今就差right沒搞定了,這個其實很簡單,只須要一句代碼:margin-right: -200px搞定:
      在這裏插入圖片描述
      其實這裏能夠理解爲:原本他就應該在上面,可是因爲寬度不夠,無奈被擠下來了,可是如今我只要給margin-right一個負值(這個值大小要超過自身的寬度)他就會上去,繼續被接納,(這個值若是給的沒有自身寬度大,那麼就至關於不被接納,還要被排斥下來)因此正好排在了空缺的地方。 注意看我給right的代碼裏面最後兩句註釋上的代碼,若是用這兩句,能夠達到和上面一樣的效果,原理也相同:先給一個margin-left: -200px(正好給200px的話就是正好貼在在父級盒子的最右邊,由於正好剛剛能上來,若是再多給點值還會再往左走,可是這裏不須要的,我只是在儘可能去把這個原理闡述明白),被上面接納,來到了它的父級盒子的貼着最右邊:
      在這裏插入圖片描述
      而後再給一個right: -200px讓它向右走200px,搞定!這個其實就和我給left盒子的方法原理同樣。最終效果圖:
      在這裏插入圖片描述

方法五:雙飛翼佈局(重點)

  • 雙飛翼佈局實際上是根據聖盃佈局演化出來的一種佈局。具體實現以下:
  • html代碼:
    <div class="main clearfix">
        <div class="content-wrapper">
            <div class="content">content</div>
        </div>
        <aside class="sidebar-left">left</aside>
        <aside class="sidebar-right">right</aside>
    </div>
    複製代碼
  • css代碼:
    body {
      color: #fff;
      font-size: 40px;
      font-family: Arial;
      background-color: #666;
      text-align: center;
    }
    
    .sidebar-left,
    .sidebar-right {
      float: left;
      height: 400px;
      line-height: 400px;
    }
    
    .content-wrapper {
      width: 100%;
      float: left;
    }
    
    .content {
      margin: 0 200px 0 150px;
      background-color: #f5c531;
      height: 400px;
      line-height: 400px;
    }
    
    .sidebar-left {
      width: 150px;
      background-color: #a0c263;
      margin-left: -100%;
    }
    
    .sidebar-right {
      background-color: #a0c263;
      width: 200px;
      margin-left: -200px;
    }
    複製代碼
    老規矩,用圖說話:
    在這裏插入圖片描述
    其實咱們能夠看到,這裏面和聖盃佈局差異不是很大,我簡單說一下里面的細節差距吧:
    1. 這裏面left直接給margin-left: -100%就能到想要的位置,爲何呢?由於要注意一點,在這裏,left父級盒子是寬度100%的,再也不是聖盃佈局裏面的留出來左右padding值的父級自適應寬度的盒子,這裏面使用content盒子的左右margin值留出來的定寬,因此直接就能把left盒子定到想要的位置
    2. 那麼同理,right盒子也是由於這樣,因此直接margin-left: -200px正好貼到父級盒子最右邊,就能到想要的位置了。

方法六:Flex三欄佈局

  • 利用Flex彈性盒子能夠很輕鬆的完成三欄佈局,而且可以達到content優先渲染的要求。
  • html結構:
<div class="flex-box">
  <div class="flex-content flex-item">我是內容</div>
  <div class="flex-left flex-item">我是左邊欄</div>
  <div class="flex-right flex-item">我是右邊欄</div>
</div>
複製代碼
  • css結構:
body {
      color: #fff;
      font-size: 30px;
      text-align: center;
    }

    .flex-box {
      display: flex;
      line-height: 600px;
    }

    .flex-left {
      width: 200px;
      height: 600px;
      background-color: lime;
      order: 0;
    }

    .flex-content {
      order: 1;
      width: 100%;
      background-color: purple;
    }

    .flex-right {
      width: 200px;
      height: 600px;
      background-color: blue;
      order: 2;
    }
複製代碼

效果圖就不貼了。。。太累了。這裏主要利用flex佈局中,給子元素添加的屬性order,這個order屬性意爲在主軸方向的排列中顯示的優先級,值越小,優先級越高,因此能夠達到HTML結構中content最早渲染,卻又能讓其在中間部分顯示的效果。css

總結

就寫這6種三欄佈局的方式吧,都是很簡單的。默默地喝掉最後一口咖啡,繼續奮戰。html

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息