欄雙飛翼布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>三欄雙飛翼布局</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
body{
overflow: hidden;/*隱藏頁面的滾動條*/
}
.content{
width: 100%;
min-width: 1120px;/*設置一個最小寬度 免得頁面布局太丑(文字會掉下來)*/
height: 200px;
background-color: red;
position: relative;
}
.left{
width: 200px;
height: 200px;
background-color: green;
position: absolute;
left: 0;
top: 0;
}
.right{
width: 300px;
height: 200px;
background-color: blue;
position: absolute;
right: 0;
top: 0;
}
.center{
/* 寬度不給默認父元素寬度 */
/* 有一個padding值 */
padding: 0 300px 0 200px;
}
</style>
</head>
<body>
<!-- 三欄布局:左右固定中間自適應 -->
<!-- 雙飛翼 -->
<div class="content">
<div class="left">200*200</div>
<div class="center">我是自適應網頁......</div>
<div class="right">300*200</div>
</div>
</body>
</html>
三欄圣杯布局
今天聊點簡單的,最近在整理面試題的時候,看到css部分,感覺自己有段時間沒有切頁面了,正好趁著這個機會好好復習一下,加深一下印象。
如何實現三欄布局 中間自適應?這也是在前端面試官經常會問到的,當你被問到這個它的時候,你的腦子里應該想到什么?給你3秒鐘的時間...那必然是最最經典的圣杯、雙飛翼布局,這就是實現這個問題最優雅的方式。
既然是三欄布局,我們先創建3個容器:left + middle + right
接下來就是實現三欄布局的效果,我們先聊一個最簡單最好想的方法,使用彈性
先給left和right都設置200px的寬度,再給它們的父容器container設置屬性display: flex;這樣這三個容器就會自動去到同一行,再給middle容器設置flex:1,這樣中間這個容器的寬度就能一直得到全部寬度減去左右兩邊容器寬度,這個寬度會隨著窗口的大小而變化,代碼和效果圖如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
div{
height: 100px;
}
.container{
display: flex;
}
.left,.right{
width: 200px;
background: #66a4bd;
}
.middle{
flex: 1;
background: gray;
}
</style>
</head>
<body>
<div class="container">
<div class="left">left</div>
<div class="middle">middle</div>
<div class="right">right</div>
</div>
</body>
</html>
這個方法看起來是不是很簡單,沒錯它真的非常簡單,都不需要動腦子,簡簡單單兩行代碼就能搞定。but!它存在一個問題,這個方法是先加載左邊容器的,中間容器加載。不知道大家在上網的時候有沒有發現過,有些頁面左右兩邊的都是廣告,重要內容都在中間,那么當我們如果使用這個方法來布局的時候,最先出來的是廣告,那你愿意嗎?我們肯定是想先看到中間的主要內容,兩邊廣告什么時候出現誰在意呢?
所以為了優化這個問題,就出現了經典的 圣杯 和 雙飛翼 布局,它們的目的就是為了在HTML結構上,中間欄在最前面保證了最先渲染中間提升性能
既然要保證中間欄最先加載,那就要把middle容器寫在前面
<body>
<div class="container">
<div class="middle">middle</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
css樣式還是先給左右容器寬度200px,高度都一樣,給個背景色便于區分:
第一步:給三個容器的父容器添加padding:0 200px;騰開位置;middle中間容器設置width:100%;此時的寬度繼承了父容器的100%;并且給三個子容器都設置float: left;讓它們都向左浮動,去到同一行,效果如下:
此時的頁面效果就是第一行位置放不下,左右兩個容器被擠到了第二行,其實按道理來說它們應該是在第一行兩塊紅色區域位置的,浮動的效果嘛,大家都能理解吧
第二步:給左右容器相對定位,讓它們相對自己原本文檔流的位置進行定位
.left{
width: 200px;
background: #76d1ea;
position: relative;
margin-left: -100%; //向左挪動父容器寬度的100%
left: -200px; //再向左挪動自身的200寬度
}
此時right接替了left原本的位置,同理,這時候只需要給right設置:margin-right: -200px; 那么就實現了我們想要的三欄布局
完整代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>圣杯</title>
<style>
*{
margin: 0;
padding: 0;
}
.container{
height: 100px;
padding: 0 200px;
}
.middle, .left, .right{
height: 100%;
float: left;
}
.middle{
width: 100%;
background: gray;
}
.left{
width: 200px;
background: #76d1ea;
position: relative;
margin-left: -100%;
left: -200px;
}
.right{
width: 200px;
background: #76d1ea;
position: relative;
margin-right: -200px;
}
</style>
</head>
<body>
<div class="container">
<div class="middle">middle</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
</html>
不過這樣布局有一個問題就是:有一個最小寬度,當頁面小于最小寬度時布局就會亂掉。 “由于設置了相對定位,所以當left原來的位置和right的位置產生重疊時,由于浮動的原因一行放不下就會換行” 。所以布局就被打亂了,使用雙飛翼布局就可以避免這個問題。
我們先把HTML結構稍微改造一下,在middle容器里面多用了個inner容器
<body>
<div class="container">
<div class="middle">
<div class="inner">middle</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
因為已經設置了middle的width:100%,這時候我們只需要設置inner容器為padding:0 200px,我們要的效果同樣是把左右兩個容器擺放到對應的紅框位置
接下來left、middle、right同樣使用浮動,left設置margin-left:-100%;(父容器的整個寬度),right設置margin-left:-200px;這樣便實現了三欄布局的效果,連定位都不使用,且當頁面過小時,布局不會亂,效果如下:
完整代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>雙飛翼</title>
<style>
*{
margin: 0;
padding: 0;
}
.container{
height: 100px;
}
.middle, .left, .right{
float: left;
height: 100%;
}
.middle{
width: 100%;
background: gray;
}
.inner{
height: 100%;
padding: 0 200px;
}
.left{
width: 200px;
background: pink;
margin-left: -100%;
}
.right{
width: 200px;
background: pink;
margin-left: -200px;
}
</style>
</head>
<body>
<div class="container">
<div class="middle">
<div class="inner">middle</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
</html>
給個圖便于大家理解
兩種布局方式都是把主要欄放在文檔流最前面,使主要欄優先加載
相同之處 :讓三列浮動,然后通過負外邊距形成三列布局
不同之處 在于如何處理中間主列的位置:
作者:深藏blue9
鏈接:https://juejin.cn/post/7276398869734817832
言
三欄布局,顧名思義就是兩邊固定,中間自適應。三欄布局在實際的開發十分常見,比如淘寶網的首頁,就是個典型的三欄布局:即左邊商品導航和右邊導航固定寬度,中間的主要內容隨瀏覽器寬度自適應。
我們不妨假定這樣一個布局:高度已知,其中左欄、右欄寬度各為300px,中間自適應,可以通過幾種方法來實現?以及各自的優缺點是什么?
本文源代碼請猛戳三欄布局源碼,歡迎star和fork
一、浮動布局
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Layout</title> <style media="screen"> html * { padding: 0; margin: 0; } .layout article div { min-height: 150px; } </style> </head> <body> <!--浮動布局 --> <section class="layout float"> <style media="screen"> .layout.float .left { float: left; width: 300px; background: red; } .layout.float .center { background: yellow; } .layout.float .right { float: right; width: 300px; background: blue; } </style> <h1>三欄布局</h1> <article class="left-right-center"> <div class="left"></div> <div class="right"></div> // 右欄部分要寫在中間內容之前 <div class="center"> <h2>浮動解決方案</h2> 1.這是三欄布局的浮動解決方案; 2.這是三欄布局的浮動解決方案; 3.這是三欄布局的浮動解決方案; 4.這是三欄布局的浮動解決方案; 5.這是三欄布局的浮動解決方案; 6.這是三欄布局的浮動解決方案; </div> </article> </section> </body> </html>
這種布局方式,dom結構必須是先寫浮動部分,然后再中間塊,否則右浮動塊會掉到下一行。
浮動布局的優點就是比較簡單,兼容性也比較好。但浮動布局是有局限性的,浮動元素脫離文檔流,要做清除浮動,這個處理不好的話,會帶來很多問題,比如父容器高度塌陷等。
二、絕對布局
<!--絕對布局 --> <section class="layout absolute"> <style> .layout.absolute .left-center-right>div{ position: absolute;//三塊都是絕對定位 } .layout.absolute .left { left:0; width: 300px; background: red; } .layout.absolute .center { right: 300px; left: 300px;//離左右各三百 background: yellow; } .layout.absolute .right { right: 0; width: 300px; background: blue; } </style> <h1>三欄布局</h1> <article class="left-center-right"> <div class="left"></div> <div class="center"> <h2>絕對定位解決方案</h2> 1.這是三欄布局的浮動解決方案; 2.這是三欄布局的浮動解決方案; 3.這是三欄布局的浮動解決方案; 4.這是三欄布局的浮動解決方案; 5.這是三欄布局的浮動解決方案; 6.這是三欄布局的浮動解決方案; </div> <div class="right"></div> </article> </section>
絕對定位布局優點就是快捷,設置很方便,而且也不容易出問題。缺點就是,容器脫離了文檔流,后代元素也脫離了文檔流,高度未知的時候,會有問題,這就導致了這種方法的有效性和可使用性是比較差的。
三、flexbox布局
<!--flexbox布局--> <section class="layout flexbox"> <style> .layout.flexbox .left-center-right{ display: flex; } .layout.flexbox .left { width: 300px; background: red; } .layout.flexbox .center { background: yellow; flex: 1; } .layout.flexbox .right { width: 300px; background: blue; } </style> <h1>三欄布局</h1> <article class="left-center-right"> <div class="left"></div> <div class="center"> <h2>flexbox解決方案</h2> 1.這是三欄布局的浮動解決方案; 2.這是三欄布局的浮動解決方案; 3.這是三欄布局的浮動解決方案; 4.這是三欄布局的浮動解決方案; 5.這是三欄布局的浮動解決方案; 6.這是三欄布局的浮動解決方案; </div> <div class="right"></div> </article> </section>
flexbox布局是css3里新出的一個,它就是為了解決上述兩種方式的不足出現的,是比較完美的一個。目前移動端的布局也都是用flexbox。 flexbox的缺點就是IE10開始支持,但是IE10的是-ms形式的。
四、表格布局
<!--表格布局--> <section class="layout table"> <style> .layout.table .left-center-right { display: table; height: 150px; width: 100%; } .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> <h1>三欄布局</h1> <article class="left-center-right"> <div class="left"></div> <div class="center"> <h2>表格布局解決方案</h2> 1.這是三欄布局的浮動解決方案; 2.這是三欄布局的浮動解決方案; 3.這是三欄布局的浮動解決方案; 4.這是三欄布局的浮動解決方案; 5.這是三欄布局的浮動解決方案; 6.這是三欄布局的浮動解決方案; </div> <div class="right"></div> </article> </section>
表格布局的兼容性很好(見下圖),在flex布局不兼容的時候,可以嘗試表格布局。當內容溢出時會自動撐開父元素。
表格布局也是有缺陷:①無法設置欄邊距;②對seo不友好;③當其中一個單元格高度超出的時候,兩側的單元格也是會跟著一起變高的,然而有時候這并不是我們想要的效果。
五、網格布局
<!--網格布局--> <section class="layout grid"> <style> .layout.grid .left-center-right { display: grid; width: 100%; grid-template-columns: 300px auto 300px; grid-template-rows: 150px;//行高 } .layout.grid .left { background: red; } .layout.grid .center { background: yellow; } .layout.grid .right { background: blue; } </style> <h1>三欄布局</h1> <article class="left-center-right"> <div class="left"></div> <div class="center"> <h2>網格布局解決方案</h2> 1.這是三欄布局的浮動解決方案; 2.這是三欄布局的浮動解決方案; 3.這是三欄布局的浮動解決方案; 4.這是三欄布局的浮動解決方案; 5.這是三欄布局的浮動解決方案; 6.這是三欄布局的浮動解決方案; </div> <div class="right"></div> </article> </section>
CSS Grid是創建網格布局最強大和最簡單的工具。就像表格一樣,網格布局可以讓Web設計師根據元素按列或行對齊排列,但他和表格不同,網格布局沒有內容結構,從而使各種布局不可能與表格一樣。例如,一個網格布局中的子元素都可以定位自己的位置,這樣他們可以重疊和類似元素定位。
但網格布局的兼容性不好。IE10+上支持,而且也僅支持部分屬性。
六、總結
通過上面詳細介紹五種布局的優缺點,在實際開發中最優選擇哪種布局?相信讀者心中會有自己的答案。
我覺得flex和grid布局就可以搞定實際開發中的布局,假設瀏覽器都支持這兩個模塊,你將選擇grid還是flexbox來給頁面布局?flexbox是一維布局,他只能在一條直線上放置你的內容區塊;而grid是一個二維布局。前面也簡單說到,你可以根據你的設計需求,將內容區塊放置到任何你想要放的地方。那么不用多說,你應該知道哪一種更適合你的布局。此外,如果要兼容低版本的IE(比如IE8+),可以考慮table布局。
最后問大家一個問題,如果中間部分被內容高度撐開,需要左右欄也撐開,這五種布局哪些布局還可以用?
答案:flex布局和table布局
作者:人心思動
鏈接:http://www.imooc.com/article/details/id/79718
*請認真填寫需求信息,我們會在24小時內與您取得聯系。