1. 程式人生 > >聖盃佈局和雙飛翼佈局的原理探究

聖盃佈局和雙飛翼佈局的原理探究

浮動佈局並不是再是流行的佈局方式,不過基於浮動的經典佈局還是經常出現在前端面試中,聖盃佈局和雙飛翼佈局就是其中常考核的知識點。聖盃佈局和雙飛翼佈局都是前端中三列設計佈局方式,要求主要中間內容優先渲染,左右內容寬度固定,中間主要內容寬度自適應排布。聖盃佈局和雙飛翼佈局都沒有使用絕對定位,而是應用浮動、負外邊距以及相對定位這幾個核心知識點來實現。

聖盃佈局

聖盃佈局是讓左右固定欄和中間自適應的主內容欄處於同一容器包裹中,容器(#container)設定padding-left、padding-right值,其中padding-left值與左側欄(#left)的寬度值相等,padding-right值與右側欄(#right)的寬度值相等,中間自適應欄的寬度設定為100%,讓中間自適應欄的寬度與容器的內容盒寬度相等。通過定位設定讓左側欄(#left)在中間欄(# center)左側恰好容納容器padding-left的空間,右側欄(# right)在中間欄(# center)右側恰好容納容器padding-right的空間。

聖盃佈局的主要框架草圖如下所示:

聖盃佈局的HTML架構程式碼:

    <div id='header'>#header</div>
    <div id='container'>
        <div id='center'>#center</div>
        <div id='left'>#left</div>
        <div id='right'>#right</div>
    </div>
    <div id='footer'>#footer</div>

聖盃佈局的CSS程式碼:

      * {
            border-width: 0;
        }

        body {
            min-width: 350px;
        }

        #header,
        #footer {
            height: 100px;
            background: #ccc;
        }

        #container {
            padding-left: 200px;
            padding-right: 150px;
box-sizing:border-box;
             min-width:550px;
 
        }

        #center {
            float: left;
            width: 100%;
            background: #f96d9f;
        }

        #left {
            width: 200px;
            float: left;
            margin-left: -100%;
            position: relative;
            left: -200px;
            background: aqua;
        }

        #right {
            width: 150px;
            float: left;
            margin-right: -150px;
            background: yellowgreen;
        }

        #left,
        #right,
        #center {
            min-height: 100px;
        }

        /* 外圍樣式 */
        #header,
        #footer,
        #center,
        #left,
        #right {
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Source Code Pro';
            font-size: 20px;
        }
        #footer {
            clear: both;
        }

  

外圍樣式是為了文字美化居中而設定的程式碼,並非聖盃佈局CSS程式碼主體部分。聖盃佈局的程式碼的核心難點是如何不通過絕對定位來讓文件流中後面的元素位於前面元素,這裡運用了浮動、負外邊距以及相對定位來實現。

這是左側欄的核心程式碼:

        #left {
            width: 200px;
            float: left;
            margin-left: -100%;
            position: relative;
            left: -200px;
        }

  

這裡margin-left: -100%;由於負外邊距-100%計算值是宿主元素內容盒模型的寬度,其寬度大於左側欄寬度200px。所以浮動的左側欄通過負外邊距上浮到上層,以中間欄(#center)的右側外邊緣為基準線,向左側移動相當於宿主元素內容盒模型寬度的距離,恰好位於中間欄(#center)的左側,佔據容器(#container)padding-left的位置。

        #right {
            width: 150px;
            float: left;
            margin-right: -150px;
        }

  

當左側欄(#left)由於負外邊距上移後,右側欄(#right)由於左浮動位於容器(#container)的內側左邊緣。同樣負外邊距 margin-right: -150px; 設定令右側欄(#right)上移,同樣是以中間欄(#center)的右側外邊緣為基準線作為右側欄(#right)的最左側邊接觸。

這樣通過對浮動元素左、右負邊距的設定,令原本位於中間欄(#center)下方的浮動元素左側欄(#left)、右側欄(#right)上移是聖盃佈局的理解難點。

聖盃佈局的最小尺寸問題

聖盃佈局是基於左側欄(#left)負外邊距 margin-left: -100%;設定來實現的,但是左側欄上移有個前提條件,就是margin-left的負值與左側欄(#left)自身的內容寬度相加後的值不大於上一行剩餘空間,才可以實現左側欄(#left)上移。這裡中間欄(#center)完全佔據上一行剩餘空間,margin-left的負值與左側欄(#left)自身的內容寬度相加後的值不大於0才可以上移,否則左側欄(#left)仍然停留在第二行,就無法實現聖盃佈局目的。所以中間欄(#center)的寬度需要不小於左側欄(#left)寬度,才能滿足聖盃佈局的實現。

聖盃佈局的最小尺寸計算:若左側欄(#left)的寬度為X,右側欄的寬度為Y,那麼容器(#container)最小尺寸計算:2X+Y。

在上述例項中,聖盃佈局最小尺寸為2x200+150=550px。所以容器(#container)需要設定最小尺寸min-width:550px;,同時這裡550px是容器邊框盒的尺寸,為了避免採用預設內容盒尺寸進行轉換計算,就採用設定:box-sizing:border-box;。

        #container {
            padding-left: 200px;
            padding-right: 150px;
box-sizing:border-box;
             min-width:550px;
 
        }

  

雙飛翼佈局

雙飛翼佈局同樣未採用絕對定位,它是在聖盃佈局的基礎上進行改進的佈局形式。雙飛翼佈局佈局中左側欄(#left)、右側欄(#right)、中間欄(#center)都是兄弟元素。通過中間欄(#center)的內部元素(# inner)設定左右外邊距為左側欄(#left)、右側欄(#right)預留位置空間,其餘通過負邊距設定令浮動元素上移的設定原理相同。

雙飛翼佈局的結構示意圖:

雙飛翼佈局HTML程式碼:

    <div id='header'>#header</div>
    <div id='center'> 
        <div id='inner'>center</div>
    </div>
    <div id='left'>#left</div>
    <div id='right'>#right</div>
    <div id='footer'>#footer</div>

  

雙飛翼佈局CSS程式碼:

    * {
            border-width: 0;
        }

        body {
            min-width: 350px;
        }

        #header,
        #footer {
            height: 100px;
            background: #ccc;
        }

        #container {
            padding-left: 200px;
            padding-right: 150px;
            box-sizing: border-box;
            min-width: 550px;
        }

        #center {  
            float: left;
            width: 100%;
            background: #f96d9f;
        }
        #inner{
            margin-left:200px;
            margin-right:150px;
        }

        #left {
            width: 200px;
            float: left;
            margin-left: -100%;
            background: aqua;
        }

        #right {
            width: 150px;
            float: left;
            margin-left: -150px;
            background: yellowgreen;
        }

        #left,
        #right,
        #center {
            min-height: 100px;
        }

        /* 外圍樣式 */
        #header,
        #footer,
        #center,
        #inner,
        #left,
        #right {
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Source Code Pro';
            font-size: 20px;
        }

        #footer {
            clear: both;
        }

  

雙飛翼佈局與聖盃佈局相比,沒有最小值限制,比其佈局適應寬度範圍更廣泛。