天天看點

CSS居中問題總結

目錄

  • 1. 前言
  • 2. 内聯元素居中
  • 2.1. 水準居中
  • 2.1.1. 使用”text-align:center”
  • 2.1.2. 使用CSS3的flexbox”justify-content:center”
  • 2.1.3. 使用”display: table-cell”
  • 2.2. 垂直居中
  • 2.2.1. 預設情況
  • 2.2.2. 行内元素互相之間的垂直居中
  • 3. 塊級元素居中
  • 3.1. 水準居中
  • 3.1.1. 使用”margin: 0 auto”
  • 3.1.2. 使用CSS3的flexbox”justify-content:center”
  • 3.1.3. 使用浮動配合相對定位
  • 3.1.4. 使用”display:table-cell”
  • 3.2. 垂直居中
  • 3.2.1. 使用“top”屬性和“margin-top”屬性的結合
  • 3.2.2. 使用CSS3“translateY”屬性
  • 3.2.3. 使用CSS3的flexbox”align-items: center”
  • 3.2.4. 使用”display:table-cell”
  • 3.2.5. 使用CSS :before 選擇器
  • 4. Bootstrap中關于居中的處理
  • 5. 小結
CSS居中問題總結

前言

  本篇集中對CSS中的各種居中問題進行總結。整體上需要居中的元素可以分為兩大類-内聯元素和塊級元素,而居中方式又要考慮水準和垂直兩個方向。

内聯元素居中

水準居中

使用”text-align:center”

根據以下W3C的官方文檔:

CSS居中問題總結

屬性“text-align”用于描述塊級元素中的行内内容如何布局。我們知道,塊級元素的顯示占據一整行,而行内元素可以在一行内并列顯示,常用的行内元素有​

​<img>​

​、​

​<input>​

​<label>​

​等。預設地,塊級元素中的行内元素是左對齊顯示的,比如:

1
2
3
4
5
6
7
8
9
10
11
12      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <span>CSS行内元素居中測試</span>
</div>
</body>
</html>      

效果如下圖所示:

CSS居中問題總結

  這種情況下我們想對行内元素标簽中的内容進行居中顯示,則可以使用“text-align: center”。要注意的是,這個屬性是用來決定行内元素的位置的,沒錯,但是該屬性并不是寫在行内元素上,而是要寫在行内元素的父級元素,即塊級元素這個“container”上,以此來決定内部文本的對齊方式。代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #block-center {
            text-align: center;
        }
    </style>
</head>
<body>
<div id="block-center">
    <span>CSS行内元素居中測試</span>
</div>
</body>
</html>      
CSS居中問題總結

使用CSS3的flexbox”justify-content:center”

  和​

​text-align​

​一樣的是,justify-content也适用于父類容器上,用于設定或檢索彈性盒子元素在主軸(橫軸)方向上的對齊方式。當屬性值為“center”時,彈性盒子元素将向行中間位置對齊。該行的子元素将互相對齊并在行中居中對齊,同時第一個元素與行的主起始位置的邊距等同于最後一個元素與行的主結束位置的邊距(如果剩餘空間是負數,則保持兩端相等長度的溢出)。

代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #block-center {
            display: flex; /*注意此處要指明flex布局*/
            justify-content: center;
        }
    </style>
</head>
<body>
<div id="block-center">
    <span>CSS行内元素居中測試(此處使用justify-content)</span>
</div>
</body>
</html>      
CSS居中問題總結

使用”display: table-cell”

  ​

​display: table​

​的CSS聲明能夠讓一個HTML元素和它的子節點像table元素一樣。使用基于表格的CSS布局,使我們能夠輕松定義一個單元格的邊界、背景等樣式,而不會産生因為使用了table标簽所導緻的語義化問題。代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #block {
            display: table;
            width: 100%;
            border: 1px solid black;
        }
        #block-center {
            display: table-cell;
            text-align: center;
            border: 1px solid orangered;
        }
        #inline-1 {
            height: 40px;
        }
    </style>
