CSS 佈局經典問題初步整理

發表於2017-05-27

本文主要對 CSS 佈局中常見的經典問題進行簡單說明,並提供相關解決方案的參考連結,涉及到三欄式佈局,負 margin,清除浮動,居中佈局,響應式設計,Flexbox 佈局,等等。

CSS 基礎知識

下面幾個入門教程不錯:

CSS 定位問題

主要就是經典的絕對定位,相對定位問題。

三欄式佈局

涉及浮動和清除浮動,主要講解“聖盃”和“雙飛翼”兩種解決方法。這兩種方法實現的都是三欄佈局,兩邊的盒子寬度固定,中間盒子自適應,它們實現的效果是一樣的,差別在於其實現的思想。

聖盃佈局

聖盃:父盒子包含三個子盒子(左,中,右)

  • 中間盒子的寬度設定為 width: 100%; 獨佔一行;
  • 使用負邊距(均是 margin-left)把左右兩邊的盒子都拉上去和中間盒子同一行;
    • .left {margin-left:-100%;} 把左邊的盒子拉上去
    • .right {margin-left:-右邊盒子寬度px;} 把右邊的盒子拉上去
  • 父盒子設定左右的 padding 來為左右盒子留位置;
  • 對左右盒子使用相對佈局來佔據 padding 的空白,避免中間盒子的內容被左右盒子覆蓋;

雙飛翼佈局

雙飛翼:父盒子包含三個子盒子(左,中,右),中間的子盒子裡再加一個子盒子。

  • 中間盒子的寬度設定為 width: 100%; 獨佔一行;
  • 使用負邊距(均是 margin-left)把左右兩邊的盒子都拉上去和中間盒子同一行;
  • 在中間盒子裡面再新增一個 div,然後對這個 div 設定 margin-leftmargin-right來為左右盒子留位置;

聖盃和雙飛翼異同

聖盃佈局和雙飛翼佈局解決的問題是一樣的,都是兩邊定寬,中間自適應的三欄佈局,中間欄要在放在文件流前面以優先渲染。

  • 兩種方法基本思路都相同:首先讓中間盒子 100% 寬度佔滿同一高度的空間,在左右兩個盒子被擠出中間盒子所在區域時,使用 margin-left 的負值將左右兩個盒子拉回與中間盒子同一高度的空間。接下來進行一些調整避免中間盒子的內容被左右盒子遮擋。
  • 主要區別在於 如何使中間盒子的內容不被左右盒子遮擋
    • 聖盃佈局的方法:設定父盒子的 padding 值為左右盒子留出空位,再利用相對佈局對左右盒子調整位置佔據 padding 出來的空位;
    • 雙飛翼佈局的方法:在中間盒子裡再增加一個子盒子,直接設定這個子盒子的 margin 值來讓出空位,而不用再調整左右盒子。

簡單說起來就是雙飛翼佈局比聖盃佈局多建立了一個 div,但不用相對佈局了,少設定幾個屬性。

利用浮動實現

我自己使用浮動也實現了三欄式佈局:左邊盒子左浮動,右邊盒子右浮動,中間盒子利用 margin-leftmargin-right 來為左右盒子留位置,同時父盒子設定 overflow: auto; 來避免子盒子溢位。

三欄式佈局參考下面幾個連結:

三欄式佈局涉及到負 magin 和 清除浮動的問題。

負 magin

這裡引出了“負 margin”的問題:

簡單總結幾點:

  • 不使用 float 的話,負 margin 元素是不會破壞頁面的文件流。所以如果你使用負 margin 上移一個元素,所有跟隨的元素都會被上移(而 relative 定位的元素則不同,會保留原位置,影響文件流)。
  • 當 static 元素的 margin-top/margin-left 被賦予負值時,元素將被拉進指定的方向。
  • 如果你設定 margin-bottom/right 為負數,元素並不會如你所想的那樣向下/右移動,而是將後續的元素拖拉進來,覆蓋本來的元素。
  • 當元素不存在 width 屬性或者 width: auto 的時候,負 margin 會增加元素的寬度.
  • margin-top 為負值不會增加高度,只會產生向上位移;margin-bottom 為負值不會產生位移,會減少自身的供 CSS 讀取的高度,影響下方的元素位置;上下相鄰的元素兩者均為負時,效果不疊加,取負值更多的那個效果。

