使用Sass優雅並高效的實現CSS中的垂直水平居中(附帶Flex佈局,CSS3+SASS完美版)

實現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;
}

  

相關文章
相關標籤/搜索