</head>
<body>
<div id="block">
    <div id="block-center">
        <img src="2.jpg" id="inline-1">
    </div>
</div>
</body>
</html>      
CSS居中問題總結

垂直居中

預設情況

  對于上述已經水準居中的文本來說,相對于父級元素的垂直居中是預設的,不需要特殊聲明,比如下面兩張圖,修改文本字号,它們始終處于父級div的垂直方向的中間(為了看得清楚,給父級元素加上了邊框)。

CSS居中問題總結
CSS居中問題總結

行内元素互相之間的垂直居中

  如果一個父級元素中有多個行内元素,那麼預設它們是在父元素的基線上進行對齊排列,也就是​

​vertical-align: baseline;​

​,以行内元素-圖檔為例,代碼為:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #block-center {
            text-align: center;
            border: 1px solid orangered;
        }
        #inline-1 {
            height: 40px;
        }
        #inline-2 {
            height: 60px;
        }
    </style>
</head>
<body>
<div id="block-center">
    <img src="2.jpg" id="inline-1">
    <img src="3.jpg" id="inline-2">
</div>
</body>
</html>      

效果如下:

CSS居中問題總結

  此時如果不想讓這些行内元素“底部對齊”呢,而是想讓它們互相居中對齊,也就是圖檔的中線在同一條水準線上呢?那就要對行内元素本身使用​

​vertical-align: middle;​

​,代碼為:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #block-center {
            text-align: center;
            border: 1px solid orangered;
        }
        #inline-1 {
            vertical-align: middle;
            height: 40px;
        }
        #inline-2 {
            vertical-align: middle;
            height: 60px;
        }
    </style>
</head>
<body>
<div id="block-center">
    <img src="2.jpg" id="inline-1">
    <img src="3.jpg" id="inline-2">
</div>
</body>
</html>      
CSS居中問題總結

塊級元素居中

使用”margin: 0 auto”

  我們以最常見的塊級元素-div為例,看一下居中的過程。首先建立一個div,代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #block {
            width: 100px;
            height: 100px;
            background-color: orangered;
        }
    </style>
</head>
<body>
<div id="block">
</div>
</body>
</html>      
CSS居中問題總結

  對塊級元素本身添加​

​margin: 0 auto​

​可使其水準居中,即左右的外邊距margin是auto的,會根據實際螢幕大小進行自動适配。修改上述style部分:

1
2
3
4
5
6
7
8      
<style>
    #block {
        width: 100px;
        height: 100px;
        background-color: orangered;
        margin: 0 auto;
    }
</style>      
CSS居中問題總結

​justify-content:center​

​不僅可以用來處理行内元素,也可以處理塊級元素,為達到與上述方法相同的效果,代碼為:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        #block {
            display: flex;
            justify-content: center;
        }
        #block-core {
            width: 100px;
            height: 100px;
            background-color: orangered;
        }
    </style>
</head>
<body>
<div id="block">
    <div id="block-core"></div>
</div>
</body>
</html>      

效果圖與上面的相同。

使用浮動配合相對定位

為了描述這種方法,我們通過下面的過程逐漸深入分析:

1.考慮最簡單的場景:父級div包含了子級div,代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #wrapper {
            border: 2px solid black;
        }
        #block {
            width: 100px;
            height: 100px;
            background-color: orangered;
        }
    </style>
</head>
<body>
    <div id="wrapper">
        <div id="block">
        </div>
    </div>
</body>
</html>      

易于了解,效果如下圖所示:

CSS居中問題總結

2.上圖黑色邊框div是一個包裹元素,我們現在把它水準移動50%,也就是設定left屬性。我們知道其預設的position屬性為“static”,這種情況下left屬性不起作用,是以将position改為relative,代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #wrapper {
            position: relative;
            left: 50%;
            border: 2px solid black;
        }
        #block {
            width: 100px;
            height: 100px;
            background-color: orangered;
        }
    </style>
