1. 程式人生 > >CSS中居中的完全指南(中英對照翻譯)

CSS中居中的完全指南(中英對照翻譯)

翻譯自:https://css-tricks.com/centering-css-complete-guide/

Centering things in CSS is the poster child of CSS complaining. Why does it have to be so hard? They jeer. I think the issue isn’t that it’s difficult to do, but in that there so many different ways of doing it, depending on the situation, it’s hard to know which to reach for.

So let’s make it a decision tree and hopefully make it easier.

在CSS中把元素放置到中間是件麻煩的事情。為什麼它這麼難呢?他們嘲笑道。我認為問題不是它多難做,而在於這根據不同的情況有很多的方式來做,它難在怎樣選用來達到設計目標。

因此我們來做一個選擇樹,希望能讓這個事情變得簡單。

 I need to center…

我需要居中...

Horizontally

水平居中

Is it inline or inline-* elements (like text or links)?

是內聯元素麼?

You can center inline elements horizontally, within a block-level parent element, with just:

如果你是要水平居中一個塊級元素的內聯子元素,只需要:

.center-children {
  text-align: center;
}
 

This will work for inline, inline-block, inline-table, inline-flex, etc.

這個會在內聯元素,內聯塊元素,內聯表,內聯flex之類的情況起效果。

Is it a block level element?

  是塊級元素麼?

You can center a block-level element by giving it margin-left and margin-right of auto (and it has a set width, otherwise it would be full width and wouldn’t need centering). That’s often done with shorthand like this:

你可以通過給一個塊級元素margin-left 和margin-right樣式賦予auto (並且這個塊級元素設定了一個寬度,否則這個塊級元素會拉伸到佔滿寬度,也就不需要居中了)來居中它。通常是這麼寫的:

.center-me {
  margin: 0 auto;
}
 

This will work no matter what the width of the block level element you’re centering, or the parent.

不論你給塊級元素和它的父元素設定了多大的寬度,這都會起效果。

Note that you can’t float an element to the center. There is a trick though.

注意你不能用float樣式把元素居中到中心。(這裡有個小訣竅)

Is there more than one block level element?

  有多個塊級元素的情況麼?

If you have two or more block-level elements that need to be centered horizontally in a row, chances are you’d be better served making them a different display type. Here’s an example of making them inline-block and an example of flexbox:

如果你有2個以上的塊級元素需要在同一行內水平居中,你可以把它們改成另一種display型別。這裡有使用inline-block和flexbox的例子:

 

Unless you mean you have multiple block level elements stacked on top of each other, in which case the auto margin technique is still fine:

除非你想要把多個塊級元素上下堆疊在一起,使用auto magrin的技巧仍然可以得到很好效果。

 

Vertically

垂直居中

Vertical centering is a bit trickier in CSS.

在CSS裡垂直居中需要一點技巧。

Is it inline or inline-* elements (like text or links)?

  是inline或者inline-* 元素(像文字或者超連結)

Is it a single line?

  是單行的?

Sometimes inline / text elements can appear vertically centered, just because there is equal padding above and below them.

有時候 行級/文字 元素 看起來是垂直居中的,只是因為上下有同樣的padding數值。

.link {
  padding-top: 30px;
  padding-bottom: 30px;
}
 

If padding isn’t an option for some reason, and you’re trying to center some text that you know will not wrap, there is a trick were making the line-height equal to the height will center the text.

如果因為某些原因不能用padding來垂直居中文字並且你確定文字不用換行,還有個用行高來等效實現居中的辦法:

.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}
 

Is it multiple lines?

  是多行的麼?

Equal padding on top and bottom can give the centered effect for multiple lines of text too, but if that isn’t going to work, perhaps the element the text is in can be a table cell, either literally or made to behave like one with CSS. The vertical-align property handles this, in this case, unlike what it normally does which is handle the alignment of elements aligned on a row. (More on that.)

使用相等的上下padding來實現多行(文字,行級元素)垂直居中效果是可以的,但是如果這麼做不行的時候,或許這些元素可以放進一個table的格子裡,或者使用css字面上指定它像一個格子裡的元素一樣表現。vertical-align屬性可以處理這個,這樣,它就不像通常那樣而是在錶行內對齊了。

 

 

If something table-like is out, perhaps you could use flexbox? A single flex-child can be made to center in a flex-parent pretty easily.

