1:盒子模型
2:CSS定位與居中問題
3:CSS浮動
盒子模型
div盒子模型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>div盒子模型</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.div-box{
width: 100px;
height: 100px;
background: #000;
padding: 10px;
border: 10px solid red;
margin: 10px;
}
</style>
</head>
<body>
<div class="div-box"></div>
</body>
</html>

margin 外邊距的合并
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>margin外邊距的合并</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.div-box1{
width: 100px;
height: 100px;
padding: 10px;
border: 10px solid red;
margin: 10px;
}
.div-box2{
width: 100px;
height: 100px;
padding: 10px;
border: 10px solid red;
margin: 10px;
}
</style>
</head>
<body>
<div class="div-box1">div</div>
<div class="div-box2">div</div>
</body>
</html>
上述代碼中,兩個div塊的上下左右外邊距margin均為10px,在外邊距合并后,div和div上下邊框之間的距離會取最大的margin值,本例中margin數(shù)值相同,上下div的border間的距離則為10px而非加和的20px。效果如圖所示:

span"盒子模型"
內(nèi)聯(lián)元素在頁面布局中并不像塊級元素一樣能夠使用盒子模型中所有的屬性,但是一些屬性也是能夠進(jìn)行的控制的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>span</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.span1{
border: 1px solid blue;
margin: 10px;
}
.span2{
padding: 100px;
border: 1px solid red;
}
div{
border: 1px solid green;
}
</style>
</head>
<body>
<span class="span1">span</span><span class="span2">span</span>
<div>1111111111111111111111111</div>
</body>
</html>
上面的代碼在頁面中的展示效果如下:

width 寬度屬性以及 height 高度屬性 僅在塊級元素以及替換元素中適用。通過上面的代碼可以看到,第二個span元素雖然設(shè)置了padding但是僅僅在left,right,以及bottom方向起了作用,并且在bottom方向上,雖然將border撐開了,但是下面的div元素仍然無視了撐開的高度,在第二行排布。在span元素中適用的盒子屬性僅有左右方向上的屬性,即:margin-left,margin-right,padding-left,padding-right,border-left,border-right。因為,span就是一個內(nèi)聯(lián)元素(行內(nèi)元素),只有行內(nèi)的屬性會起到作用。在上述元素中,通常只會使用到 margin-left 以及 margin-right。
display:inline-block
display屬性可以將塊級元素轉(zhuǎn)換為行內(nèi)元素,同樣也可以將行內(nèi)元素轉(zhuǎn)換為塊級元素。inline-block屬性值則是使一些行內(nèi)元素具有塊級元素的某些屬性。如代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.span1{
display: inline-block;
width: 100px;
height: 100px;
margin: 10px;
border: 1px solid blue;
}
.span2{
display: inline-block;
width: 100px;
height: 100px;
margin: 10px;
border: 1px solid red;
}
div{
width: 100px;
height: 100px;
border: 1px solid green;
margin: 10px;
}
</style>
</head>
<body>
<span class="span1">span</span><span class="span2">span</span>
<div>div</div>
</body>
</html>
頁面展示效果如下:

可以看到span內(nèi)設(shè)置了display: inline-block;屬性后,不僅盒模型的所有屬性都可以使用,且兩個span元素在一行進(jìn)行了顯示。兩個span元素之間的margin為20px ,因為左右margin不會產(chǎn)生合并,但是注意的是,span和 下一行的div之間的margin同樣為20px,說明在上下方向,span與div的margin并沒有合并!
box-sizing: border-box;
測試代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
div{
width: 100px;
height: 100px;
padding: 10px;
border: 10px solid red;
margin: 10px;
box-sizing: border-box;
}
</style>
</head>
<body>
<div>div</div>
</body>
</html>
上述代碼在網(wǎng)頁顯示的效果為:

CSS屬性
box-sizing: border-box; 可以將原來的content-box(width,height作用在content上)轉(zhuǎn)換為border-box(width ,height作用在border以內(nèi))。簡單的來說,這個盒子模型的寬度和高度的100px,是content+padding+boder的和。
CSS定位與居中問題
居中是頁面布局最常被用到的需求,處理居中問題往往有多種解決方式,本篇博客將介紹CSS定位以及常用的幾種解決居中問題的思路。
static
position: static;指定了元素使用正常的布局行為,即元素在文檔常規(guī)流中當(dāng)前的布局位置。此時 top, right, bottom, left 和 z-index 屬性無效。什么叫文檔流呢?文檔流就是元素在頁面中的流動方向,即:行內(nèi)元素從左到右,塊級元素自上至下。
relative
relative最大的作用就是使元素成為可定位的祖先元素。被設(shè)置為relative定位屬性值的元素可以使用top,right,bottom,left,z-index等屬性值進(jìn)行相對定位,且相對定位的元素不會離開常規(guī)流。那么relative相對定位,到底是相對哪個元素進(jìn)行定位的呢?實際上,就是相對于自己原本常規(guī)流中的位置進(jìn)行相對定位的。示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>relative相對定位</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.box {
display: inline-block;
width: 100px;
height: 100px;
background: red;
color: white;
}
#two {
position: relative;
top: 20px;
left: 20px;
background: blue;
z-index: -1;
}
</style>
</head>
<body>
<div class="box" id="one">One</div>
<div class="box" id="two">Two</div>
<div class="box" id="three">Three</div>
<div class="box" id="four">Four</div>
</body>
</html>
示例在頁面的效果為:

四個div均設(shè)置了
display: inline-block;屬性,可以看到藍(lán)色的div塊相對于自己常規(guī)流中的位置 偏移了top: 20px;left: 20px;,但是Two塊并沒有脫離常規(guī)流,而是在常規(guī)流中占據(jù)了自己原來的"一畝三分地"。這里設(shè)置了z-index: -1;,z-index可以控制元素堆疊的順序,通常來說 z-index 較大的元素會覆蓋較小的一個。所以Two塊會被 Three塊壓在下面。
absolute
絕對定位元素相對于最近的 非 static 祖先元素定位。通常這個祖先元素設(shè)置為relative,被設(shè)置了absolute的元素會相對于 設(shè)置了relative的祖先元素進(jìn)行定位,倘若沒有這樣一個祖先元素,那么它就會相對于body定位。被設(shè)置position: absolute; 的元素會脫離文檔流,示例1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute絕對定位</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.div1{
color: #FFFFFF;
display: inline-block;
width: 100px;
height: 100px;
background: red;
}
.div2{
color: #FFFFFF;
display: inline-block;
width: 100px;
height: 100px;
background: red;
position: relative;
}
.child{
display: inline-block;
width: 100px;
height: 100px;
background: blue;
position: absolute;
left: 30px;
top: 30px;
}
</style>
</head>
<body>
<div class="div1">div1</div>
<div class="div2">
div2
<div class="child"></div>
</div>
</body>
</html>
在頁面中的效果為:

藍(lán)色的block相對于設(shè)置了相對定位的父元素div2 發(fā)生了偏移。示例2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute絕對定位</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.box {
display: inline-block;
border: 1px solid #000000;
background: red;
width: 100px;
height: 100px;
float: left;
color: white;
}
#three {
background: blue;
position: absolute;
top: 20px;
left: 20px;
}
</style>
</head>
<body>
<div class="box" id="one">One</div>
<div class="box" id="two">Two</div>
<div class="box" id="three">Three</div>
<div class="box" id="four">Four</div>
</body>
</html>
示例效果:

