Centering in CSS: A Complete Guidecss
BY CHRIS COYIER ON SEPTEMBER 2, 2014html
附:文中涉及到了flex的一些用法,若是没有接触过flex布局,建议看一下阮一峰老师的这篇指南:Flex 布局教程:语法篇git
博客文章地址:https://guitong.github.io/blo... 显示效果更佳。github
CSS居中是常被开发者抱怨的问题之一。Why dose it have to be so hard?? They jeer. 我认为问题不在于它实现起来有多难,而是有太多可以实现它的方法。在不一样的情景下,如何去选择,才是真正困惑咱们的地方。浏览器
因此如今,让咱们来作一个决策树,使CSS居中问题更容易解决。ide
它是行内或类行内元素吗?(好比文本和连接)布局
你能够将行内元素置于块级父元素内,而后用下面的CSS代码来使其水平居中:flex
.center-children { text-align: center; }
https://codepen.io/chriscoyie...ui
这种方法适用于inline,inline-block,inline-table,inline-flex等类型的元素。flexbox
它是一个块级元素吗?
为了居中一个块级元素,你能够设置它的margin-left
和margin-right
值为auto
(它的width
值已给定,不然将占满容器,也就不须要居中了)。一般简写以下:
.center-me { margin: 0 auto; }
https://codepen.io/chriscoyie...
不管咱们将要居中的块级元素或父元素的宽度如何,这都将起做用。
注意你不能将浮动元素居中。There is a trick though.
有多个块级元素吗?
若是你须要将多个块级元素水平居中于单行,一个好的办法是改变它们的dispaly
类型。这里有两个例子,分别使用了inline-block
和 flexbox 方法实现:
https://codepen.io/chriscoyie...
除非你是想让它们堆叠在一块儿,那么刚才使用的设置自动外边距值将仍然有效。
https://codepen.io/chriscoyie...
垂直居中在CSS中比较棘手。
它是行内或类行内元素吗?
是单行吗?
有时行内/文本元素能垂直居中显示,仅仅是由于它们有相等的上下padding
值。
.link { padding-top: 30px; padding-bottom: 30px; }
https://codepen.io/chriscoyie...
若是因为某些缘由,设置padding的方法并不可选,而你须要居中已知不会换行的文本,有一个技巧是使其line-height
值与其height
值相等。
.center-text-trick { height: 100px; line-height: 100px; white-space: nowrap; }
https://codepen.io/chriscoyie...
是多行吗?
对于多行文本的状况,依然可使用上下padding相等的方法使其垂直居中,可是若是这种方法失效了,可能文本所在的元素是一个table cell,不论是经过字面量定义的仍是经过CSS定义的。(红叶注:这里的意思就是该元素能够是直接使用<td>
表格标签声明,也能够是为元素设置display:table-cell;
属性而使其成为一个table cell,父元素设置display:table; )。若是是文本在<td>
这样的元素内,该元素默认有CSS属性vertical-align:middle;
,因此不须要咱们显示地设置。然而,若是你是手动更改CSS使其成为table cell元素的,就须要显示地加入这个属性vertical-align:middle;
。
下面的例子很是清晰地展现了这种方法:
https://codepen.io/chriscoyie...
若是你不喜欢或者这种方法也很差使,也许你能够用flexbox?单个子flex元素能够很是轻松地在父flex元素内垂直居中。
.flex-center-vertically { display: flex; justify-content: center; flex-direction: column; height: 400px; }
https://codepen.io/chriscoyie...
可是要记住,上面的讨论都是基于元素父容器有一个固定的高度(px,%,etc)。
若是这些方法都没法实现,你能够采用“ghost element”技术,将一个全高度的伪元素将放置于容器中,文本将与其垂直对齐。
.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; }
https://codepen.io/chriscoyie...
它是一个块级元素吗?
知道元素的高度吗?
不知道网页布局的高度是至关常见的,有不少缘由:若是文本的宽度改变,那么重布局时高度就会改变;文本样式的改变会改变高度;文本数量改变会改变高度;具备固定纵横比的元素(如图像),会在尺寸改变时影响高度。Etc。
可是若是你明确地知道高度,能够像这样使其垂直居中:
.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; */ }
https://codepen.io/chriscoyie...
未知元素高度?
不要紧。你仍然可使用相似上面的方法使其居中。先将其绝对定位至父元素半高位置,再提高自身半高距离便可。
.parent { position: relative; } .child { position: absolute; top: 50%; transform: translateY(-50%); }
https://codepen.io/chriscoyie...
~~> Can you use flexbox?
你可使用flexbox吗?
若是能够,那就至关简单了。
.parent { display: flex; flex-direction: column; justify-content: center; }
https://codepen.io/chriscoyie...
你能够将前面的方法任意组合起来,实现完美的居中效果。可是我发现一般能够将其分为三类:
元素有固定的宽度和高度吗?
先将元素绝对定位至50%/50%位置,而后加入负margin值,使该值等于高度和宽度的一半(注:元素若是有padding要记得计算进去,参考下例)。这样就可使元素水平且垂直居中,并具备良好的浏览器兼容性。
.parent { position: relative; } .child { width: 300px; height: 100px; padding: 20px; position: absolute; top: 50%; left: 50%; margin: -70px 0 0 -170px; }
https://codepen.io/chriscoyie...
元素的宽度与高度未知?
若是你不知道该元素的宽高,能够将它的transform
属性设置为translate(-50%, -50%)
。也能够达到相同的效果。
.parent { position: relative; } .child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
https://codepen.io/chriscoyie...
你可使用flexbox吗?
在水平和垂直两个方向上居中元素,你须要用到flex的两个属性:
.parent { display: flex; justify-content: center; align-items: center; }
https://codepen.io/chriscoyie...
这是一个小技巧,对单个元素来讲很是有效:
body, html { height: 100%; display: grid; } span { /* thing to center */ margin: auto; }
https://codepen.io/chriscoyie...
You can totally center things in CSS !!!