CSS 的居中问题
CSS 中一个常见的问题就是图片或者文本的居中。这个问题可以细分成以下三种:
- 文本居中对齐
- 块水平居中
- 块垂直居中
下面我们来讨论下这几个问题。
文本的居中对齐
最常见以及最容易的居中问题是段落或者标题的文本居中显示,CSS 中的text-align属性可以解决这个问题:
p { text-align: center }
h2 { text-align: center }
这将会使得 p 或者 h2 中的每一行居中对齐,就像这样
另外一种情况是,文本处于 div 中,而 div 具有一定的高度,那么我们除了设置text-align之外还需要设置行高与 div 高度一样,类似于这样:
div {
height: 100px;
width: 100px;
line-height: 100px;
text-align: center;
}
...
<div>
Hello World!
</div>
块或者图片的水平居中
有时候不仅仅是文本需要居中,而是一个块需要居中。换另一种描述:我们想块的左边距和右边距相同。解决的办法是将这些边距设置成 auto。如果块的宽度是固定的话这种做法是很常用的,但如果块本身是大小可变的话这个块会占满整个可用宽度,从而失效。
这种做法示例如下:
p.blocktext {
margin-left: auto;
margin-right: auto;
width: 6em;
}
...
<p class="blocktext">This rather...
这种做法也可以用来使得图片居中:让图片变成块,然后对它使用 margin 属性。举个栗子:
img.displayed {
display: block;
margin-left: auto;
margin-right: auto
}
...
<img class="displayed" src="..." alt="...">
块垂直居中
CSS2 没有单独属性来使得块垂直居中,不过 CSS3 总算是有了。在 CSS2 中你可以同时通过使用几个属性来实现实现块的垂直居中,这个技巧就是将父级块变成一个 table cell——因为 table cell 中的内容会被垂直居中。
div.container {
min-height: 10em;
display: table-cell;
vertical-align: middle
}
...
<div class="container">
<p>This small paragraph...</p>
</div>
CSS3 中的垂直居中
CSS3 为垂直居中提供了其他的解决办法。我们可以使用绝对定位来实现垂直居中,但这可能会导致页面元素重叠,如果你知道在你的场景中不会发生元素重叠的情况,你可以使用绝对定位以及‘transform’属性来居中元素。例如:
页面结构会类似于这样:
<div class=container3>
<p>This paragraph…</p>
</div>
css 样式会类似于这样:
div.container3 {
height: 10em;
position: relative /* 1 */
}
div.container3 p {
margin: 0;
position: absolute; /* 2 */
top: 50%; /* 3 */
transform: translate(0, -50%) /* 4 */
}
需要注意的几点是:
- 将父级 container 声明为相对定位;
- 将需要垂直居中的元素声明为绝对定位;
- 使用‘top: 50%’来将该元素放置在 container 的高度的一半。(注意这里的 50%指的是 container 高度的 50%)
- 使用 translation 来将该元素向上移动其高度的一半。(‘translation(0, -50%)’的 50%指的是元素自身的高度)
我们也可以使用 display 属性的新关键字 flex 来实现垂直居中。
CSS 样式会类似于这样:
div.container5 {
height: 10em;
display: flex;
align-items: center
}
div.container5 p {
margin: 0
}
CSS3 中同时垂直、水平居中
我们可以混合使用上述方法来实现同时垂直、水平居中。
注意将段落绝对定位的一个副作用:段落有多长它就有多宽(除非我们显式为段落指定一个宽度)。在下面这个例子中,我们不指定宽度因为我们只有一个单词(Center!),这时候段落的宽度等于单词的宽度。
页面结构:
<div class=container4>
<p>Centered!</p>
</div>
对于 CSS 样式,垂直居中的部分和之前的例子一样。但我们现在使用‘left: 50%’将元素放置在 container 的水平一半的位置,同时使用‘translate’转换将其向左移动其宽度的一半:
div.container4 {
height: 10em;
position: relative
}
div.container4 p {
margin: 0;
background: yellow;
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%)
}
下面这个 例子 解释为什么‘margin-right: -50%’是需要的。
如果 CSS 支持‘flex’的话,那同时垂直、水平居中就更简单了:
CSS 样式:
div.container6 {
height: 10em;
display: flex;
align-items: center;
justify-content: center
}
div.container6 p {
margin: 0
}
相比之前,只增加了‘justify-content: center’。就像‘align-items’决定了 container 里面的元素的垂直对齐一样,‘justify-content’决定了水平的对齐。(就像它们起的名字一样实际更复杂点,但简单来说作用是这样的)。
CSS3 在 viewport 居中
对于一个绝对定位的元素默认的 container 是 viewport(对于浏览器来说,就是浏览器窗口)。在 viewport 居中非常简单,下面是一个完整的例子(使用 HTML5 语法):
<html>
<style>
body {
background: white
}
section {
background: black;
color: white;
border-radius: 1em;
padding: 1em;
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%)
}
</style>
<section>
<h1>Nicely centered</h1>
<p>This text block is vertically centered.
<p>Horizontally, too, if the window is wide enough.
</section>
margin-right 是用来补偿 left: 50%
的。由于 left 规则将可用宽度减少了 50%,因此每一行的宽度都变得不超过父级 container 宽度的一半。通过声明其 margin-right 向右扩展 50%,行宽重新变得与 container 的宽度一样。
试试调整浏览器窗口大小:当窗口足够宽的时候每个句子都只占一行,只有当窗口对于整个句子太窄的时候这些句子会被切割成几行。去掉 margin-right: -50%
,然后重新调整窗口,你会看到即便窗口的宽度等于文本宽度的两倍但这些句子已经被切割成多行了。
使用 translate 来在 viewport 中居中的方法是 Charlie 在 Stack Overflow 的一个答案 首次提出的
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论