面試之CSS篇 - 實現三欄佈局的延伸

不吃早餐發表於2019-03-11

本文探討下面試常談問題之三欄佈局,說到三欄佈局,可能大家心中至少也可以想出 2-3 種答案,這些谷歌就一大堆解決方案的題目為什麼還要拿出來談談呢?

這裡主要是考察掌握知識度的延伸,比如你能答出幾種? => 這幾種方式的優缺點在哪? => 最佳方案是哪個以及如何解決這些缺點...

這些可以考驗到你是否背題亦或者真正掌握到這些知識點。

高度已知,實現三欄佈局,左右 300px 中間自適應。

在實現前先重置一下預設的樣式

* {
  margin: 0;
  padding: 0;
}
.layout {
  margin-top: 20px;
}
.layout article div {
  min-height: 100px;
}
複製程式碼

浮動佈局解決方案

左右浮動,給寬度,這樣就實現了,是不是很簡單~但是也存在一些缺點,後邊會講到。

<section class="layout float">
  <style>
    .layout.float .left {
      float: left;
      width: 300px;
      background: red;
    }
    .layout.float .right {
      float: right;
      width: 300px;
      background: blue;
    }
    .layout.float .center {
      background: yellow;
    }
  </style>
  <article class="left-right-center">
    <div class="left"></div>
    <div class="right"></div>
    <div class="center">
      <h1>浮動解決方案</h1>
      1. 這是三欄佈局中間部分 2. 這是三欄佈局中間部分
    </div>
  </article>
</section>
複製程式碼

絕對定位佈局解決方案

left/center/right 均給絕對定位,左右給 300px,中間設定 left 300 right 300,也同樣實現這個佈局~

<!-- 絕對定位解決方案 -->
<section class="layout absoulute">
  <style>
    .layout.absoulute .left-center-right > div {
      position: absolute;
    }
    .layout.absoulute .left {
      left: 0;
      width: 300px;
      background: red;
    }
    .layout.absoulute .center {
      left: 300px;
      right: 300px;
      background: yellow;
    }
    .layout.absoulute .right {
      right: 0;
      width: 300px;
      background: blue;
    }
  </style>
  <article class="left-center-right">
    <div class="left"></div>
    <div class="center">
      <h1>絕對定位解決方案</h1>
      1. 這是三欄佈局中間部分 2. 這是三欄佈局中間部分
    </div>
    <div class="right"></div>
  </article>
</section>
複製程式碼

flex 佈局解決方案

父級 box 給 display: flex , 左右寬 300, 中間 flex : 1 ,flex 的靈活性也十分的好用 ~

<section class="layout flexbox">
  <style>
    .layout.flexbox {
      margin-top: 140px;
    }
    .layout.flexbox .left-center-right {
      display: flex;
    }
    .layout.flexbox .left {
      width: 300px;
      background: red;
    }
    .layout.flexbox .center {
      flex: 1;
      background: yellow;
    }
    .layout.flexbox .right {
      width: 300px;
      background: blue;
    }
  </style>
  <article class="left-center-right">
    <div class="left"></div>
    <div class="center">
      <h1>flex 佈局解決方案</h1>
      1. 這是三欄佈局中間部分 2. 這是三欄佈局中間部分
    </div>
    <div class="right"></div>
  </article>
</section>
複製程式碼

table 佈局解決方案

父級 display: table; 左中右 display: table-cell;

<section class="layout table">
  <style>
    .layout.table .left-center-right {
      width: 100%;
      display: table;
      height: 100px;
    }
    .layout.table .left-center-right > div {
      display: table-cell;
    }
    .layout.table .left {
      width: 300px;
      background: red;
    }
    .layout.table .center {
      background: yellow;
    }
    .layout.table .right {
      width: 300px;
      background: blue;
    }
  </style>
  <article class="left-center-right">
    <div class="left"></div>
    <div class="center">
      <h1>表格佈局解決方案</h1>
      1. 這是三欄佈局中間部分 2. 這是三欄佈局中間部分
    </div>
    <div class="right"></div>
  </article>
</section>
複製程式碼

grid 佈局解決方案

利用網格佈局 ,父級 display: grid; width: 100%; grid-template-columns: 300px auto 300px;

<section class="layout grid">
  <style>
    .layout.grid .left-center-right {
      display: grid;
      width: 100%;
      grid-template-rows: 100px;
      grid-template-columns: 300px auto 300px;
    }
    .layout.grid .left {
      background: red;
    }
    .layout.grid .center {
      background: yellow;
    }
    .layout.grid .right {
      background: blue;
    }
  </style>
  <article class="left-center-right">
    <div class="left"></div>
    <div class="center">
      <h1>grid佈局解決方案</h1>
      1. 這是三欄佈局中間部分 2. 這是三欄佈局中間部分
    </div>
    <div class="right"></div>
  </article>
</section>
複製程式碼

優缺點

上面我們給出 5 種解決方案,那麼面試官怎麼延伸這個問題呢? 如果把高度已知去掉,又該如何實現呢?那我們不止要考慮水平方向的,同時要考慮中間的高度問題。那我們剛寫的五種方案,哪些可以適用,哪些又不能適用了呢 這五種方案的相容性又如何,最優的解決方案又是哪個

  • float
    • 缺點:在於脫離文件流,意味著它下面的子元素也必須脫離文件流,還需要清除浮動帶來的影響,如果處理不好會帶來很多問題,這是它本身的侷限性
    • 優點:相容性很好,快捷,不容易出問題
  • absoulute
  • flex
    • 缺點:相容到 IE 8
    • float 、absoulute 出現之後出現的一種佈局方式,為了解決兩種佈局方式的不足。flex 佈局方案算是比較完美的一種,尤其是現在移動端基本都是使用 flex 佈局
  • table
    • 缺點:操作麻煩,對 seo 不友好 ,當某一個單元格高度超出的時候,那麼其他單元格也會跟著調整高度,有時候我們場景是不允許的
    • 優點:相容性很好,當 flex 解決不了的話,可以嘗試下用表格佈局
  • grid
    • 新出的網格佈局,通過 網格佈局可以做很多事情,程式碼精簡

當我們增加內容高度時會發生什麼事情呢?

面試之CSS篇 - 實現三欄佈局的延伸

很明顯

  • 浮動佈局文字自動排版到左邊了。(浮動的基本原理)
  • 絕對定位撐開中間部分的佈局,兩邊不變
  • flex 、table 佈局中內容撐開盒子的高度 - better
  • grid 佈局中內容中不撐開高度

關於浮動的問題有可以延伸出來,怎麼解決內容向左排版的 bug 呢?建立 BFC ,那麼 BFC 又是什麼呢,具體我會在下一篇文章介紹。

頁面佈局總結

  • 語義化掌握到位
  • 頁面佈局深刻理解
  • CSS 基礎知識紮實
  • 程式碼書寫規範

頁面佈局的變通

  • 三欄佈局
    • 左右寬固定,中間自適應
    • 上下高固定,中間自適應
  • 兩欄佈局
    • 左寬度固定,右自適應 或者相反
    • 上寬度固定,下自適應 或者相反

本文產生的程式碼 css - 實現三欄佈局篇

參考 https://www.bilibili.com/video/av31563161?p=3

相關文章