</head>
<body>
    <div id="wrapper">
        <div id="block">
        </div>
    </div>
</body>
</html>      
CSS居中問題總結

我們發現,此時​

​<div id="wrapper">​

​的左邊界位于正中間,左右都是610px,也就是說,這個”left: 50%”是相對于wrapper的父級元素即body進行确定的,而body的寬度就是浏覽器視窗寬度。同時發現,視窗出現了水準方向滾動條,這是由于wrapper向右進行偏移,但本身寬度又沒變導緻的水準方向溢出。溢出了多少呢?通過下面的操作容易看出溢出正好是浏覽器寬度的一半,也就是wrapper向右偏移的距離:

CSS居中問題總結

3.為了防止出現滾動條,我們可以将wrapper這個div向左浮動,即加上一句“float: left;”,效果如下:

CSS居中問題總結

4.現在,想讓橙色方塊水準居中,隻要加50%的left就好了,代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #wrapper {
            position: relative;
            float: left;
            left: 50%;
            border: 2px solid black;
        }
        #block {
            width: 100px;
            height: 100px;
            background-color: orangered;
            position: relative;
            left: -50%;
        }
    </style>
</head>
<body>
    <div id="wrapper">
        <div id="block">
        </div>
    </div>
</body>
</html>      
CSS居中問題總結

使用”display:table-cell”

  這種方法我們将在下文中塊級元素垂直居中統一介紹-使用”display:table-cell”同時達到水準和垂直居中的效果。

使用“top”屬性和“margin-top”屬性的結合

分析:

a. 由水準居中部分的分析我們可以知道,當元素水準居中後,在垂直方向還是“密鋪”的,也就是從上到下排列,不會向下移動之類的。那麼為了把元素“向下拽”,就考慮設定該元素的top屬性為某個值,進而相對于父級元素在頂端有一定的空白,經過合理調整後可位于正中間。

b. 首先,我們要知道,css中position屬性的預設值是static;其次,要知道top屬性對于position值為“static”的元素不會産生任何效果。是以,想修改一個元素的top值,必須将元素的position修改為不是static的,這裡我們改為“position: relative”。

c. 将top屬性設定為一個百分比,這個百分比是相對于誰來說的呢?—是逐級向上尋找的,直到找到一個可以确定高度的父級元素,按照這個父級元素的高度結合百分比來設定top的具體值。這裡橙色div的父級元素是​

​<body>​

​,再向上的父級元素是​

​<html>​

​。而浏覽器在預設狀态下,是沒有給html和body一個高度的,為了使之成為剛才所說的“可以确定高度的父級元素”,将​

​<body>​

​和​

​<html>​

​的高度均設定為100%。

d. 既然是居中,也就是一半,我們考慮先将元素的top屬性設定為50%,看看效果,代碼為:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #block {
            position: relative;
            width: 100px;
            height: 100px;
            background-color: orangered;
            margin: 0 auto;
            top: 50%;
        }
    </style>
</head>
<body>
<div id="block">
</div>
</body>
</html>      
CSS居中問題總結

e.從上圖可以看出,橙色正方形的定邊到浏覽器視窗上方和下方的距離是一樣的,都是298px,也就是說top: 50%;不是将元素居中,而是整體下移了父級元素高度的一半,這也是很好了解的。但是我們已經有了一個基礎,在此基礎上,通過再設定元素的margin-top,可以進行修正,margin-top是指元素的頂外邊距,正值表明元素會繼續下移,那麼取負值即可向上,橙色正方形的高度為100px,那麼margin-top取為-50px,css代碼修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17      
<style>
    html,body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
    }
    #block {
        position: relative;
        width: 100px;
        height: 100px;
        background-color: orangered;
        margin: 0 auto;
        top: 50%;
        margin-top: -50px;
    }
</style>      
CSS居中問題總結

我們能夠看出現在已經完全居中了。

