面布局中最常見的需求就是元素或者文字居中了,但是根據場景的不同,居中也有簡單到復雜各種不同的實現方式,本篇就帶大家一起了解下,各種場景下,該如何使用 CSS 實現居中
頁面布局中最常見的需求就是元素或者文字居中了,但是根據場景的不同,居中也有簡單到復雜各種不同的實現方式,有的特定場景下可能還有一些稀奇古怪的bug,本篇就帶大家一起了解下,各種場景下,該如何使用 CSS 實現居中
根據應用場景,我們把居中的需求分為與盒子相關的居中和內容相關的居中,盒子相關的居中比較好理解,也是我們比較常見的應用場景,內容相關實際也很常用,只是平時注意得比較少,但如果對概念理解不清晰,實現出來的效果可能經常會偏差那么一丟丟,然后就開始窮舉法解決問題了,這里也是我們本次討論的重點
盒子模型相關的居中基本上可以根據盒子有沒有給定寬高度分為分為兩大類
我們先預設一下頁面結構設置樣式
<div class="parent">
<div class="children"></div>
</div>
給定寬高的場景比較簡單,能獲取到元素的寬高那么直接計算子元素需要的偏移量就可以了,或者借助表格元table-cell現居中,但是大部分時候我們遇到的場景是不確定,并且不確定的解決方案可以向下兼容給定寬高的,這里就不過多贅敘了,直接看下一種情況
寬高不固定時,主流的解決方案有兩種,一種是使用彈性布局,另一種是使用定位
.parent {
display: flex;
justify-content: center;
align-items: center;
}
.children {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.parent {
position: relative;
}
.children {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
基本現在瀏覽器對彈性布局的支持已經很好了,也是主流的居中解決方案,放心用即可
提到內容,最常想到的就是文字,圖片,icon這些,這些元素的對齊大部分時候都是根據基準線來實現的baseline,可以使用設置行高line-height(這種方案有瑕疵,后面會詳細介紹),文字居中屬性text-align來實現,當然也可以轉換成彈性布局來實現居中,都是可以的
這里我們舉一個稍微特殊點的案例來進行分析,看應該如何進行居中
結構
<div class="parent">
<span class="children1">HelloWorld</span>
<span class="children2">世界你好</span>
</div>
樣式
.parent {
width: 100%;
height: 100px;
background-color: aquamarine;
}
.children1 {
font-size: 42px;
background-color: red;
}
.children2 {
font-size: 18px;
background-color: yellow;
}
.parent {
display: flex;
justify-content: center;
align-items: center;
}
簡單省心,達到效果
.parent {
line-height: 100px;
text-align: center;
}
這個時候就會發現,水平方向使用text-align來居中沒有問題,但是垂直方向出來的效果就和預想的有偏差了,我們先來分析為什么會這樣
line-height 等于元素高度的時候文本并不是真的居中了,而是看著居中了,當元素高度和font-size差距較大的時候,這種不是真正的居中就越發的明顯
line-height,指的是兩行文字基線之間的距離(這說法實際有點爭議,也可以字面理解就行的高度),如果 line-height 剛好等于盒子的高度,那么意味著基線就在盒子一半的位置,這樣就實現了內容的垂直居中
我們在用line-height實現文字垂直居中的時候,有個前提,一個是單行元素,另外沒有多種內聯元素(不同大小的圖片,文字,icon等等),不然你會在對齊內聯元素的時候遇到很多麻煩
那么如何解決這個問題呢,首先要了解,行內元素在垂直方向的定位,是基于什么,先來看一張圖,可能大家在其它地方也看過,輔助我們理解
在父元素定義了line-height的條件下,vertical-align的作用是讓(inline/inline-block)子元素依據父元素的基點對齊。
根據上圖示意,不難看出,不管文字的大小,它們都是基于基線(baseline)來確定垂直方向的定位(可看helloWorld和世界你好的底部是在同一水平線的)
看到這里有的同學應該就想到了,可以通過設置vertical-align修改對齊方式不就好了嗎?我們來試試先把世界你好的設置下vertical-align: middle試一試
可以看到耶,為什么沒有效果,這時可能同學就要急了,但先別急,你在把HelloWorld也設置一下試試
.children1 {
font-size: 42px;
background-color: red;
vertical-align: middle;
}
.children2 {
font-size: 24px;
background-color: yellow;
vertical-align: middle;
}
這個時候效果就出來了,怎么樣,是不是很神奇~
我們再來一起看 vertical-align
vertical-align 屬性設置元素的垂直對齊方式。該屬性定義行內元素的基線相對于該元素所在行的基線的垂直對齊
如果我們只設置一個元素的 vertical-align 屬性的化,那么就是后設置的和前面的對齊,我們可以把這兩個大小字體調換下順序,然后單獨給HelloWorld設置middle
可以看到這個字體是有點向下偏移一點點,原因就是這時它是跟小字號的baseline對齊了
我們同樣把兩個都設置成middle再看下
這時就正常啦~簡單總結一下,就是在使用vertical-align這個屬性進行垂直對齊居中時,一定要注意,如果有多個元素,一定要保證他們的基準線是一致的,這樣才能達到我們想要的效果
當父div的行高等于自身高度時,內部的行內元素會上下居中顯示。行內塊沒有固定高度時也會上下居中顯示。所以需要對父div的 line-height 進行調整。利用定位屬性(top、left、right、bottom)百分比的模式。若為100%,則代表偏移的長度為父div的高度(寬度)的100%。定位屬性top和bottom(或是left和right)值分別設置為0,但子div有固定高度(寬度),并不能達到上下(左右)間距為0,此時給子div設置 margin:auto 會使它居中顯示。
轉載自喜歡JS的無名小站
例如 一個父div(w:100%;h:400px)中有一個子div(w:100px;100px;)。讓其上下左右居中。
利用表格單元格的居中屬性。
父div外層配置一個div,同時設置為表格元素 (display: table),寬度為100%
父div配置為表格單元格元素 (display: table-cell)
父div配置居中屬性(vertical-align: middle),使子div上下居中
子div通過margin配置左右居中(margin-left:auto; margin-right:auto)
<style> * {margin: 0; padding: 0; box-sizing: border-box;} .table {display: table; width: 100%;} .father {display: table-cell; vertical-align: middle;} .son {margin: auto;} </style> <body> <div class="table" > <div class="father" style="width: 100%; height: 400px; border: 1px solid rebeccapurple;"> <div class="son" style="width: 100px; height: 100px;background: palegreen;"></div> </div> </div> </body>
注:
表格單元格比較特殊,如果只有一個單元格時,它的寬度默認會占父級(table|tr)寬度的100%;
table默認寬度不會撐開,需要手動配置width:100%;
當父div的行高等于自身高度時,內部的行內元素會上下居中顯示。行內塊沒有固定高度時也會上下居中顯示。通過文本居中屬性text-align:center
,可以使內部行內元素或行內塊元素左右居中顯示。
子div設定為行內塊元素(display:inline-block);
父div設置行高(line-height)使子div上下居中
父div設置文本居中(text-align:center)使子div左右居中。
<style> * {margin: 0; padding: 0; box-sizing: border-box;} .father {line-height: 500px; text-align: center; font-size: 0;} .son { display: inline-block; /* display: inline-flex; display: inline-grid; display: inline-table; */ } </style> <body> <div class="father" style="width: 100%; height: 400px; border: 1px solid rebeccapurple;"> <div class="son" style="width: 100px; height: 100px;background: palegreen;"></div> </div> </body>
注: 行高如果設置為當前父div的高度(400px)的話,有固定高度的子div并不會居中顯示的,問題出在瀏覽器默認將其當做文本居中的,即把它當做了一段文本(chrome默認font-size:16px;hight:21px)進行居中,沒把它當做高度100px進行居中。所以需要對父div的line-height
進行調整。以font-size:0
(對應的字體高度為0)為例子,則需要line-height增加一個子div的高度(400px + 100px;)。
利用定位屬性(top、left、right、bottom)百分比的模式。若為100%,則代表偏移的長度為父div的高度(寬度)的100%。
父div標記下定位(position:relative|absolute|fixed);子div絕對定位(position:absolute)
子div上下居中:top:50%;margin-top:-h/2;
或是 bottom:50%;margin-bottom:-h/2;
;
子div左右居中: left:50%;margin-left:-w/2
或是 right:50%;margin-right:-w/2
;
<style> * {margin: 0; padding: 0; box-sizing: border-box;} .father {position: relative;} .son {position: absolute;bottom:50%;margin-bottom: -50px;left: 50%;margin-left: -50px; } </style> <body> <div class="father" style="width: 100%; height: 400px; border: 1px solid rebeccapurple;"> <div class="son" style="width: 100px; height: 100px;background: palegreen;"></div> </div> </body>
定位屬性top和bottom(或是left和right)值分別設置為0,但子div有固定高度(寬度),并不能達到上下(左右)間距為0,此時給子div設置margin:auto會使它居中顯示。
父div標記下定位(position:relative|absolute|fixed|sticky);子div絕對定位(position:absolute)
子div上下居中:top:0;bottom:0;margin-top:auto;margin-bottom:auto
子div左右居中:left:0;right:0;margin-left:auto;margin-right:auto
<style> * {margin: 0; padding: 0; box-sizing: border-box;} .father {position: relative;} .son {position: absolute; top: 0; bottom:0; left: 0; right: 0; margin: auto} </style> <body> <div class="father" style="width: 100%; height: 400px; border: 1px solid rebeccapurple;"> <div class="son" style="width: 100px; height: 100px;background: palegreen;"></div> </div> </body>
彈性盒子,自帶的一個居中功能
<style> * {margin: 0; padding: 0; box-sizing: border-box;} .father {display: flex; align-items: center} .son {margin: auto} </style> <body> <div class="father" style="width: 100%; height: 400px; border: 1px solid rebeccapurple;"> <div class="son" style="width: 100px; height: 100px;background: palegreen;"></div> </div> </body>
flex兼容性,以及存在的已知問題
方法二和方法三兼容性要比其它好些
Can I use
css-vertical-center-solution
CSS實現垂直居中的5種方法--前端觀察
● ●
在網頁上使 HTML 元素居中看似一件很簡單的事情. 至少在某些情況下是這樣的,但是復雜的布局往往使一些解決方案不能很好的發揮作用。
在網頁布局中元素水平居中比元素垂直居中要簡單不少,同時實現水平居中和垂直居中往往是最難的?,F在是響應式設計的時代,我們很難確切的知道元素的準確高度和寬度,所以一些方案不大適用。據我所知, 在CSS中至少有六種實現居中的方法。我將使用下面的HTML結構從簡單到復雜開始講解:
<div class="center"> <img src="jimmy-choo-shoe.jpg" alt></div>
鞋子圖片會改變,但是他們都會保持500px
X500px
的大小。 HSL colors 用于使背景顏色保持一致。
有時顯而易見的方案是最佳的選擇:
div.center { text-align: center; background: hsl(0, 100%, 97%);
}
div.center img { width: 33%; height: auto;}
這種方案沒有使圖片垂直居中:你需要給<div>
添加padding
或者給內容添加margin-top
和margin-bottom
使容器與內容之間有一定的距離。
這種方式實現水平居中和上面使用text-align的方法有相同局限性。
div.center { background: hsl(60, 100%, 97%);}
div.center img { display: block; width: 33%; height: auto; margin: 0 auto;}
注意: 必須使用display: block
使margin: 0 auto
對img
元素生效。
使用 display: table-cell
, 而不是使用table
標簽; 可以實現水平居中和垂直居中,但是這種方法需要添加額外的元素作為外部容器。
<div class="center-aligned"> <div class="center-core"> <img src="jimmy-choo-shoe.jpg"> </div></div>
CSS:
.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+瀏覽器上生效。
這種 方案 有非常好的跨瀏覽器支持。有一個缺點就是必須顯式聲明外部容器元素的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;}
Stephen在他的 博客 中演示了這種方案的幾種變化。
Chris Coiyer 提出了一個使用 CSS transforms 的新方案。 同樣支持水平居中和垂直居中:
.center { background: hsl(180, 100%, 97%); position: relative; min-height: 500px;}.center img { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 30%; height: auto;}
但是有以下幾種缺點:
CSS transform 在部分就瀏覽器上需要使用 前綴。
不支持 IE9 以下的瀏覽器。
外部容器需要設置height
(或者用其他方式設置),因為不能獲取 絕對定位 的內容的高度。
如果內容包含文字,現在的瀏覽器合成技術會使文字模糊不清。
當新舊語法差異和瀏覽器前綴消失時,這種方法會成為主流的居中方案。
.center { background: hsl(240, 100%, 97%); display: flex; justify-content: center; align-items: center;}.center img { width: 30%; height: auto;}
在很多方面 flexbox 是一種簡單的方案, 但是它有新舊兩種語法以及早期版本的IE缺乏支持 (盡管可以使用 display: table-cell
作為降級方案)。
現在規范已經最終確定,現代瀏覽器也大都支持,我寫了一篇詳細的教程 教程。
在某些情況下比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)); }
我在 這篇文章 中詳細講解了calc
。
這種方案和flex一樣有許多相同的缺點: 雖然在現代瀏覽器中有良好的支持,但是在較早的版本中仍然需要瀏覽器前綴,并且不支持IE8。
.center img { width: 40%; height: auto; position: absolute; top: calc(50% - 20%); left: calc(50% - 20%);}
當然還有 其他更多的方案。理解這六種方案之后,web開發人員在面對元素居中的時候會有更多的選擇。
關注“網頁設計自學平臺”訂閱號回復以下|關鍵字|
|dw教程|js教程|淘寶案例|軟件下載|搜狐案例|網站模板
|ps教程|ai教程 |ui教程|騰訊案例| ae教程 |字體下載|
|上課素材|前端特效|華潤萬家案例|最新dw案例|
戳“閱讀原文”入群獲取最新高清前端視頻!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。