清除浮動

清除浮動主要是為了解決高度塌陷問題。而簡單的 clear: both 並不能解決這個問題,所以引出了許多解決方案。

各種解決方案在上面的連結裡有很詳細的說明了,這裡就不贅述了。大體分為兩類:

  • 其一,通過在浮動元素的末尾新增一個空元素,設定 clear: both 屬性,after 偽元素其實也是通過 content 在元素的後面生成了內容為一個點的塊級元素;
  • 其二,通過設定父元素 overflow 或者 display: table 屬性來閉合浮動

順便補充一句,clear float(例如 clear: left) 是對某個元素設定,以避免其某一邊有浮動元素,即對當前元素產生約束,約束的邊界為其他的浮動元素。對於已經浮動的元素,設定 clear float 是無效的。

居中佈局

  • Centering in CSS: A Complete Guide:非常全面的居中定位部落格,包括各種情況下的水平居中,垂直居中和水平垂直居中方案。有展示示例及相應的 HTML 和 CSS 程式碼

文章大致結構:

  • 水平居中
    • 對於行內元素(inline):text-align: center;
    • 對於塊級元素(block):設定寬度且 marigin-leftmargin-right 是設成 auto
    • 對於多個塊級元素:對父元素設定 text-align: center;,對子元素設定 display: inline-block;;或者使用 flex 佈局
  • 垂直居中
    • 對於行內元素(inline)
      • 單行:設定上下 pandding 相等;或者設定 line-heightheight 相等
      • 多行:設定上下 pandding 相等;或者設定 display: table-cell;vertical-align: middle;;或者使用 flex 佈局;或者使用偽元素
    • 對於塊級元素(block):下面前兩種方案,父元素需使用相對佈局
      • 已知高度:子元素使用絕對佈局 top: 50%;,再用負的 margin-top 把子元素往上拉一半的高度
      • 未知高度:子元素使用絕對佈局 position: absolute; top: 50%; transform: translateY(-50%);
      • 使用 Flexbox:選擇方向,justify-content: center;
  • 水平垂直居中
    • 定高定寬:先用絕對佈局 top: 50%; left: 50%;,再用和寬高的一半相等的負 margin 把子元素回拉
    • 高度和寬度未知:先用絕對佈局 top: 50%; left: 50%;,再設定 transform: translate(-50%, -50%);
    • 使用 Flexbox:justify-content: center; align-items: center;

響應式設計

“響應式設計(Responsive Design)” 是一種讓網站針對不同的瀏覽器和裝置“呈現”不同顯示效果的策略。

媒體查詢(Media Queries)是做此事所需的最強大的工具。

注: Responsive Web Design = RWD,Adaptive Web Design = AWD

RWD:

  • 採用 CSS 的 media query 技術
  • 流體佈局(fluid grids)
  • 自適應的圖片/視訊等資源素材

(為小、中、大螢幕做一些優化,目的是讓任何尺寸的螢幕空間都能得到充分利用)

AWD:

  • CSS media query 技術(僅針對有限幾種預設的螢幕尺寸設計)
  • 用 JavaScript 來操作 HTML 內容
  • 在伺服器端操作 HTML 內容(比如為移動端減少內容,為桌面端提供更多內容)

以上 RWD 和 AWD 解釋引自 知乎 @屹峰

可以參考 Bootstrap 的網格系統:http://getbootstrap.com/css/#grid-less

The Bootstrap 3 grid system has four tiers of classes: xs (phones), sm (tablets), md (desktops), and lg (larger desktops).

自己實現網格系統: Creating Your Own CSS Grid System

Flexbox 佈局

Flexbox 佈局參考下面幾篇文章就可以了,幾篇文章大同小異,看一兩篇就知道大概了,講的挺詳細的,在此不贅述

相關文章