使用CSS3“translateY”屬性

  在上面方法的基礎上,将下移50%的元素向上修正時,可以采取更簡單的辦法:translateY(-50%)。translateY()方法通過給定一個值,将元素沿Y軸進行移動,并且,給定的是是相對于元素自身的,是以50%就表示元素自身Y方向長度的一半。負号表示沿Y軸反方向移動(Y軸正向向下)。這種方法還有一個明顯的好處,就是和margin-top相比,給定的是一個比例,而不像margin-top這樣寫死,這樣後面的可維護性也會好一些。CSS代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17      
<style>
    html,body {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
    }
    #block {
        position: relative;
        width: 100px;
        height: 100px;
        background-color: orangered;
        margin: 0 auto;
        top: 50%;
        transform: translateY(-50%);
    }
</style>      

使用CSS3的flexbox”align-items: center”

  彈性盒模型在處理居中問題上真是簡單明了。上面說了兩種使用flexbox進行水準居中的方法,垂直居中一樣可以使用flexbox搞定,align-items 屬性定義flex子項在flex容器的縱軸方向上的對齊方式;justify-content屬性定義flex子項在flex容器的橫軸方向上的對齊方式。代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        body {
            display: flex;
            align-items: center;
            justify-content: center;
        }
        #block {
            width: 100px;
            height: 100px;
            background-color: orangered;
        }
    </style>
</head>
<body>
<div id="block">
</div>
</body>
</html>      

  我們曾在内聯元素的水準居中使用過這種辦法,它也可以用于塊級元素的水準和垂直居中。核心是使用”text-align: center; vertical-align: middle;”這兩個屬性。另外特别要注意的是,為了讓這兩個屬性對于想要居中顯示的塊級元素生效,必須指定該塊級元素為”display: inline-block;”。”display:inline-block”将對象呈遞為内聯對象,但是對象的内容作為塊對象呈遞。換句話說就是與”display: block”相比,它可以讓設定了同類display屬性的元素顯示在同一行;與”display: inline”相比,可以對設定了該屬性的元素設定高度。代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #parent {
            display: table;
            width: 100%;
            height: 100%;
        }
        #wrapper {
            display: table-cell;
            text-align: center;
            vertical-align: middle;
        }
        #block {
            width: 100px;
            height: 100px;
            background-color: orangered;
            display: inline-block;
        }
    </style>
</head>
<body>
<div id="parent">
    <div id="wrapper">
        <div id="block">display: table-cell實作塊級元素水準和垂直居中</div>
    </div>
</div>
</body>
</html>      

使用CSS :before 選擇器

  關于:before 選擇器本身這裡不做介紹,使用:before,在想要居中顯示的元素前面追加了一個内聯元素來占據相應的位置,進而達到垂直居中的效果,代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31      
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        html,body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        body:before {
            content:'';
            display:inline-block;
            vertical-align:middle;
            height:50%;
        }
        #block {
            width: 100px;
            height: 100px;
            background-color: orangered;
            position: relative;
            top: -50px;
        }
    </style>
</head>
<body>
    <div id="block"></div>
</body>
</html>      
CSS居中問題總結

Bootstrap中關于居中的處理

  Bootstrap中關于排版的居中提供了兩個class:

  1. class=”text-center”

    源碼為:

1
2
3      
.text-center {
  text-align: center;
}      
  1. class=”center-block”
1
2
3
4
5      
.center-block {
  display: block;
  margin-right: auto;
  margin-left: auto;
}      

這兩個類中使用到的方法在上文中都有提及。結合Bootstrap提供的其他強大的樣式,容易實作各類排版。

小結

  本文總結了很多使用CSS對元素進行居中的辦法,CSS是十分靈活且強大的,一定還有其他更好的辦法。以上所列舉的方法在正常開發中應該是夠用了,并且通過實作居中了解了很多相關原理,這對于排錯過程中快速定位問題很重要。