如果說類似table的寫法已經過時了,或許你可以使用flexbox?單個flex-child可以在一個flex-parent內簡單完美地完成對齊。

.flex-center-vertically {
  display: flex;
  justify-content: center;
  flex-direction: column;
  height: 400px;
}
 

Remember that it’s only really relevant if the parent container has a fixed height (px, %, etc), which is why the container here has a height.

記住父級有一個固定高度(px,%之類),也就是容器是否有一個固定高度是很重要的。

If both of these techniques are out, you could employ the “ghost element” technique, in which a full-height pseudo-element is placed inside the container and the text is vertically aligned with that.

如果兩個技巧都失敗了,你可以使用“幽靈元素”技巧,也就是把一個100%高度的偽元素防止到容器內,然後文字就可以垂直居中了。

.ghost-center {
  position: relative;
}
.ghost-center::before {
  content: " ";
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}
.ghost-center p {
  display: inline-block;
  vertical-align: middle;
}
 

Is it a block-level element?

  是塊級元素麼?

  

Do you know the height of the element?

    你知道元素高度麼?

It’s fairly common to not know the height in web page layout, for lots of reasons: if the width changes, text reflow can change the height. Variance in the styling of text can change the height. Variance in the amount of text can change the height. Elements with a fixed aspect ratio, like images, can change height when resized. Etc.

在網頁佈局中由於各種原因無法明確高度是常見狀況,比如:寬度改變,文字重新流式排版會造成高度改變各種各樣style的文字會改變高度。不同數量的文字會改變高度。含有固定寬高比的元素,比如圖片,會在尺寸變化時改變高度。諸如此類。

But if you do know the height, you can center vertically like:

但是如果你知道高度,你可以像這樣垂直居中元素:

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}
 

Is the element of unknown height?

    是高度未知的元素麼?

It’s still possible to center it by nudging it up half of it’s height after bumping it down halfway:

把它提升自身高度的50%然後用top把它向下移動父元素的一半高度來實現居中仍然是可行的。

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
 

Do you care if the element stretches the height of the container?

    你在意元素會撐高容器的高度麼?

If you don’t, you just need the content inside vertically centered, using tables or CSS display to make elements into tables can do the trick.

如果不在意,你只需要用table或者css指定的類table行為技巧來讓它垂直居中。

 

 

Can you use flexbox?

    你可以使用flexbox麼?

No big surprise, this is a lot easier in flexbox.

沒什麼好驚訝,用flexbox簡單多了。

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

You can also get centering in flexbox using margin: auto; on the child element.

在flexbox中你也可以在子元素中使用 margin:auto; 來實現垂直居中

 

Both Horizontally and Vertically

水平垂直同時居中

You can combine the techniques above in any fashion to get perfectly centered elements. But I find this generally falls into three camps:

你可以組合使用以上的任意時髦技術來實現完美的元素居中效果。但是我發現通常最終會成為三種情況:

Is the element of fixed width and height?

  是有固定寬高的元素麼?

Using negative margins equal to half of that width and height, after you’ve absolutely positioned it at 50% / 50% will center it with great cross browser support:

在使用absolute定位元素到50% 50%之後,再對它們自身寬高使用-50%magrin的技巧,會得到非常好的跨瀏覽器相容的居中效果。

.parent {
  position: relative;
}

.child {
  width: 300px;
  height: 100px;
  padding: 20px;

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

  margin: -70px 0 0 -170px;
}
 

Is the element of unknown width and height?

元素的寬高未知麼?

If you don’t know the width or height, you can use the transform property and a negative translate of 50% in both directions (it is based on the current width/height of the element) to center:

如果你不知道元素的寬或者高,你可以對水平垂直同時使用transform屬性設定到-50%(這個50%是基於被居中的元素的寬高的)的辦法來居中元素:

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

Can you use flexbox?

你可以使用flexbox麼?

To center in both directions with flexbox, you need to use two centering properties:

使用flexbox水平垂直同時居中,你需要使用連個居中屬性:

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

Can you use grid?

你可以使用grid麼?

This is just a little trick (sent in by Lance Janssen) that will pretty much work for one element:

這個有點取巧(Lance Janssen發來的),它對於單個元素效果非常完美:

body, html {
  height: 100%;
  display: grid;
}
span { /* thing to center */
  margin: auto;
}

 

  

Conclusion

  總結

  You can totally center things in CSS.

  你可以在css里居中所有