導語:元素居中對齊在很多場景看上去很和諧很漂亮。除此之外,對於前端開發面試者的基礎也是很好的一個考察點。下面跟著作者的思路,一起來看下吧。
場景分析
- 一個元素,它有可能有背景,那我要它的背景居中對齊
- 一個元素,它還有可能有個父級元素,那我要它居中於其父級元素
- 一個元素,它也有可能還帶有一些子內容,我要讓它的子內容居中
場景建模
根據場景分析提出的一些假設,我們試著去建立對應的模型,下面是分別根據上面的三個場景設計的相關模型。
- 搞父子元素居中對齊
- 搞元素背景居中對齊
- 搞元素內容居中對齊
場景實現
相關說明
為了統一,這裡我們定義一個400*400px
的帶著黑色邊框粉紅色身體的類名為.box
的父容器,它有可能會有一個200*200px
的帶著原諒色身體的類名為.box-son
的子容器。這裡為了效果能夠直觀且明顯,筆者故意把背景圖片的原始大小處理成小於宿主畫素的大小。好吧,我們開始吧!
背景居中
我們做這樣一件事,在一個div容器中,我們通過background-image
屬性引入一張背景,之後我們期望這張引入的背景呢,它能夠水平垂直居中於宿主元素。
這裡介紹兩個屬性background-repeat
和background-position
,如果你初中英語好的話,我想你也應該知道了,這裡字面意思就是這個屬性的意思。一個是設定背景圖片怎麼鋪宿主元素(預設時鋪滿的)更美麗的,另一個是設定背景圖片相對於宿主元素的的位置,你可以傳畫素、百分比、相關方向單詞(top、bottom、left、right)給它。當其為百分比的時候,它的計算公式如下:
(container width - image width) * (position x%) = (x offset value)
(container height - image height) * (position y%) = (y offset value)
簡言之,就是宿主元素的寬高減去圖片寬高乘以相關百分比就是相對於宿主元素左上角那個原點的位置。
在背景圖片不重複的情況下,你想讓一張圖片居中於宿主元素的方法,可以有background-postion: center center
、background-postion: 50%, 50%
,也可以簡寫成background-postion: center
或者background-postion: 50%
所以,在樓上這些前提下,我們大致能夠歸出一個類,形如:
/** 這裡以複雜寫法的百分比為例, 分別代表距離宿主元素左上角的x和y軸的距離**/
.box-son {
background-repeat: no-repeat;
background-position: 50%, 50%;
}
文字內容居中
如果宿主元素的內容是文字之類的,我們期望它能夠居中於宿主元素,這裡用到兩個屬性,一個是text-align
,一個是line-height
。text-algin:center
可以使內容水平居中於宿主元素,將line-height
設定成宿主元素相同的高度,便可讓宿主元素垂直居中。
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example11
子元素居中於父元素
相關說明
這裡解釋下,父相子絕,這個是我閹割了“父級元素相對定位,子級元素絕對定位”這句話濃縮後的叫法。後面出現這個概念我就不過多再進行重複介紹了。
父相子絕 + margin: auto
父元素相對定位子元素絕對定位後,設定其top、right、bottom、left
都為0,之後我們將其的margin
設定為auto
。這樣子的話,父級元素與子級元素他們之間空出來的部分都會被這個margin
均勻撐開。
.box-position {
position: relative;
}
.box-example1 {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example1
父相子絕 + 負值margin
父元素相對定位子元素絕對定位後,子元素設定top: 50%; left:50%;
,這裡的百分比參考值是相對於父元素的寬高,參考的點是父元素的左上角和子元素的左上角,所以我們需要矯正一下,減去子元素寬高的一半。這件事可以讓子元素的margin
代勞。
.box-position {
position: relative;
}
.box-example2 {
position: absolute;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
}
相關例子連結: https://ataola.github.io/show/zj/center-middle.html#example2
父相子絕 + 平移(translate)
在樓上那個例子的基礎上,為了矯正子元素的偏移,我們其實還可以用css的平移屬性。這個平移的百分比是相對於其本身的寬高的,所以是向反方向50%。
.box-position {
position: relative;
}
.box-example3 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example3
父子double相(不推薦,做著玩玩的)
一個不成熟的做法哈,父子都是相對定位也還是可以勉強居中的,硬算嘛,這裡沒有太大價值就不展開了。
.box-position {
position: relative;
}
.box-example4 {
position: relative;
top: 90px;
left: 90px;
}
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example4
父子double相 + rem(不推薦,同樓上)
沒有太大價值,略過。
相關例子連結: https://ataola.github.io/show/zj/center-middle.html#example5
父相子絕 + calc
calc這個css屬性可以允許在宣告css屬性值時執行一些計算,回到我們之前的那個矯正偏移量的模型上,那麼這裡很容易想到子元素top、left
屬性設定成50%減去子元素一半的這樣一個模型。
.box-position {
position: relative;
}
.box-example6 {
position: absolute;
top: calc(50% - 100px);
left: calc(50% - 100px);
}
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example6
新舊flex
flex佈局,但凡一個正經點的初面都會遇到的,因為它好用也很常用,這裡介紹兩種,一種是新版的flex佈局的寫法,一種是舊版的flex佈局的寫法
flex佈局你就把它看成是一條軸線,一條長得還挺夯實的軸線,在這條軸線上,我們想要放一個盒子,有很多種放法,具體的可以搜下阮一峰老師的教程這裡不再贅述。一個化繁為簡的想法哈,這個是跟琦瑞哥學到的,就是我們很多時候也不一定能記得住那麼多屬性,我們期望做這樣一件事,就是把它化抽象為形象。我們可以用具體的方位去表達我們的想法,簡言之就是封裝成一個類庫,然後用一些接地氣的類名去控制flex佈局。
有興趣的童鞋可以看下我實現的一個低配版的css樣式庫:https://ataola.github.io/show/box/assets/taolaui/flex.css
新版flex的寫法
在不改變軸方向的情況下,其父元素設定align-items: center;
表示垂直居中,justify-content: center;
表示水平居中。
父元素設定:
.flex {
display: flex;
}
.flex-middle {
align-items: center;
}
.flex-center {
justify-content: center;
}
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example7
舊版flex的寫法
這裡就是提及一下有這麼種存在,讀者用新版的寫法就好。
.box-old {
display: -webkit-box;
-webkit-box-pack: center;
-webkit-box-align: center;
}
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example8
table佈局
父元素設定display: table
,子元素設定display:table-cell
,在只有一個子元素的情況下它會盡可能撐滿父元素,多個子元素的情況下水平均分。設定vertical-align: middle
可以使得其內容垂直居中。
.box-table {
display: table;
}
.box-son-table {
display: table-cell;
vertical-align: middle;
}
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example9
grid佈局
前面我們提到的flex佈局時軸佈局是一維的,這裡的grid網格佈局時二維的是平面的。將其父元素設定成display:grid
,然後子元素設定align-self: center;
表示垂直居中,justify-self: center;
表示水平居中。
.box-grid {
display: grid;
}
.box-son-grid {
align-self: center;
justify-self: center;
}
相關例子連結:https://ataola.github.io/show/zj/center-middle.html#example10
最後
相關實現地址已開源:https://ataola.github.io/show/zj/center-middle.html,若有不足之處,供批評指正!
其他網頁設計基礎總結:https://ataola.github.io/show/
參考文獻
https://developer.mozilla.org/zh-CN/docs/Web/CSS/background-position
https://developer.mozilla.org/zh-CN/docs/Web/CSS/background-repeat
https://developer.mozilla.org/zh-CN/docs/Web/CSS/calc
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。