網頁原生佈局的方法其實網上有很多,大概為Flow(流動佈局模型)、Float(浮動佈局模型)、Layer(層級佈局模型)。 ...
前言
網頁原生佈局的方法其實網上有很多,大概為Flow(流動佈局模型)、Float(浮動佈局模型)、Layer(層級佈局模型)。
<!--more-->
Flow佈局
流動佈局模型其實就是預設的網頁佈局模式。也就是說網頁在預設狀態下的HTML網頁元素都是根據流動模型來分佈網頁內容的。
流動佈局將會有兩個比較典型的特征,
第一,塊級元素都會在所處的最近父級容器元素內自上而下按順序垂直順延分佈,因為在預設狀態下,塊級元素的寬度都是100%(即父級元素寬度的100%)。實際上,塊狀元素都會以行的形式占據位置。如下代碼所示,
<html>
<body>
<h1>我是h1</h1>
<div>我是div</div>
</body>
</html>
如上述代碼所示,在沒有外在樣式的影響下,h1和div的寬度都將是100%(為頁面的預設寬度)。
第二,在流動模型下,內聯元素都會在所處的最近父級容器元素內從左到右水平分佈顯示。
<html>
<body>
<a>我是a</a>
<span>我是span</span>
</body>
</html>
內聯元素不會像塊級元素那樣獨自的占據一行。
Float佈局
任何元素在預設的情況下都是處於整個文檔流中的,不會浮動的。當我們給某一個元素設置浮動時,即可讓該元素擺脫當前文檔流,成為浮動元素。
如下代碼,給div元素設置浮動,讓兩個div併排顯示。
div{
width:200px;
height:200px;
border:2px red solid;
float:left;
}
<div id="div1">我是div1</div>
<div id="div2">我是div2</div>
這裡有一點需要註意,如果我給div設置的浮動是float: right,那麼div1將會貼在右側,而div2將會貼在div1的左側。
Layer佈局
什麼是層級佈局模型?
層級佈局模型就像是圖像軟體PhotoShop中非常流行的圖層編輯功能一樣,每個圖層能夠精確定位操作,但在網頁設計領域,由於網頁大小的活動性,層級佈局模型沒能受到熱捧。但是在網頁上局部使用層級佈局還是有其方便之處的。
應用層級佈局,往往需要定位屬性的配合。CSS中有3種定位類型,
- 絕對定位(position: absolute)
- 相對定位(position: relative)
- 固定定位(position: fixed)
絕對定位
如果想為元素設置層級佈局模型中的絕對定位,需要設置position:absolute(表示絕對定位),這條語句的作用將元素從文檔流中拖出來,然後使用left、right、top、bottom屬性相對於其最接近的一個具有定位屬性的父包含塊進行絕對定位。如果不存在這樣的包含塊,則相對於body元素,即相對於瀏覽器視窗。
相對定位
如果想為元素設置層級佈局模型中的相對定位,需要設置position:relative(表示相對定位),它通過left、right、top、bottom屬性確定元素在正常文檔流中的偏移位置。相對定位完成的過程是首先按static(float)方式生成一個元素(並且元素像層一樣浮動了起來),然後相對於以前的位置移動,移動的方向和幅度由left、right、top、bottom屬性確定,偏移前的位置保留不動。
相對定位與絕對定位最大的區別在於,前者沒有脫離當前文檔流而後者已經脫離了當前文檔流。脫離當前文檔流的意思是,該元素的前後元素在計算位置和偏移時將不再計算該元素的大小和位置。
固定定位
position: fixed,表示固定定位,與absolute定位類型類似,但它的相對移動的坐標是視圖(屏幕內的網頁視窗)本身。由於視圖本身是固定的,它不會隨瀏覽器視窗的滾動條滾動而變化,除非你在屏幕中移動瀏覽器視窗的屏幕位置,或改變瀏覽器視窗的顯示大小,因此固定定位的元素會始終位於瀏覽器視窗內視圖的某個位置,不會受文檔流動影響,這與background-attachment:fixed;(用於定位背景圖片的位置)屬性功能相同。
固定定位在某一種場景下很有用,當我們需要在頁面的某一位置固定的展示某一元素,且不受頁面滾動條的影響。比如,常見的“返回頂部”之類的按鈕。
混合使用
現代網頁佈局中,經常將相對定位和絕對定位混合使用,以達到更加靈活的目的。如下代碼,
<style>
#box1{
width:200px;
height:200px;
position:relative; /* 前輩元素的定位必須設置為relative */
}
#box2{
position:absolute; /* 相對於最近的一個定位設置為relative的前輩元素的絕對定位 */
top:20px;
left:30px;
}
</style>
<div id="box1">
<div id="box2">相對參照元素進行定位</div>
</div>
即,box2相對於box1是絕對定位的。當改變box1的位置時,box1內部的子元素是不會發生變化的,因為他們都是相對box1絕對定位的。
常見佈局方式(兩列)
兩列情況暫定左側寬為100PX
方法一:
float + calc()
.right {
width: calc(100% - 100px);
}
方法二:
position / float + margin-left
//html部分同上
//css
.left {
position:absolute;left: 0; /*或 float:left; */
width: 100px;
background: blue;
}
.right{
margin-left: 100px;
background: red;
text-align:center;
}
兩列佈局中,左邊固定,右邊自適應如何實現。
1.左浮動,右邊用margin-left長度為左邊的固定寬度,寬為100%
2.利用的是創建一個新的BFC(塊級格式化上下文)來防止文字環繞的原理來實現的。BFC就是一個相對獨立的佈局環境,它內部元素的佈局不受外面佈局的影響。它可以通過以下任何一種方式來創建:
- float的值不為none
- position的值不為static或者relative
- display的值為 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一個
- overflow的值不為visible
三列佈局左右固定中間自適應
聖杯
思路
首先有三行,頭部和尾部各占一行,中間內容區一行,頭尾不重要
中間內容分為三列對應三個div,為了先展示中間的主要內容所以把中間那列放前面,然後是左和右對應的div
中間內容自適應寬度為100%,此時已經把3個div所在的父容器占滿了,所以想辦法讓左右2個div放置在左右側,
左側採取margin-left取-100%讓其在最左側,
右側同理取值-200px(像素值為寬度大小),保證剛好占滿自身寬度
這時候測試發現已經有自適應效果了,但是縮小到一定程度頁面就出問題了,左右不在了,
所以加上最低寬度就是左右2個DIV的寬度(另外得考慮瀏覽器預設的body下的margin為8px,做了樣式重置不考慮)
這時候發現中間的內容文字被左右遮擋了,對父容器用pading左右值為左右元素寬度,
為什麼不對中間的DIV設置padding,我發現設置了不起作用,具體的原因我暫時也搞不懂來龍去脈,
發現padding後左右有留白,這個時候左邊需要用 left: -200px;position: relative;來設置DIV位置,
辦法確實巧妙。右邊實現同理。
這時候發現已經大致有了點樣子了,效果也看的到,此時典型的三欄佈局,左右固定,中間內容自適應已經完成。
總結:
其實這個佈局已經有點年頭(聖杯佈局),通過左右兩塊DIV來遮擋了中間div寬度為100%的區域,
然後壓縮了三個DIV共有的父容器,來實現對中間內容展示的完善,也使左右2個不在遮擋中間了。
然後我又趁機試了下z-index屬性,這裡有個小問題要註意(要讓z-index起作用有個小小前提,
就是元素的position屬性要是relative,absolute或是fixed)我之前的想法是讓中間的內容置於頂層,不受div會因為某種hack導致位置變更遮擋了中間內容。
只需要設置下z-index屬性值即可,左右可不設置,也可以設置以防萬一,不同瀏覽器對z-index的預設值解析不同,可能會導致問題。基本的佈局架構就是如此,根據實際項目需求在此架構上完善,或者以後遇到這種類似的問題能打開思路,便算是有點收穫了。
核心代碼
<style>
body {
/*因為瀏覽器預設body為margin:8px所以多加了16px*/
min-width: 616px;
}
header {
width: 100%;
height: 40px;
background-color: darkseagreen;
}
.container {
/*height: 200px;*/
/*overflow: hidden;*/
padding: 0 200px;
}
.middle {
width: 100%;
height: 200px;
background-color: deeppink;
float: left;
/*position: relative;*/
}
.left {
width: 200px;
height: 200px;
background-color: blue;
float: left;
margin-left: -100%;
left: -200px;
position: relative;
}
.right {
width: 200px;
height: 200px;
background-color: darkorchid;
float: left;
margin-left: -200px;
right: -200px;
position: relative;
}
footer {
clear: both;
width: 100%;
height: 30px;
background-color: darkslategray;
}
</style>
<header>
<h4>Header內容區</h4>
</header>
<div class="container">
<div class="middle">
<h4>中間彈性區</h4>
<p>
我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容
</p>
</div>
<div class="left">
<h4>左邊欄</h4>
</div>
<div class="right">
<h4>右邊欄</h4>
</div>
</div>
<footer>
<h4>Footer內容區</h4>
</footer>
雙飛翼
思路
雙飛翼佈局的方式跟聖杯在前部分是一樣,不同之處主要在於如何處理中間的內容塊被遮擋的問題
聖杯用padding的思路,使之壓縮,但是父容器壓縮,左右DIV位置變更,只能用相對位置進行left
設置位移為元素寬度來調整
而雙飛翼的路線為採用的方式相比聖杯的父容器padding,
改變的是中間內容的內層div的外邊框,相對來說對佈局的破壞不大,
但是要採用這種方式又不破壞頁面結構,就只能在中間內容div內部的再加個DIV設置margin或padding.
使之內容變相“壓縮”等同padding效果,並且不會改變中間內容DIV外部的結構,只是內部的。
細心的人留意下我註釋的代碼,這裡其實還有個CSS浮動的樣式問題,出現這種情況有各種方式清除浮動,
我就不多講解。大概有6種。
清除浮動(常用)
1.一般目前常用就是用:after偽元素給使用的浮動的父容器設置。
新浪使用方式
.clearfix:after{
content: '';
display: block;
clear: both;
height: 0;
visibility: hidden;
}
.clearfix:after{ /*最簡方式*/
content: '';
display: block;
clear: both;
}
2.給父元素定高
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.outer{
border: 1px solid black;
width: 300px;
height: 50px;
}
.inner{
width: 50px;
height: 50px;
background-color: #ff4400;
margin-right: 20px;
float: left;
}
.footer{
background-color: #005FC3;
width: 200px;
height: 100px;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
</div>
<div class="footer"></div>
</body>
</html>
3.利用 overflow:hidden 屬性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.outer{
border: 1px solid black;
width: 300px;
overflow: hidden;
zoom: 1;/*相容 IE*/
}
.inner{
width: 50px;
height: 50px;
background-color: #ff4400;
margin-right: 20px;
float: left;
}
.footer{
background-color: #005FC3;
width: 200px;
height: 100px;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
</div>
<div class="footer"></div>
</body>
</html>
核心代碼
<!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>
header {
width: 100%;
height: 40px;
background-color: darkseagreen;
}
.container {
/*height: 200px;*/
/*overflow: hidden;*/
}
.middle {
width: 100%;
height: 200px;
background-color: deeppink;
float: left;
word-break: break-all;
}
.left {
width: 200px;
height: 200px;
background-color: blue;
float: left;
margin-left: -100%;
}
.right {
width: 200px;
height: 200px;
background-color: darkorchid;
float: left;
margin-left: -200px;
}
footer {
width: 100%;
height: 30px;
background-color: darkslategray;
clear: both;
}
.div-middle {
margin: 0 200px;
/*padding: 0 200px;*/
}
</style>
</head>
<body>
<header>
<h4>Header內容區</h4>
</header>
<div class="container">
<div class="middle">
<div class="div-middle">
<h4>中間彈性區</h4>
<p>
我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容我是各種內容
</p>
</div>
</div>
<div class="left">
<h4>左邊欄</h4>
</div>
<div class="right">
<h4>右邊欄</h4>
</div>
</div>
<footer>
<h4>Footer內容區</h4>
</footer>
</body>
</html>
End
本篇只做階段性的初級總結,原諒我沒有貼出代碼的效果圖,以後有機會再擴展併進行效果圖片展示,希望大家自己在編輯器下嘗試效果。
學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入學習交流群
343599877,我們一起學前端!