[TOC] 在CSS中對元素進行 水平居中 是非常簡單的:如果它是一個行內元素,就對它的父元素應用 ;如果它是一個塊級元素,就對它自身應用 。然而要對一個元素進行垂直居中,就有點束手無策了,本文介紹了幾種常用的垂直居中方法以供參考! 一、表格佈局法 利用表格的vertical align屬性,當然首 ...
[TOC]
在CSS中對元素進行水平居中是非常簡單的:如果它是一個行內元素,就對它的父元素應用text-align:center
;如果它是一個塊級元素,就對它自身應用margin:auto
。然而要對一個元素進行垂直居中,就有點束手無策了,本文介紹了幾種常用的垂直居中方法以供參考!
一、表格佈局法
利用表格的vertical-align屬性,當然首先將顯示方式設置為表格,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.wrap{
display:table;
width: 400px;
height: 200px;
border: 1px solid red;
}
.cell{
display:table-cell;
/*讓其內容也水平居中*/
text-align: center;
vertical-align:middle;
}
.content{
border: 1px solid green;
}
</style>
</head>
<body>
<div class="wrap">
<div class="cell">
<div class="content">
看,我又居中沒?
</div>
</div>
</div>
</body>
</html>
這種方法需要在要居中的元素外層再添加一層包裹,如上面的.cell,好處是不用知道需要居中的元素是什麼東西,比如上面的.content標簽,在css中未對其位置進行任何設置。
二、基於行內塊的解決方案(來自於第二篇參考文獻)
這種方法確實講究技巧,在實際實施中估計也不常用,但還是有必要介紹一下。具體思路是在包裹元素內設置一個“ghost”元素,使其高度為包裹元素的100%,然後同時設置“ghost”元素和居中元素vertical-align:middle
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.wrap{
width: 400px;
height: 200px;
border: 1px solid red;
text-align: center;
}
.wrap:before{
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.content{
display: inline-block;
vertical-align: middle;
width: 150px;
height: 50px;
border: 1px solid green;
}
</style>
</head>
<body>
<div class="wrap">
<div class="content">
看,我居中沒?
</div>
</div>
</body>
</html>
三、基於絕對定位的解決方案
1.絕對定位+負的外邊距
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.wrap{
position: relative;
width: 400px;
height: 200px;
border: 1px solid red;
}
.content{
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 50px;
margin-top: -25px;
margin-left: -50px;
border: 1px solid green;
}
</style>
</head>
<body>
<div class="wrap">
<div class="content">
看,我居中沒?
</div>
</div>
</body>
</html>
使用這種方法要求居中的元素具有固定的寬度和高度。
上面的方法本質上做了這樣幾件事情:先把要居中的元素的左上角放在已定位祖先元素的正中心,然後再利用負外邊距把它向左、向上移動(移動距離相當於自身寬高的一半),從而把元素的正中心放置在祖先元素的正中心。藉助CSS3中強大的calc()函數(當然實際實施過程中要考慮瀏覽器的相容性),.content的樣式還可以設置成:
<style type="text/css">
.wrap{
position: relative;
width: 400px;
height: 200px;
border: 1px solid red;
}
.content{
position: absolute;
top: calc(50% - 25px);
left: calc(50% - 50px);
width: 100px;
height: 50px;
border: 1px solid green;
}
</style>
註意:表達式中有“+”和“-”時,其前後必須要有空格,如"widht: calc(12%+5em)"這種沒有空格的寫法是錯誤的calc函數的具體用法可以參考:
CSS3的calc()使用
2.絕對定位+margin:auto
實現原理:利用css定位規則,設置左右、上下方向定位為0,margin為auto,讓css根據定位計算margin值,用hack的方式實現居中。居中塊的尺寸需要固定。
寸需要可控
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.wrap{
position: relative;
width: 400px;
height: 200px;
border: 1px solid red;
}
.content{
position: absolute;
width: 150px;
height: 50px;
margin: auto;
top:0;left: 0;bottom: 0;right: 0;
border: 1px solid green;
}
</style>
</head>
<body>
<div class="wrap">
<div class="content">
看,我居中沒?
</div>
</div>
</body>
</html>
上面提到的兩種絕對定位的方案最大的局限就是它要求元素的寬度和高度固定。下麵介紹的第三種基於絕對定位的方案則不會出現這個問題,對於需要居中的元素寬高是否固定沒有硬性要求,這樣居中元素的尺寸就由其內容確定了。
3.絕對定位+transform反向偏移
還是上面的例子將內部元素的設置負的外邊距的那兩句改成
<style type="text/css">
.wrap{
position: relative;
width: 400px;
height: 200px;
border: 1px solid red;
}
.content{
position: absolute;
top: 50%;
left:50% ;
border: 1px solid green;
transform: translate(-50%,-50%);
}
</style>
使用這種方法對於居中元素寬高沒有要求的原因是在translate()變形函數中使用百分比時,是以這個元素本身的寬度和高度為基準進行換算和移動的。
當然了,使用基於絕對定位的方法一定要先知道你要居中的對象是哪一個,這樣才能對其設置絕對定位,這是與表格佈局法明顯不同的地方。
四、基於視口單位的解決方案(僅適用於基於視口的居中)
假如不想使用絕對定位,仍然可以採用translate()技巧來讓元素以其自身寬高一半進行偏移,但是如果使用絕對定位,也就無法使用left和top使元素左上角位於容器正中心。
我們的第一反應很可能是用margin屬性的百分比來實現。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.content{
border: 1px solid green;
margin: 50% auto 0;
transform: translateY(-50%);
}
</style>
</head>
<body>
<div class="content">
看,我居中沒?
</div>
</body>
</html>
實際上的結果卻如上圖所示,元素到了視口的下方。原因在於margin的百分比是以父元素的寬度作為基準的。在《CSS揭秘》這本大作中提到了一種方法可以正確使元素基於視口居中,該方法採用視口單位vh作為長度單位。1vh表示視口單位的1%。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.content{
border: 1px solid green;
width: 150px;
margin: 50vh auto 0;
transform: translateY(-50%);
}
</style>
</head>
<body>
<div class="content">
看,我居中沒?
</div>
</body>
</html>
五、基於使用css3彈性佈局(Flexbox)的解決方案
css3的伸縮盒佈局簡直是一切佈局的救星,遺憾的是,很多老瀏覽器不支持,哎哎哎哎!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.wrap{
display: flex;
width: 400px;
height: 200px;
border: 1px solid red;
}
.content{
margin: auto;
border: 1px solid green;
}
</style>
</head>
<body>
<div class="wrap">
<div class="content">
看,我居中沒?
</div>
</div>
</body>
</html>
想讓.content居中就是這麼簡單,使包裹元素display: flex;
要居中的元素margin: auto;
這樣水平和垂直方向都居中了,而且對於居中元素的寬高也沒有要求。
Flexbox還有另一個好處在於,它可以在不知道需要居中的元素是什麼的情況下使居中元素居中,就像方法一的效果一樣,具體實現是藉助:align-items和justify-content
仍然用上面的例子.
<style type="text/css">
.wrap{
display: flex;
align-items: center;
justify-content: center;
width: 400px;
height: 200px;
border: 1px solid red;
}
.content{
border: 1px solid green;
}
</style>
實現效果相同。
五、單行文本時的居中
可以利用line-height屬性與元素高度相同
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.content{
width: 150px;
height: 100px;
line-height: 100px;
text-align: center;
border: 1px solid green;
}
</style>
</head>
<body>
<div class="content">
看,我居中沒?
</div>
</body>
</html>
參考:
CSS揭秘(英文原版:CSS Secrets)
Centering in the Unknown