三欄式布局(所謂的聖杯和雙飛翼)


前面的話

  常常聽說聖杯布局和雙飛翼布局,以為是兩個很高級的語匯。但實際上,他們只是三欄式布局的兩種布局方法而已。本文將介紹三欄式布局的4種思路

 

float

【1】聖杯布局

  聖杯布局使用float、負margin和relative,不需要添加額外標簽。.main元素設置padding,為兩側定寬元素留出位置。內容元素設置100%寬度,占據中間位置。而兩側定寬元素通過設置負margin和relative的偏移屬性配合,到達相應位置

  缺點: 並沒有實現等高布局;使用了相對定位,擴展性不好

<style>
body,p{margin: 0;}
.top,.bottom{
    height: 30px;
}
.middle{
    padding: 0 120px;
    overflow: hidden;
}
.main{
    width: 100%;
    float: left;
}
.left,.right{
    float: left;
    width: 100px;    
    position: relative;
}
.left{
    margin-left: -100%;
    left: -120px;
}
.right{
    margin-left: -100px;
    right: -120px;
}
</style>
<div class="parent" id="parent" style="background-color: lightgrey;">
    <div class="top" style="background-color: lightblue;">
        <p>top</p>
    </div>  
    <div class="middle" style="background-color: pink;">
        <div class="main" style="background-color: lightcoral;">
            <p>main</p>
            <p>main</p>
        </div>
        <div class="left" style="background-color: orange;">
            <p>left</p>
        </div>
        <div class="right" style="background-color: lightsalmon;">
               <p>right</p>
        </div>
    </div>          
    <div class="bottom" style="background-color: lightgreen;">
        <p>bottom</p>
    </div>        
</div>

【2】雙飛翼布局

  雙飛翼布局在聖杯布局的基礎上,通過為.main元素外添加一層div結構,不使用相對定位。在.main元素上設置margin。兩側的定寬列通過margin來占據.main元素的margin區域

  缺點: 並沒有實現等高布局,增加了html結構

<style>
body,p{margin: 0;}
.top,.bottom{height: 30px;}
.middle{overflow: hidden;}
.mainWrap{
    width: 100%;
    float: left;
}
.main{margin: 0 120px;}
.left,.right{
    float: left;
    width: 100px;    
}
.left{margin-left: -100%;}
.right{margin-left: -100px;}
</style>
<div class="parent" id="parent" style="background-color: lightgrey;">
    <div class="top" style="background-color: lightblue;">
        <p>top</p>
    </div>  
    <div class="middle" style="background-color: pink;">
        <div class="mainWrap">
            <div class="main" style="background-color: lightcoral;">
                <p>main</p>
                <p>main</p>
            </div>            
        </div>
        <div class="left" style="background-color: orange;">
            <p>left</p>
        </div>
        <div class="right" style="background-color: lightsalmon;">
               <p>right</p>
        </div>
    </div>          
    <div class="bottom" style="background-color: lightgreen;">
        <p>bottom</p>
    </div>        
</div>

【3】float + box-sizing + background-clip

  .main元素的border區域為兩側定寬列的所在區域,實現偽等高效果;設置.main的padding和background-clip來實現元素間隔。兩側元素通過負margin調整到.main元素的border區域

  缺點: 兼容性不好

<style>
body,p{margin: 0;}
.top,.bottom{height: 30px;}
.middle{overflow: hidden;}
.main{
    float: left;
    width: 100%;
    border-left: 100px solid lightgrey;
    border-right: 100px solid lightgrey;
    padding: 0 20px;
    background-clip: content-box;
    box-sizing: border-box;
}
.left,.right{
    float: left;
    width: 100px;    
}
.left{margin-left: -100%;}
.right{margin-left: -100px;}
</style>
<div class="parent" id="parent" style="background-color: lightgrey;">
    <div class="top" style="background-color: lightblue;">
        <p>top</p>
    </div>  
    <div class="middle" style="background-color: pink;">
        <div class="main" style="background-color: lightcoral;">
            <p>main</p>
            <p>main</p>
        </div>            
        <div class="left" >
            <p>left</p>
        </div>
        <div class="right" >
               <p>right</p>
        </div>
    </div>          
    <div class="bottom" style="background-color: lightgreen;">
        <p>bottom</p>
    </div>        
