CSS三欄佈局方案

平時開發或者面試的時候,常常會遇到這樣的場景,實現一個三欄佈局,具體要求以下:css

高度爲100px,左右欄寬度固定爲300px,中間欄寬度自適應。html

有多種佈局方案能夠實現,這裏一一探索。android

浮動佈局方案

實現思路:git

經過讓左右兩欄固定寬度和浮動,並設置中間欄的左右外邊距實現三欄自適應github

這裏還有一種實現思路,中間欄建立一個BFC一樣能夠實現自適應,原理是浮動不會影響BFC內的內容web

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>三欄佈局-浮動佈局方案</title>
  <style> .left, .right, .main { height: 100px; } .left { width: 300px; float: left; background: red; } .right { width: 300px; float: right; background: blue; } .main { margin-left: 300px; margin-right: 300px; background: yellow; } </style>
</head>
<body>
  <article>
    <aside class="left">left</aside>
    <aside class="right">right</aside>
    <main class="main">main</main>
  </article>
</body>
</html>
複製代碼

缺點:面試

  1. 內容展示順序與DOM結構不一致,主體內容後加載,必定程度影響用戶體驗
  2. 當寬度縮小到不足以顯示三欄時,右側欄會被擠到下方

兼容性:chrome

  1. PC端支持IE6+, Firefox 2+, Chrome 1+
  2. 移動端支持iOS Safari 1.0,Android browser 1.0

絕對定位佈局方案

實現思路:segmentfault

容器設置爲相對定位,左右兩欄分別用絕對定位,中間欄增長左右外邊距實現自適應瀏覽器

還有一種思路, 左右兩欄分別絕對定位在兩側,中間欄一樣使用絕對定位,並設置左右的距離爲300px

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>三欄佈局-絕對定位方案</title>
  <style> .container { position: relative; } .main, .left, .right { height: 100px; } .main { margin-left: 300px; margin-right: 300px; background: yellow; } .left { position: absolute; top: 0; left: 0; width: 300px; background: red; } .right { position: absolute; top: 0; right: 0; width: 300px; background: blue; } </style>
</head>
<body>
  <article class="container">
    <main class="main">main</main>
    <aside class="left">left</aside>
    <aside class="right">right</aside>
  </article>
</body>
</html>
複製代碼

缺點:

  1. 父元素必需要定位(使用非static的定位方式)
  2. 寬度縮小到沒法顯示主體內容時,主體內容會被覆蓋沒法顯示

優勢:

  1. 內容能夠優先加載

兼容性:

  1. PC端支持IE6+, Firefox 2+, Chrome 1+
  2. 移動端未知

Flex佈局方案

實現思路:

設置容器爲flex,而後左右欄設置固定寬度不可伸縮,中間欄設置爲自動伸縮

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>三欄佈局-彈性盒佈局方案</title>
  <style> .container { display: flex; } .left, .main, .right { height: 100px; } .left { flex: 0 0 300px; background: red; } .main { flex: 1 1 auto; background: yellow; } .right { flex: 0 0 300px; background: blue; } </style>
</head>
<body>
  <article class="container">
    <aside class="left">left</aside>
    <main class="main">main</main>
    <aside class="right">right</aside>
  </article>
</body>
</html>
複製代碼

缺點:

  1. 沒法兼容低版本的瀏覽器

優勢:

  1. 代碼簡潔,DOM結構清晰
  2. 主流的實現方式

兼容性:

  1. PC端支持IE10及以上、Edge 12,chrome 21,firefox 28,safari 6.1(IE10爲部分支持,其餘瀏覽器版本爲徹底支持)
  2. 移動端支持iOS Safari 7, android browser 4.4
  3. 兼容性詳情

網格佈局方案

實現思路:

設置容器爲grid,而後設置行高度爲100px,設置三欄的寬度

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>三欄佈局-網格佈局方案</title>
  <style> .container { display: grid; grid-template-rows: 100px; grid-template-columns: 300px 1fr 300px; } .left { background: red; } .main { background: yellow; } .right { background: blue; } </style>
</head>
<body>
  <article class="container">
    <aside class="left">left</aside>
    <main class="main">main</main>
    <aside class="right">right</aside>
  </article>
</body>
</html>
複製代碼

缺點:

  1. 兼容性相對彈性盒要差,不過目前絕大部分瀏覽器較新的版本已經支持

優勢:

  1. 代碼簡潔,DOM結構清晰

兼容性:

  1. PC端支持IE10及以上、Edge 16,chrome 57,firefox 52,safari 10.1(IE10爲部分支持,其餘瀏覽器爲徹底支持的起始版本)
  2. 移動端支持iOS Safari 10.3, android browser 67
  3. 兼容性詳情

表格佈局方案

實現思路:

設置容器爲table且寬度爲100%,並設置子元素爲table-cell

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>三欄佈局-表格佈局方案</title>
  <style> .container { display: table; width: 100%; } .left, .main, .right { display: table-cell; height: 100px; } .left { width: 300px; background: red; } .main { background: yellow; } .right { width: 300px; background: blue; } </style>
</head>
<body>
  <article class="container">
    <aside class="left">left</aside>
    <main class="main">main</main>
    <aside class="right">right</aside>
  </article>
</body>
</html>
複製代碼

缺點:

  1. 非語義化

優勢:

  1. 兼容瀏覽器版低

兼容性:

  1. PC支持IE8+, Firefox 3+, Chrome 4+, Safari 3.1+
  2. 移動端支持 iOS Safari 3.2, android browser 2.1
  3. 兼容性詳情

聖盃佈局

實現思路:

經過將左右兩欄掛在容器的兩側,從而實現三欄佈局,形狀相似聖盃

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>三欄佈局-聖盃佈局方案</title>
  <style> .container { margin-left: 300px; margin-right: 300px; overflow: hidden; } .main, .left, .right { height: 100px; } .main { float: left; width: 100%; background: yellow; } .left { float: left; margin-left: -100%; width: 300px; position: relative; left: -300px; background: red; } .right { float: left; margin-left: -300px; width: 300px; position: relative; left: 300px; background: blue; } </style>
</head>
<body>
  <article class="container">
    <main class="main">main</main>
    <aside class="left">left</aside>
    <aside class="right">right</aside>
  </article>
</body>
</html>
複製代碼

缺點:

  1. 當中間欄寬度比左欄寬度小時,佈局會發生混亂

優勢:

  1. 支持內容優先加載

兼容性:

  1. 參考浮動佈局方案

雙飛翼佈局方案

實現思路:

基於聖盃佈局,引入一個容器來放置中間欄,而且設置中間欄的外邊距,不須要使用相對定位

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>三欄佈局-雙飛翼佈局方案</title>
  <style> .main .in, .left, .right { height: 100px; } .main { float: left; width: 100%; } .main .in { margin-left: 300px; margin-right: 300px; background: yellow; } .left { float: left; width: 300px; margin-left: -100%; background: red; } .right { float: right; width: 300px; margin-left: -300px; background: blue; } </style>
</head>
<body>
  <article class="container">
    <main class="main">
      <div class="in">main</div>
    </main>
    <aside class="left">left</aside>
    <aside class="right">right</aside>
  </article>
</body>
</html>
複製代碼

缺點:

  1. DOM結構較複雜

優勢:

  1. 支持內容優先加載
  2. 相對聖盃佈局,寬度縮小,佈局不會發生混亂

兼容性:

  1. 參考浮動佈局方案

歡迎訪問我的博客 blog.bookcell.org/

參考

相關文章
相關標籤/搜索