由上面的例子可以看到,絕對定位元素脫離了文檔流,并且當(dāng)設(shè)置了絕對定位的元素如果沒有非static的祖先元素,就會相對于body進(jìn)行定位。設(shè)置了absolute,fixed的元素會自動轉(zhuǎn)換為inline-block,也就是說即使在代碼中沒有添加
display: inline-block;,只要有position: absolute;,那么這個元素就會變?yōu)橐粋€inline-block。使用絕對定位在處理頁面元素居中問題上除了可以設(shè)置top,left,right,bottom屬性的具體值來達(dá)到水平居中,垂直居中,還可以將屬性設(shè)置為top:0;bottom:0;left:0;right:0;margin:auto;來達(dá)到居中的效果。示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute居中妙招</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.outer {
width: 300px;
height: 300px;
border: 1px solid red;
position: relative;
}
.inner{
width: 100px;
height: 100px;
border: 1px solid blue;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
</style>
</head>
<body>
<div class="outer">
<span class="inner"></span>
</div>
</body>
</html>
頁面顯示效果為:

通過示例可以看到,即使div內(nèi)層為span元素,但是設(shè)置了絕對定位后,可以添加width和height屬性,在代碼中,我們雖然沒有添加
display: inline-block;,但是,默認(rèn)地 span這個行內(nèi)元素 變成了 一個 inline-block。并且看到span元素相對于父元素水平居中且垂直居中。
用 absolute定位畫一個旋轉(zhuǎn)的太極
- 在線效果預(yù)覽:點(diǎn)擊預(yù)覽
- 使用在線工具:colorzilla
- 參考:keyframes
- 參考:animation-iteration-count
- 參考: animation-timing-function
使用absolute定位畫一個勻速旋轉(zhuǎn)的太極,代碼如下(非在線預(yù)覽的代碼):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>line-height</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
background: #666;
}
@keyframes spin {
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
.yinyang{
width: 200px;
height: 200px;
border-radius: 50%;
background: linear-gradient(to bottom, #ffffff 0%,#ffffff 50%,#000000 51%,#000000 100%);
position: relative;
animation-duration: 3s;
animation-name: spin;
animation-iteration-count: infinite;
animation-timing-function: linear;
margin: 0 auto;
top: 200px;
}
.yinyang::before{
content: '';
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
background: #FFFFFF;
box-sizing: border-box;
border: 40px solid black;
left: 0;
top: 25%;
}
.yinyang::after{
content: '';
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
background: #000;
box-sizing: border-box;
border: 40px solid #FFFFFF;
left: 50%;
top: 25%;
}
</style>
</head>
<body>
<div class="yinyang"></div>
</body>
</html>
fixed
fixed和absolute可謂是"本是同根生",因為它和absolute一樣,固定定位元素會脫離文檔流,但fixed和 absolute的參照物不同,fixed 會參照 viewport 視口 做絕對定位。例如在網(wǎng)頁中,我們滾動頁面,但一直固定在視口的廣告,這些懸浮的廣告就是使用fixed固定定位來實現(xiàn)的。
sticky
sticky即粘性定位,粘性定位可以被認(rèn)為是相對定位和固定定位的混合。粘性定位的元素如果產(chǎn)生了偏移,原位置仍然會在常規(guī)流中。它的偏移標(biāo)尺是最近的有滾動的祖先元素(設(shè)有overflow: scroll;),如果沒有,那么它的標(biāo)尺就是viewport即:視口。示例如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
div{
height: 100px;
border: 1px solid red;
position: sticky;
top: 50px;
}
</style>
</head>
<body>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<div>div</div>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
<p>111</p><p>111</p><p>111</p><p>111</p><p>111</p>
</body>
</html>
本例中,div元素相對于viewport粘性定位,在視口top:50px處,可以想象生成了一個高度為100px的"矩形"。在div沒有和"矩形"重合前,div元素處在文檔流,隨著頁面滾輪向下滾動,div與"矩形"完成了"重合"。這時,div則出現(xiàn)了固定定位的效果,即以視口為參照,固定在相對于視口top:50px處,但是div文檔流的位置仍然保留。
處理元素居中的問題
頁面布局中,最頻繁需要處理的問題就是元素居中的問題。無論是水平居中,還是垂直居中,常規(guī)的解決思路為:
- 搞清楚,誰相對于誰居中
- 將問題轉(zhuǎn)換為一個塊級元素相對于另一個塊級元素居中的問題
例如使用屬性 margin: 0 auto水平居中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>居中問題</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.out{
width: 300px;
height: 300px;
border: 1px solid black;
}
.inner{
width: 100px;
height: 100px;
border: 1px solid red;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="out">
<div class="inner"></div>
</div>
</body>
</html>
除了利用margin進(jìn)行居中,還可以使用相對定位和絕對定位,只要計算出偏移量就可以讓內(nèi)部的div相對于外部的div塊水平居中。偏移量left=父級塊的width×50%-內(nèi)部塊的width×50%,本例中為left:100px;偏移量top=父級塊的height×50%-內(nèi)部塊的height×50%,本例為:top:100px。本例使用CSS定位水平居中及垂直居中,代碼為:
*{
padding: 0;
margin: 0;
}
.out{
width: 300px;
height: 300px;
border: 1px solid black;
position: relative;
}
.inner{
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
top: 100px;
left: 100px;
}
除了上面計算具體的偏移量,還可以使用這樣的寫法:
*{
padding: 0;
margin: 0;
}
.out{
width: 300px;
height: 300px;
border: 1px solid black;
position: relative;
}
.inner{
width: 100px;
height: 100px;
border: 1px solid red;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
當(dāng)然,這只是一般的解決思路,并不能處理所有的問題,或者說,有些屬性和方法在使用上,更加便捷。例如:text-align屬性。text-align:center; text-align 屬性只有在塊級元素內(nèi)使用才能生效,CSS屬性定義行內(nèi)文本如何相對它的塊父元素對齊,它并不能控制塊元素自己的對齊,只能控制它的行內(nèi)內(nèi)容的對齊。如:<div><span>span</span></div> 如果希望行內(nèi)的文本"span" 在行內(nèi)水平居中,在塊級標(biāo)簽內(nèi)使用text-align即:div{text-align: center;}即可。如果一個div塊包裹著一個img圖片,也可以用text-align來設(shè)置圖片水平居中,但是一般情況下不會這么做。因為text-align 屬性顧名思義,是用來設(shè)置文本的一個屬性(text)。設(shè)置圖片水平居中的方法往往是在img標(biāo)簽外部再嵌套一個div標(biāo)簽。解決居中問題,更多的還需要不斷摸索和嘗試。
CSS浮動
- 案例一:使用浮動完成如下左右布局的效果:
image.png
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>案例一</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
background: #EFEFEF;
}
.clearfix:after{
content: '';
display: block;
clear: both;
}
.skills{
width: 940px;
margin: 0 auto;
}
.skills h2{
font-size: 30px;
color: #3D4451;
text-align: center;
margin-top: 60px;
margin-bottom: 30px;
}
.skills ol{
list-style: none;
background-color: #FFFFFF;
padding: 50px;
box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.75);
}
.skills ol>li{
width: 47%;
color: #3D4451;
box-sizing: border-box;
float: left;
margin-bottom: 30px;
}
.skills ol>li:nth-child(even){
float: right;
}
.skills ol>li:nth-child(5),
.skills ol>li:nth-child(6){
margin-bottom: 0;
}
.skills ol li .progressBar{
height: 5px;
background-color: #FAEAEA;
border-radius: 3px;
margin-top: 5px;
}
.skills ol li .progressBar>.progress{
width: 70%;
height: 100%;
background-color: #E6686A;
border-radius: 3px;
}
</style>
</head>
<body>
<section class="skills">
<h2>技能</h2>
<ol class="clearfix">
<li>
HTML5 & CSS3
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
JavaScript
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
jQuery
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
Vue
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
React
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
<li>
HTTP
<div class="progressBar">
<div class="progress"></div>
</div>
</li>
</ol>
</section>
</body>
</html>
本案例使用在線shadow生成器:cssmatic。
本案例中使用了浮動,完成了示例的左右排布的效果,使用浮動后,元素會脫離文檔流,出現(xiàn)"浮動溢出",也叫"高度塌陷",需要在元素浮動后"清除浮動"。清除浮動有以下幾種常用方法:
- 方法一
在浮動元素后,使用一個空元素例如:<div class="clear"></div> - 方法二
給浮動元素添加overflow: hidden; - 方法三
使用CSS3的:after偽元素這也是現(xiàn)在清除浮動最常用的方法。具體為在浮動的元素的父級元素添加class="clearfix"屬性,然后添加CSS清除浮動代碼:
.clearfix:after{
content: '';
display: block;
clear:both;
}
- 案例二:使用浮動完成如下布局:
image.png
案例效果為:點(diǎn)擊"所有","原生JS&CSS","框架",底部的滾動條發(fā)生滾動。代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>absolute絕對定位</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
background-color: #EFEFEF;
}
.clearfix:after{
content: '';
display: block;
clear: both;
}
.portfolio{
width: 940px;
margin: 60px auto 0;
text-align: center;
}
.portfolio h2{
color: #3D4451;
font-size: 30px;
margin-bottom: 30px;
}
.portfolio nav{
text-align: center;
display: inline-block;
cursor: pointer;
}
.portfolio ol{
list-style-type: none;
margin-bottom: 5px;
}
.portfolio ol>li{
font-size: 17px;
float: left;
margin-right: 40px;
}
.portfolio ol>li:nth-child(3){
margin-right: 0;
}
.progressBar{
height: 5px;
background: #FFFFFF;
border-radius: 3px;
}
.progressBar .progress{
width: 15%;
height: 100%;
background-color: #E6686A;
border-radius: 3px;
transition: all 0.5s;
}
.progressBar.state-1 .progress{
margin-left: 0;
width: 15%;
}
.progressBar.state-2 .progress{
margin-left: 74px;
width: 39%;
}
.progressBar.state-3 .progress{
margin-left: 209px;
width: 18%;
}
</style>
</head>
<body>
<section class="portfolio">
<h2>作品集</h2>
<nav>
<ol class="clearfix">
<li id="li1">所有</li>
<li id="li2">原生JS & CSS</li>
<li id="li3">框架</li>
</ol>
<div id="progressBar" class="progressBar state-1">
<div class="progress"></div>
</div>
</nav>
<script>
li1.onclick = function () {
progressBar.className = 'progressBar state-1'
}
li2.onclick = function () {
progressBar.className = 'progressBar state-2'
}
li3.onclick = function () {
progressBar.className = 'progressBar state-3'
}
</script>
</section>
</body>
</html>

