「前端面試題系列2」如何實現一個聖盃佈局?

Micherwa發表於2019-01-14

前言

最近,有個朋友向我訴苦說,面試的時候突然被問到了如何實現佈局和原理,有點懵。之前JavaScript的部分回答得挺好的,偏偏在這裡翻船了,完全沒有思路,後面的面試狀態一落千丈。結局也如他所料,沒有被錄取。

我給這個朋友做了解答之後,回家整理出此文。希望其他小夥伴面試中,再被問及聖盃佈局的時候,可以沉著作答。

本文將介紹經典佈局——聖盃佈局的原理以及兩種實現方法:浮動和flex。

什麼是聖盃佈局?

聖盃佈局是為了討論「三欄液態佈局」的實現,最早的完美實現是由 Matthew Levine 在 2006 年寫的一篇文章 《In Search of the Holy Grail》 ,它主要講述了網頁中關於最佳聖盃的實現方法。

它有以下幾點要求:

  • 上部(header)和下部(footer)各自佔領螢幕所有寬度。
  • 上下部之間的部分(container)是一個三欄佈局。
  • 三欄佈局兩側寬度不變,中間部分自動填充整個區域。
  • 中間部分的高度是三欄中最高的區域的高度。

接下來,將會介紹兩種實現的方法。它們的最終效果都一樣,如下圖:

「前端面試題系列2」如何實現一個聖盃佈局?

實現方法1:浮動

先上程式碼:

<div class="header">
    <h4>header</h4>
</div>

<div class="container">
    <div class="middle">
        <h4>middle</h4>
        <p>middle-content</p>
    </div>
    
    <div class="left">
        <h4>left</h4>
        <p>left-content</p>
    </div>
    
    <div class="right">
        <h4>right</h4>
        <p>right-content</p>
    </div>
</div>

<div class="footer">
    <h4>footer</h4>
</div>
複製程式碼
.header, .footer {
    border: 1px solid #333;
    background: #ccc;
    text-align: center;
}
.footer {
    clear: both;
}

.container {
    padding:0 220px 0 200px;
    overflow: hidden;
}
.left, .middle, .right {
    position: relative;
    float: left;
    min-height: 130px;
}
.middle {
   width: 100%;
    background: blue;
}
.left {
    margin-left: -100%;
    left: -200px;
    width: 200px;
    background: red;
}
.right {
    margin-left: -220px;
    right: -220px;
    width: 220px;
    background: green;
}
複製程式碼

解析一下思路:

  • 在html中,先定義好header和footer的樣式,使之橫向撐滿。
  • 在container中的三列設為浮動和相對定位(後面會用到),middle要放在最前面,footer清除浮動。
  • 三列的左右兩列分別定寬200px和220px,中間部分middle設定100%撐滿
  • 這樣因為浮動的關係,middle會佔據整個container,左右兩塊區域被擠下去了
  • 接下來設定left的 margin-left: -100%;,讓left回到上一行最左側
  • 但這會把middle給遮住了,所以這時給外層的container設定 padding: 0 220px 0 200px;,給left空出位置
  • 這時left並沒有在最左側,因為之前已經設定過相對定位,所以通過 left: -200px; 把left拉回最左側
  • 同樣的,對於right區域,設定 margin-left: -220px; 把right拉回第一行
  • 這時右側空出了220px的空間,所以最後設定 `right: -220px;##把right區域拉到最右側就行了。

實現方法2:flex彈性盒子

用彈性盒子來實現聖盃佈局特別簡單,只需要把中間的部分用flex佈局即可。

<div class="header">
    <h4>header</h4>
</div>

<div class="container">
    <div class="left">
        <h4>left</h4>
        <p>left-content</p>
    </div>
    
    <div class="middle">
        <h4>middle</h4>
        <p>middle-content</p>
    </div>
    
    <div class="right">
        <h4>right</h4>
        <p>right-content</p>
    </div>
</div>

<div class="footer">
    <h4>footer</h4>
</div>
複製程式碼
.header, .footer {
    border: 1px solid #333;
    background: #ccc;
    text-align: center;
}

.container {
    display: flex;
}
.left {
    width: 200px;
    background: red;
}
.middle {
    flex: 1;
    background: blue;
}
.right {
    width: 220px;
    background: green;
}
複製程式碼

解析一下思路:

  • header和footer同上面一樣,橫向撐滿。footer不用再清浮動了
  • container中的left、middle、right依次排布即可,不用特意將middle放置到最前面
  • 給container設定彈性佈局 display: flex;
  • left和right區域定寬,middle設定 flex: 1; 即可

總結

總的來說,彈性佈局是最適合實現聖盃佈局的方法了,相較浮動,彈性佈局的結構更清楚,更好理解,也不用擔心移動端的適配問題。

而浮動的方法,在面試中可能會遇到,主要考察對佈局的理解能力。所以,建議大家可以把浮動的例子拷貝下來,自行模擬一把,以便加深理解。

更新(2019-01-17)

感謝 @沉末 提出的建議,這裡補充一下。

聖盃佈局的另一個核心:重要的內容先載入。就像本文中的 middle 在前,left 和 right 在後。

PS:歡迎關注我的公眾號 “超哥前端小棧”,交流更多的想法與技術。

「前端面試題系列2」如何實現一個聖盃佈局?

相關文章