圣杯布局和双飞翼布局是前端工程师需要日常掌握的重要布局方式。两者的功能相同,都是为了实现一个两侧宽度固定,中间宽度自适应的三栏布局。
作用
圣杯布局和双飞翼布局解决的问题是相同的,就是两边顶宽,中间自适应的三栏布局,中间栏要在放在文档流前面以优先渲染。
区别
圣杯布局:为了让中间div内容不被遮挡,将中间div设置了左右padding-left和padding-right后,将左右两个div用相对布局position: relative并分别配合right和left属性,以便左右两栏div移动后不遮挡中间div。
双飞翼布局:为了让中间div内容不被遮挡,直接在中间div内部创建子div用于放置内容,在该div里用margin-left和margin-right为左右两栏div留出位置。
代码示例
详细代码点击这里去github查看
圣杯布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>圣杯布局</title> </head> <style> .container { padding: 0 100px 0 200px; }
.left { width: 200px; background: red; margin-left: -100%; left: -200px; } .right{ width: 100px; background: blue; margin-left: -100px; right: -100px; } .main{ width: 100%; background: yellow; } .left,.main,.right{ float: left; min-height: 200px; position: relative; } </style>
<body> <div class="container"> <div class="main">main</div> <div class="left">left</div> <div class="right">right</div> </div> </body>
</html>
|
圣杯布局总结:用父盒子的padding将中间栏挤到中间,并腾出地方给两边栏
双飞翼
优点:不会像圣杯布局那样变形
缺点是:多加了一层dom节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>双飞翼</title> </head> <style> .left,.main,.right{ min-height: 300px; float: left; } .content{ margin: 0 100px 0 200px; } .left{ width: 200px; background: green; margin-left: -100%; } .main{ width: 100%; background: red; } .right{ width: 100px; background: blue; margin-left: -100px; } </style>
<body> <div class="container"> <div class="main"> <div class="content">main</div> </div> <div class="left">left</div> <div class="right">right</div> </div> </body>
</html>
|
双飞翼总结:中间的div外层用另一个div包裹了一下,然后利用 margin来把嵌套的div“挤”到中间
使用其他方法实现中间栏div内容不被遮挡
除了圣杯布局和双飞翼布局,我们还可以用别的方式实现同样的效果
方案一
使用box-sizing:boder-box
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>其他方法实现中间栏div内容不被遮挡</title> </head>
<style> .container{ padding: 0 100px 0 200px; } .left,.main,.right{ float:left; position: relative; min-height: 200px; } .left{ background: lightgreen; width: 200px; margin-left: -100%; left: -200px; } .main{ background: lightpink; width: 100%; box-sizing: border-box; padding: 0 100px 0 200px; } .right{ background: lightseagreen; width: 100px; margin-left: -100px; right: -100px; } </style>
<body> <div class="container"> <div class="main">main</div> <div class="left">left</div> <div class="right">right</div> </div> </body>
</html>
|
方案二
利用flex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>flex</title> </head>
<style> .container{ display: flex; min-height: 300px; } .main { flex-grow: 1; background-color: mediumaquamarine; } .left{ flex-basis: 200px; background-color: mediumpurple; } .right{ flex-basis: 300px; background-color: red; } </style> <body> <div class="container"> <div class="left">left</div> <div class="main">main</div> <div class="right">right</div> </div> </body> </html>
|