</div>

 

absolute

  設置子元素的top:0;bottom:0;使得所有子元素的高度都和父元素的高度相同,實現等高效果

  缺點: 需要為.middle元素設置高度,擴展性較差

<style>
body,p{margin: 0;}
.top,.bottom{height: 30px;}
.middle{
    position: relative;
    height: 40px;
}
.left,.right,.main{
    position: absolute;
    top: 0;
    bottom: 0;
}
.left{width: 100px;}
.right{
    width: 100px;
    right: 0;
}
.main{
    left: 120px;
    right: 120px;
}
</style>
<div class="parent" id="parent" style="background-color: lightgrey;">
    <div class="top" style="background-color: lightblue;">
        <p>top</p>
    </div>  
    <div class="middle" style="background-color: pink;">
        <div class="main" style="background-color: lightcoral;">
            <p>main</p>
            <p>main</p>
        </div>              
        <div class="left" style="background-color: lightseagreen;" >
            <p>left</p>
        </div>
        <div class="right" style="background-color: lightcyan;" >
               <p>right</p>
        </div>
    </div>          
    <div class="bottom" style="background-color: lightgreen;">
        <p>bottom</p>
    </div>        
</div>

 

flex

  flex中的伸縮項目默認都拉伸為父元素的高度,可實現等高效果。通過改變伸縮項目的order,可以實現元素順序調換的效果

  缺點: 兼容性不高

<style>
body,p{margin: 0;}
.top,.bottom{height: 30px;}
.middle{display: flex;}
.left,.right{width: 100px;}
.right{order: 2;}
.main{
    order: 1;
    flex: 1;
    margin: 0 20px;
}
</style>
<div class="parent" id="parent" style="background-color: lightgrey;">
    <div class="top" style="background-color: lightblue;">
        <p>top</p>
    </div>  
    <div class="middle" style="background-color: pink;">
        <div class="main" style="background-color: lightcoral;">
            <p>main</p>
            <p>main</p>
        </div>              
        <div class="left" style="background-color: lightseagreen;" >
            <p>left</p>
        </div>
        <div class="right" style="background-color: lightcyan;" >
               <p>right</p>
        </div>
    </div>          
    <div class="bottom" style="background-color: lightgreen;">
        <p>bottom</p>
    </div>        
</div>

 

grid

<style>
body,p{margin: 0;}
.top,.bottom{height: 30px;}
.middle{display:grid;grid-template-columns:100px 1fr 100px;grid-gap:20px;}
.main{grid-area:1/2/2/3;}
</style>
<div class="parent" id="parent" style="background-color: lightgrey;">
    <div class="top" style="background-color: lightblue;">
        <p>top</p>
    </div>  
    <div class="middle" style="background-color: pink;">
        <div class="main" style="background-color: lightcoral;">
            <p>main</p>
            <p>main</p>
        </div>              
        <div class="left" style="background-color: lightseagreen;" >
            <p>left</p>
        </div>
        <div class="right" style="background-color: lightcyan;" >
               <p>right</p>
        </div>
    </div>          
    <div class="bottom" style="background-color: lightgreen;">
        <p>bottom</p>
    </div>        
</div>

 

總結

  由於限定了主要內容元素在html結構中於前面,通過css樣式改變將其位置調到中間的前提,所以思路並不是很多。float浮動流的元素可以通過負margin調換位置;absolute絕對定位流的元素可以通過偏移屬性調換位置;flex彈性盒模型可以通過order屬性調換位置;grid通過grid-area調換位置。而處於正常流中的元素除了使用relative外,使用負margin是無法調換位置的,所以table、inline-block等布局方式在此前提下不是很實用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM