實現css水平垂直居中的方法有不少,在這裏我簡單的說下四種比較經常使用的方法:css
1.使用CSS3中的Flex佈局html
對於flex,咱們要了解的是它是一個display的屬性,並且必需要給他的父元素設置flex屬性(flex必須配合絕對定位使用!!!!!),除了設置display:flex以外,還有另外兩個屬性須要設置,分別是justify-content和align-items,他們的意思分別是水平居中和垂直居中。HTML+CSS代碼以下:瀏覽器
body { position: absolute; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .parentNode { width: 400px; height: 400px; background: #f00; }
<body> <div class="parentNode"></div> </body>
當需求改變時,好比咱們要在此div裏面嵌套一個div,根據我上面提到的,要想子DIV垂直水平居中,咱們也要給父DIV一樣這樣設置sass
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; } body { position: absolute; // flex必須配合absolute使用纔會生效 width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } .parentNode { width: 400px; height: 400px; background: #f00; position: relative; // 這裏必須用relative 緣由是 相對於 body這個父標籤訂位 若是用absolute會找上級的relative,若是沒有,就到頂級的document display: flex; justify-content: center; align-items: center; } .childNode { width: 200px; height: 200px; background: #fff; } </style> </head> <body> <div class="parentNode"> <div class="childNode"></div> </div> </body> </html>
2.使用CSS3中的transform佈局
.parentNode { width: 400px; height: 400px; background: #f00; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
3.當你知道元素的width與height時,使用CSS2中的最普通不過的margin字體
.parentNode { width: 400px; height: 400px; background: #f00; position: absolute; left: 50%; top: 50%; margin: -200px 0 0 -200px; }
4.使用比較特殊的margin:autoflex
.parentNode { width: 400px; height: 400px; background: #f00; overflow: auto; margin: auto; // 在標準流的狀況下,讓 margin-top 以及 margin-bottom 都爲0 position: absolute; top: 0; left: 0; bottom: 0; right: 0; // 使瀏覽器對其元素所在的區域內從新渲染,四個值都設爲0目的是讓整個窗口都爲該元素的從新渲染區域,以後margin-top以及margin-bottom都相等 }
如今讓咱們來使用強大的SASS重構一下這幾個樣式,先拿flex開刀吧,網站
@mixin center { display: flex; justify-content: center; align-items: center; } body { position: absolute; width: 100%; height: 100%; @include center;
.parentNode { width: 400px; height: 400px; background: #f00; position: relative; @include center;
.childNode { width: 200px; height: 200px; background: #fff; } } }
若是你的整個網站中有幾處小樣式相似,好比顏色,字體等,在 Sass 可使用"$"變量來統一處理,那麼這種選擇仍是不錯的。但當你的樣式變得愈來愈複雜,須要重複使用大段的樣式時,使用變量就沒法達到咱們目了。這個時候 Sass 中的混合宏就會變得很是有意義,@mixin 是用來聲明混合宏的關鍵詞,有點相似 CSS 中的 @media、@font-face 同樣。center 是混合宏的名稱。大括號裏面是複用的樣式代碼。@include爲調用混合宏。除了聲明一個不帶參數的混合宏以外,還能夠在定義混合宏時帶有參數,而且在裏面還能夠寫更加複雜的邏輯。spa
下面我將會用到if else語句以及@mixin混合宏來封裝咱們上面的第2,3,4方法。code
咱們的思路是先將DIV的左上角絕對定位到容器的中心位置,而後爲 mixin 添加兩個可選參數($width,$height),分別表明元素的寬高,若是傳遞了參數,那麼就使用負向 margin
的方法實現居中;若是沒有傳遞參數,就使用 CSS3的transform
的方法。
/** * 爲子元素設定定位上下文 */ .parent { position: relative; } /** * 讓子元素絕對居中於父容器 * 沒有向 Sass mixin 傳遞寬和高,使用 CSS transform 屬性實現居中效果 */ .child-with-unknown-direction { @include center; } /** * 讓子元素絕對居中於父容器 * 向 Sass mixin 傳遞了寬度,因此就使用負向 margin 處理水平位置, * 使用 CSS transform translateY 處理垂直位置 */ .child-with-known-width { @include center(400px); } /** * 讓子元素絕對居中於父容器 * 向 Sass mixin 傳遞了高度,因此就使用負向 margin 處理垂直位置, * 使用 CSS transform translateX 處理水平位置 */ .child-with-known-height { @include center($height: 400px); } /** * 讓子元素絕對居中於父容器 * 向 Sass mixin 傳遞了高度和寬度,因此就使用負向 margin 處理水平和垂直位置 */ .child-with-known-direction { @include center(400px, 400px); }
如今咱們開始封裝@mixin,由上面的CSS分析知,要實現居中必須先讓元素絕對定位
@mixin center($width: null, $height: null) { position: absolute; top: 50%; left: 50%; }
而後根據下面的邏輯搭建@mixin的骨架
width | height | solution |
---|---|---|
null | null | translate |
defined | defined | margin |
defined | null | margin-left + translateY |
null | defined | margin-right + translateX |
@mixin center($width:null,$height:null){ display: flex; justify-content: center; align-items: center; @if $width and $height { // do margin } @else if not $width and not $height { // do transform translate(-50%,-50%) } @else if not $width { // do margin-top and transform translateX } @else { // do margin-left and transform translateY } }
最後咱們把具體的代碼插入到不一樣的條件中去
@mixin center($width:null,$height:null){ position: absolute; top: 50%; left: 50%; @if $width and $height { // do margin width: $width; height: $height; margin: -($height / 2) #{0 0} -($width / 2); //這裏若是直接寫 0 0 他會編譯爲 margin: xx 0 xx 而不是 margin:xx 0 0 xx,因此用 #{0 0}
} @else if not $width and not $height { // do transform translate(-50%,-50%) transform: translate(-50%,-50); } @else if not $width { // do margin-top and transform translateX height: $height; margin-top: -(height / 2); transform: translateX(-50%); } @else { // do margin-left and transform translateY width: $width; margin-top: -(width / 2); transform: translateY(-50%); } }
最後咱們能夠經過Koala軟件離線編譯也能夠經過http://www.sassmeister.com/在線編譯,下面是編譯好的結果
@charset "UTF-8"; /** * 爲子元素設定定位上下文 */ .parent { position: relative; } /** * 讓子元素絕對居中於父容器 * 沒有向 Sass mixin 傳遞寬和高,使用 CSS transform 屬性實現居中效果 */ .child-with-unknown-direction { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50); } /** * 讓子元素絕對居中於父容器 * 向 Sass mixin 傳遞了寬度,因此就使用負向 margin 處理水平位置, * 使用 CSS transform translateY 處理垂直位置 */ .child-with-known-width { position: absolute; top: 50%; left: 50%; width: 400px; margin-top: -width/2; transform: translateY(-50%); } /** * 讓子元素絕對居中於父容器 * 向 Sass mixin 傳遞了高度,因此就使用負向 margin 處理垂直位置, * 使用 CSS transform translateX 處理水平位置 */ .child-with-known-height { position: absolute; top: 50%; left: 50%; height: 400px; margin-top: -height/2; transform: translateX(-50%); } /** * 讓子元素絕對居中於父容器 * 向 Sass mixin 傳遞了高度和寬度,因此就使用負向 margin 處理水平和垂直位置 */ .child-with-known-direction { position: absolute; top: 50%; left: 50%; width: 400px; height: 400px; margin: -200px 0 0 -200px; }