CSS 居中?來一探究竟

個人博客原文: https://wzb.me/posts/2019/10/28/css-centering.html

「居中」是進行佈局時最多見的需求之一了。CSS 有多種居中的方式,在何時挑選適合的方案?是一個值得思考的問題。css

法律聲明

警告:本做品遵循 署名-非商業性使用-禁止演繹 4.0 未本地化版本(CC BY-NC-ND 4.0) 協議發佈。你應該明白與本文有關的一切行爲都應該遵循此協議。html

這是什麼?

寫在前面

本文將會按照具體場景來選擇相應的居中方式,幫助你係統地理清 CSS 居中。css3

注意:爲了簡潔,文中給出的 CSS 代碼只會給出關鍵的定義佈局的代碼。瀏覽器

在水平方向上的居中(Horizontally Centering)

對於行內(inline / inline-* )元素

要將行內元素居中,只須要給其父塊級元素(block-level parent element)定義如下 CSS 規則:ide

.block-level-parent-of-inline-element {
  text-align: center;
}

centering-inline-element

這對 inline inline-block inline-table inline-flex etc. 都生效

text-align 不單單是針對於 text 的對齊描述,實際上,它影響的是塊級元素下的行內元素與文本(inline contents)。佈局

參考: text-align - CSS | MDN

對於塊級元素(block element)

要將塊級元素居中,給其定寬(width)以後定義如下 CSS 規則post

.block-element {
  margin: 0 auto;
}

css-centering-block-element

若是沒有給定塊級元素寬度?那它會充滿整行,以致於不須要居中了... 🔨flex

就像這樣ui

full-witdh

若是有多個塊級元素?

若是你想將多個塊級元素在水平方向上居中,有如下兩種方法。spa

  • 將多個塊級元素設置 display: inline-box; 而後給父級元素定義 text-align: center;(與上文的行內元素居中同理)
.parent {
  text-align: center;
}
.block-elements {
  display: inline-block;
}

inline-blocks-centering

  • 使用 Flexbox
.parent {
  display: flex;
  justify-content: center;
}

centering-blocks-in-flex

在豎直方向上的居中(Vertically Centering)

對於行內(inline / inline-* )元素

好比文字(text)和連接(links)

只有一行時

  • 要讓行內元素/文字看起來在豎直方向上的中間,能夠給其定義上下相等的內邊距(padding)
a {
  padding-top: 20px;
  padding-bottom: 20px;
}

centering-links

  • 還有一種方案是,將文字的行高值設置與其元素高度相同。
.box {
  height: 60px;
  line-height: 60px;
}

centering-a-line

仔細思考,若是文字的內容超過一行,或者是父級元素的大小在響應式變化的狀況下變小致使文字須要換行,會出現這樣的狀況。

lines-wraps

解決這個問題,只須要設置文字不換行便可

.box {
  height: 60px;
  line-height: 60px;
  white-space: nowarp;
}

lines-center-no-wrap

有多行文字時

  • 一樣的,能夠給元素設置上下相等的 padding,讓文字看起來在中間
  • 將父元素定義爲 display: table; 同時將子元素設置爲 display: tabel-cell; 而且給予 vertical-align: middle; 屬性。
.box {
  display: table;
  height: 60px;
}

.box p {
  display: table-cell;
  vertical-align: middle;
}
  • 使用 Flexbox 居中

將文字放在塊級元素中,給其父元素使用 Flex

.box {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

以上效果相同,以下圖。

muti-lines-centering

對於塊級(block)元素

已經肯定塊級元素的高度

在實際狀況下,不多會明確地肯定某一個元素的高度。若是真的可以肯定某個元素的高度,可使用下面的方法。

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px;
}

這裏須要注意的是 top 屬性的計算方法,能夠參考 CSS - top | MDN

centerring-position-block

不能肯定塊級元素的高度

咱們仍可使用與上例相似的方法,不過須要使用 transform 屬性。

.parent {
  position: relative;
}
.box {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
對於 translate 的計算方式,能夠參考 Is the CSS3 transform translate percentage values relative to its width and/or height? - Stack Overflow

若是你不在意元素撐大的話

你不在意元素是否撐開,只想要它的內容豎直居中,可使用 table 或者是 CSS display 將其變成 table 行爲。

main {
  padding: 5px;
  display: table;
}
main div {
  display: table-cell;
  vertical-align: middle;
}

table-vertical-centering

可見,元素被撐大了。🔨

Flexbox

使用 Flexbox 在豎直方向上居中是一樣的方便。

.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

flex-vertical-center

水平和豎直方向上同時居中

你能夠將上面的方法結合使用達到此目的。不過這裏總結了幾種比較方便的方式。

元素肯定了高度和寬度時

使用絕對定位以後,設置爲負的margin屬性,其值等於 高度/寬度 的50%。

.parent {
  position: relative;
}

.child {
    height: 60px;
    width: 180px;

    position: absolute;
    top: 50%;
    left: 50%;

    margin: -30px 0 0 -90px;
}

centering-positon-nagetive

這樣進行居中的瀏覽器兼容性很是好。

不肯定元素高寬

與上例相同,使用絕對定位,不過換成了 translate 屬性。

.parent {
  position: relative;
}

.child {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

unknow-height-width-centering

Flexbox

相信你已經想到了 Flexbox 如何實現,只須要把主軸和側軸方向上都設置爲居中就行了。

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

flex-centerring

Gird

對於居中一個元素來講,可使用 Gird 的 trick。

.parent {
  display: grid;
}
.parent div {
  margin: auto;
}

flex-centerring

寫在最後

如今你對居中的方法與選擇有了清楚的認識,你不再怕居中了。XD

References

相關文章
相關標籤/搜索