css居中
- CSS居中情況:
- 網頁元素水平居中;horizontally
- 網頁元素垂直居中;vertically
- 網頁元素同時實現水平居中和垂直居中;
更新:2018.6.17
一、水平居中
lineheight
absolute + 負margin
absolute + margin auto
absolute + calc
absolute + transform
table
css-table
flex
(一)行內或類行內元素
- 實現方式:使用
text-align
實現水平居中
這種方法可以讓 inline/inline-block/inline-table/inline/flex 等類型的元素實現居中
- 代碼:
div.center {
text-align: center;
background: hsl(0, 100%, 97%); // HSL colors 用於使背景顏色保持一致。
div.center img {
width: 33%;
height: auto;
}
- 缺點:這種方案沒有使圖片垂直居中:需要給
<div>
添加 padding 或者給內容添加 margin-top 和 margin-bottom使容器與內容之間有一定的距離。
(二)塊級元素
(1)單個塊級元素:
- 實現方案:使用
margin: auto
居中
設置方法:
margin-left
和margin-right
爲 auto(前提是已經爲元素設置了適當的 width 寬度,否則塊級元素的寬度會被拉伸爲父級容器的寬度)
- 示例代碼
<main class="block-parent">
<div class="block-horizon-center">我是一個居中的塊級元素</div>
</main >
.block-horizon-center {
width: 200px;
margin-left: auto;
margin-right: auto;
/* U can also do this */
margin: 0 auto;
}
- 使用
margin:0 auto;
注意: 必須使用display: block使 margin: 0 auto對img元素生效。
div.center {
background: hsl(60, 100%, 97%);
}
div.center img {
display: block;
width: 33%;
height: auto;
margin: 0 auto;
}
- 缺點:這種方式實現水平居中和上面使用text-align的方法有相同侷限性。
(2)多個塊級元素
實現方式:多個塊級元素在同一水平線上居中,通過設置display 值。
具體實現
方法1:設置
display:inline-block
,
方法2:設置display:flexbox
- 示例代碼
<main class="inline-block-horizon-center">
<div>我是一個居中的塊級元素。</div>
<div>我是一個居中的塊級元素,而且我有更多的內容。</div>
<div>我是一個居中的塊級元素。</div>
</main>
<main class="flex-horizon-center">
<div>我是一個居中的塊級元素。</div>
<div>我是一個居中的塊級元素,而且我有更多的內容。</div>
<div>我是一個居中的塊級元素。</div>
</main>
main div {
max-width: 125px;
}
.inline-block-horizon-center {
text-align: center;
}
.inline-block-horizon-center div {
display: inline-block;
/* U may like do this although it's not necessary */
vertical-align: middle/top;
}
.flex-horizon-center {
display: flex;
justify-content: center;
}
二、垂直居中
(一)行內或類行內元素
(1)單行 single line
方案(1):使用 padding
屬性
實現方法
給元素添加等值的
padding-top
和padding-bottom
示例代碼
.link {
padding-top: 30px;
padding-bottom: 30px;
}
方案(2):
- 實現方法:使用
line-height
屬性
已知文本不會換行,讓
line-height
和height
的值相等
- 示例代碼
.single-inline-parent {
height: 30px;
line-height: 30px;
white-space: nowrap; /* 強制不換行 */
overflow: hidden; /* 文本溢出時隱藏 */
text-overflow: ellipsis; /* 溢出內容爲省略號 */
}
(2)多行 multiple lines
情況一:多行不定高
- 使用 padding 屬性
- 使用 flexbox 相關屬性
- 使用“幽靈元素”
方案(1):使用 padding
屬性
實現方法:設置
padding-top
和padding-bottom
實現垂直居中示例代碼
<div>
<span class="multi-line-vertical-center">
I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.I'm vertically centered multiple lines of text.
</span>
</div>
.multi-line-vertical-center {
padding-top: 30px;
padding-bottom: 30px;
/* 也可以這樣寫 */
padding: 30px 10px;
overflow: hidden;
}
方案(2): 使用 flexbox
實現方法:使用 flexbox 實現垂直居中,
因爲對於父級容器爲 display: flex 的元素來說,它的每一個子元素都是垂直居中的
示例代碼
<div class="flex-center">
<p>我是flexbox容器中垂直居中的多行文本。</p>
</div>
.flex-center {
display: flex;
justify-content: center;
width: 240px;
}
方案(3):使用 "幽靈元素"(ghost element)
- 實現方式:使用 僞元素
首先,在需要垂直居中的元素上添加僞元素,將僞元素的
height
等於父級容器的height
然後,爲文本添加vertical-align: middle;
- 示例代碼
<div class="ghost-center">
<p>I'm vertically centered multiple lines of text in a container. Centered with a ghost pseudo element</p>
</div>
.ghost-center {
position: relative;
}
.ghost-center::before {
content: " ";
display: inline-block;
height: 100%;
width: null;
vertical-align: middle;
}
.ghost-center p {
display: inline-block;
vertical-align: middle;
/* 如果這個不起作用,可能需要把 width 設置爲:比如 width: 100px; */
}
情況二:多行定高
父級元素定高時,採用的方法
方案(1):使用 padding
屬性
- 實現方法:對於多行文本,同樣可以使用等值 padding-top 和 padding-bottom 的方式實現垂直居中。
方案(2):使用 table-cell
和 vertical-align
屬性
- 實現方法:爲文本設置一個類似 table-cell 的父級容器,然後使用 vertical-align 實現垂直居中
注意:IE8- 版本無效
<div class="center-table">
<p>I'm vertically centered multiple lines of text in a CSS-created table layout.</p>
</div>
.center-table {
display: table;
width: 240px;
height: 250px;
}
.center-table p {
display: table-cell;
vertical-align: middle;
}
- 方法3:可以使用
flexbox
實現垂直居中,對於父級容器爲display: flex
的元素來說,它的每一個子元素都是垂直居中的:
.flex-center-vertically {
display: flex;
justify-content: center;
flex-direction: column;
height: 400px;
}
(二)塊級元素
情況一:元素定高
- 實現方法:設置絕對定位的
top
、margin-top
值
首先,讓元素 絕對定位 到父容器的中心點,
然後,設置 負向margin
,負值的大小爲其自身高度的一半
。注意::
如果父元素設置了padding
,則計算 負向margin
時,負值的大小爲:其自身高度的一半再加上父元素的內邊距
- 示例代碼
<main>
<div>
我是一個具有固定高度的塊級元素,在我的父級元素中垂直居中。
</div>
</main>
main {
position: relative;
}
main div {
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
情況二:元素的高度未知
無法獲知元素的具體高度是非常常見的一種狀況,比如:視區寬度變化,會觸發佈局重繪,從而改變高度;對文本施加不同的樣式會改變高度;文本的內容量不同會改變高度;當寬度變化時,對於寬高比例固定的元素(比如圖片),也會自動調整高度……
方案(1):
- 實現方法:定位屬性
positin
和 變換
首先,需要先將元素定位到容器的中心位置,
然後,使用transform
的translate
屬性,將元素的中心和父容器的中心重合
- 示例代碼
<main>
<div>
I'm a block-level element with an unknown height, centered vertically within my parent.
</div>
</main>
main {
position: relative;
}
main div {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
方案(2):使用 flexbox
實現方法:使用
flexbox
實現垂直居中:示例代碼
<main>
<div>
I'm a block-level element with an unknown height, centered vertically within my parent.
</div>
</main>
main {
display: flex;
flex-direction: column;
justify-content: center;
}
(三)行內/塊級元素
- 使用
transform
屬性,從單行文本、段落到box,都會垂直對齊。
.verticalcenter{
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
}
問題:目前瀏覽器對Transform的支持是需要關注的,Chrome 4, Opera 10, Safari 3, Firefox 3, and Internet Explorer 9均支持該屬性。
三、實現水平居中且垂直居中
- 三種類型:
寬高固定元素、寬高不固定元素、flex
方案(1):使用 table-cell
居中
使用
display: table-cell
,可以實現水平居中和垂直居中,外部容器設置爲行內塊元素;適用情況:
注意:這種方法需要添加額外的元素作爲外部容器。、
示例代碼
<div class="center-aligned">
<div class="center-core">
<img src="jimmy-choo-shoe.jpg">
</div>
</div>
.center-aligned {
display: table;
background: hsl(120, 100%, 97%);
width: 100%;
}
.center-core {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.center-core img {
width: 33%;
height: auto;
}
- 注意:爲了使div 不折疊必須加上 width: 100%,外部容器元素也需要加上一定高度使得內容垂直居中。給html和body設置高度後,也可以使元素在body垂直居中。此方法在IE8+瀏覽器上生效。
方案(2):使用 absolute
定位居中
- 這種方案有非常好的跨瀏覽器支持。
注意:有一個缺點就是必須顯式聲明外部容器元素的
height
:
- 示例代碼
.absolute-aligned {
position: relative;
min-height: 500px;
background: hsl(200, 100%, 97%);
}
.absolute-aligned img {
width: 50%;
min-width: 200px;
height: auto;
overflow: auto;
margin: auto;
position: absolute;
top: 0; left: 0;
bottom: 0; right: 0;
}
- 實現方法2:
首先,設定父級容器爲相對定位的容器,
.
然後,設定子元素絕對定位的位置:
position: absolute;
top: 50%;
`left: 50%
;
.
最後,使用負向 margin 實現水平和垂直居中,margin 的值爲寬高(具體的寬高需要根據實際情況計算padding
)的一半。
.parent {
position: relative;
}
.child {
width: 300px;
height: 100px;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
margin: -70px 0 0 -170px;
}
- 補充:視口居中:模態窗
內容元素:position: fixed,z-index: 999,記住父容器元素 position: relative
- 示例代碼
.Absolute-Center.is-Fixed {
width: 50%;
height: 50%;
overflow: auto;
margin: auto;
position: fixed;
top: 0; left: 0; bottom: 0; right: 0;
z-index: 999;
}
(三)寬高不固定元素
- 使用
translate
居中 - 代碼:
<main>
<div>
我是一個具有未知高度和寬度的塊級元素,在我的父級中垂直居中。
</div>
</main>
main {
position: relative;
}
main div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
缺點:
- CSS transform 在部分就瀏覽器上需要使用 前綴。
- 不支持 IE9 以下的瀏覽器。
- 外部容器需要設置height (或者用其他方式設置),因爲不能獲取 絕對定位 的內容的高度。
- 如果內容包含文字,現在的瀏覽器合成技術會使文字模糊不清。
- 使用transform 有一個缺陷,就是當計算結果含有小數時(比如 0.5),會讓整個元素看起來是模糊的,一種解決方案就是爲父級元素設置 transform-style: preserve-3d; 樣式:
示例代碼
.parent-element {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
}
(四)使用 flexbox
居中
- 示例代碼
<main>
<div>
我是一個具有未知寬度和高度的塊級元素,在我的父級中垂直居中。
</div>
</main>
main {
display: flex;
justify-content: center;
align-items: center;
}
(五)使用calc居中
在某些情況下比flexbox更全面:
示例代碼
.center {
background: hsl(300, 100%, 97%);
min-height: 600px;
position: relative;
}
.center img {
width: 40%;
height: auto;
position: absolute;
top: calc(50% - 20%);
left: calc(50% - 20%);
}
calc
允許你基於當前的頁面佈局計算尺寸。在上面的簡單計算中, 50% 是容器元素的中心點,但是如果只設置50%會使圖片的左上角對齊div的中心位置。 我們需要把圖片向左和向上各移動圖片寬高的一半。計算公式爲:
top: calc(50% - (40% / 2));
left: calc(50% - (40% / 2));
- 在現在的瀏覽其中你會發現,這種方法更適用於當內容的寬高爲固定尺寸:
.center img {
width: 500px; height: 500px;
position: absolute;
top: calc(50% - (300px / 2));
left: calc(50% - (300px – 2));
}
- 這種方案和flex一樣有許多相同的缺點: 雖然在現代瀏覽器中有良好的支持,但是在較早的版本中仍然需要瀏覽器前綴,並且不支持IE8。
.center img {
width: 40%; height: auto;
position: absolute;
top: calc(50% - 20%);
left: calc(50% - 20%);
}