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


實現css水平垂直居中的方法有很多,在這里我簡單的說下四種比較常用的方法:

1.使用CSS3中的Flex布局

對於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同樣這樣設置

<!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:auto

.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為調用混合宏。除了聲明一個不帶參數的混合宏之外,還可以在定義混合宏時帶有參數,並且在里面還可以寫更加復雜的邏輯。

下面我將會用到if else語句以及@mixin混合宏來封裝我們上面的第2,3,4方法。

我們的思路是先將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;
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM