在网页设计中,居中元素时,您拥有的关于要居中元素及其父元素的信息越多,它就越容易。 那么,如果您什么都不知道呢? 它仍然可以做到。
不太难:已知子元素
如果您知道要居中元素及其父元素的高度和宽度(并且这些尺寸不会改变,即非流体宽度环境),则将元素居中的一个万无一失的方法就是使用像素值对其进行绝对定位,使其看起来完美居中。
假设您知道要居中元素的精确宽度和高度,但父元素的高度和宽度可能会改变。

您对要居中的元素进行绝对定位,并将顶部和左侧的值设置为 50%,并将顶边距和左边距设置为元素高度和宽度的负的一半。 这有点绕口,所以 查看这里。
更难:未知子元素
难点在于您不知道要居中元素的尺寸。

最粗俗的处理方法就是直接使用表格
<table style="width: 100%;">
<tr>
<td style="text-align: center; vertical-align: middle;">
Unknown stuff to be centered.
</td>
</tr>
</table>
如果您担心语义问题,可以尝试将其与您的内容相匹配。
<div class="something-semantic">
<div class="something-else-semantic">
Unknown stuff to be centered.
</div>
</div>
并获得与表格相同的结果,例如
.something-semantic {
display: table;
width: 100%;
}
.something-else-semantic {
display: table-cell;
text-align: center;
vertical-align: middle;
}
CSS 表格可能适合您。 或者可能不适合。 表格的渲染方式与普通块级 div 稍有不同。 例如,100% 宽度。 表格只会扩展到其内部内容所需的宽度,而块级元素默认情况下会自动扩展到其父元素的宽度。 此外,如果您需要该 div 中的其他内容进行定位或以其他方式不作为表格单元格,那么上帝保佑您。
Michał Czernow 向我写信,介绍了一种非常巧妙的替代方法,它可以实现相同的效果。 如果我们在父元素内部设置一个“幽灵”元素,高度为 100%,然后我们对该元素和要居中的元素执行vertical-align: middle
,我们就能获得相同的效果。

那么,幽灵元素需要是一个非语义元素吗? 不需要,它可以是一个伪元素。
/* This parent can be any width and height */
.block {
text-align: center;
/* May want to do this if there is risk the container may be narrower than the element inside */
white-space: nowrap;
}
/* The ghost, nudged to maintain perfect centering */
.block:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em; /* Adjusts for spacing */
}
/* The element to be centered, can also be of any width and height */
.centered {
display: inline-block;
vertical-align: middle;
width: 300px;
}
View Demo
我想告诉您,幽灵元素技术要好得多,应该成为未来各个时代的首选居中技术。 但实际上,它与表格技巧几乎相同。 该方法的浏览器支持几乎涵盖所有内容,包括 IE 8+。 IE 7 不支持伪元素。 但是它也不支持 CSS 表格,所以两者旗鼓相当。 如果需要 IE <= 7 支持,则需要使用<table>
(或使用同样非语义的<span>
或类似的元素作为幽灵元素)。
这些内容并非全新领域。 Gary Turner 在五年前就写过相关内容。 但是,我感谢 Michał 用伪元素实现了它,使其成为迄今为止最语义化的方法。
注意:0.25em 的回退调整有点不稳定。 为了完美实现它,您可以在父元素上设置 font-size: 0;,然后在内容容器内部将字体大小恢复。
示例链接已损坏。 很棒的技术! 谢谢! =)
看起来 JSfiddle 宕机了。 希望它能尽快恢复。
我一直都在寻找类似的东西。 等不及要看到演示了 :)
我认为这是一个很好的示例! 我也一直在等待演示……
非常酷,我将开始使用它! 真的很有趣,我怀念使用旧的
<center>
标签,因为它会自动将所有内容水平居中。 唉:P为什么要为可以在样式表中使用简单的 text-align:center 完成的事情添加多余的标记?
我不明白添加“幽灵元素”的优势。 您能详细说明一下吗?
CM
幽灵元素的高度是父元素的 100%,因此任何与之垂直对齐的内容都将与其居中对齐。 这就是整个方法的运作原理。
我在您的演示中尝试在 HTML 条件注释中添加一个 span(用于 ie7-),定义相同的属性(除了内容),但不起作用。 所以我用其他 span 替换了 div(由于 ie7- 对自然块级元素分配内联块存在 bug),并且起作用了!
这对语义和代码验证来说很遗憾,但比使用表格要好,不是吗?
示例:<a href=”http://jsfiddle.net/vTQBs/”>http://jsfiddle.net/vTQBs/</a>
抱歉,更新后的测试:http://jsfiddle.net/wFPhW/
这在 CSS 中生成了如此多的代码,仅仅为了避免简单的 4 行代码。
请告诉我,对于这种应用来说,
<table>
为什么不够语义化?表格是一个表示数据的元素,任何其他用法都不语义化。
您也可以使此 CSS 代码可重用,然后您可以像 “干净的 clearfix” 一样在整个网站中使用它。 您将获得语义性和可维护性。
我认为这是一个很棒的代码片段。
感谢 Chris
说真的,我们还在讨论这个吗? 现在是 2011 年。
说真的,拥有 .centered 类也不语义化。 它将设计规范引入您的 HTML 中。
vertical-align: middle
声明是否应该放在包含display: table-cell
的选择器上? 有一天,我看到vertical-align: middle
放在包含display: table
声明的选择器上(父元素)然后是(希望有)flexbox
box-orient: vertical;
box-pack | box-align: center;
并且没有提到如何使用 jQuery 作为主要操纵器来实现垂直居中的渐进增强? ;)
太棒了! 我实际上要坐下来看看是否能想出类似的东西,但这要干净得多。
不会
<div class="wrapper"><div class="inner">内容</div></div>
与
.wrapper { float: left; position: relative; left: 50%; }
.inner { float: left; position: relative; left: -50%; }
在这种情况下起作用并更优雅吗?
当然——不能垂直居中。 抱歉……
太棒的小技巧了!这让我不禁思考,:before 和 :after 伪元素还有多少未开发的潜力。
我相信,人们越意识到它们的用处,大家代码的简洁性就会越高。
当然不是跨浏览器兼容的,但不管怎样。
你是说 transform 吗?它对于所有主要浏览器的最新最终版本(除了 IE10)都是跨浏览器兼容的。
这是一个非常巧妙的方法,我以前不知道。谢谢!
但令人遗憾的是,没有直接的方法来实现如此简单的事情。我真的认为 CSS 应该从头开始重新思考。
Chris,当您不知道父元素的大小,但知道子元素的大小,那么还有另一种通过纯 CSS 实现居中的方法。
Stu Nicholls 在 2006 年做了一个类似的演示,可能会有帮助。他写了他的解决方案。
以下是他的演示链接:
在已知大小的外层容器中居中未知大小的图像
inline-block 的间隙是否总是 0.25em?
http://www.lifeathighroad.com/web-development/css-web-development/inline-block-whitespace-workaround/
我还没弄明白的是,如果我有一个包围一个 div 的锚点,假设是 200px x 200px。
我希望整个 div 都成为一个大链接,而不仅仅是里面的文本。有时文本会换行到两行或更多行。我希望文本在整个块级锚点内垂直居中。
我不担心 IE6 支持,但如果有人能做到这一点并提供示例,我会给你 10 美元!:)
如果我表达得不够清楚,一张小图可能会有帮助。
———————————————
|
| 这段文本和整个
| 周围应该
| 居中且可点击
|
|
———————————————
要使整个 div 成为链接,您可以使用“onclick”像这样
onclick="location.href='https://css-tricks.cn'"
要使其看起来像链接,您还需要在 CSS 中更改光标。
cursor:pointer;
我为您做了一个示例
http://jsfiddle.net/R2eDQ/
希望我能帮到您!
很棒的技巧,但标题应该是“未知元素的居中”:)
该解决方案解决了当居中块的高度(与其容器相反)未知时垂直居中的问题。
它要求容器具有已知且固定高度。
没有,不是这样吧?
如果容器元素有 min-height,这也行不通——伪元素会立即获得高度为零。我修改了 Chris 的笔:
http://codepen.io/anon/pen/dFfmG
我和 Christopher 遇到完全相同的问题:一个设置了 min-height 的容器,但由于带有 min-height 的父元素的子元素不会像预期那样适应 height: 100%(就像这种情况下的伪元素一样),所以对我来说不起作用。
最终,我将伪元素的 min-height 设置为与父元素相同。这似乎没有任何问题,而且当子元素的高度超过父元素时不会造成问题。我制作了一个包含比较和一些视觉指示器的示例,以便您了解正在发生的事情:http://jsfiddle.net/XXQeB/
我错过了对解决方案的更深入的解释。
– 到底发生了什么
– 为什么你需要它们都被“中间化”?
嘿 Chris,
对我来说,和 Mark 一样。当我设置
因为我不知道浏览器窗口的高度,所以里面的所有东西都跑到顶部了。:( 我是不是漏掉了什么?
来自柏林的问候。
是的,我漏掉了!
之前的所有对象也必须设置 height: 100%。
Ferge,
你说得对,直到我将 html/body 的高度设置为 100%,垂直居中才对我有用。
Chris,
当我将浏览器窗口最小化到小于指定内容宽度时,会发生一件奇怪的事情——我会得到一个垂直滚动条,内容会下降到视窗下方。我通过将 body 的 min-width 设置为与内容宽度匹配来修复它。结果 CSS
html, body { height: 100%; margin: 0; }
.wrap { width: 100%; height: 100%; text-align: center; }
.wrap:before { content: “”; display: inline-block; height: 100%; vertical-align: middle; margin-right: -0.25em; }
.centered { display: inline-block; vertical-align: middle; width: 960px; }
body { min-width: 960px; }
我一直需要做这个:在一个已知的父元素内居中、可变高度的图像,并在图像下方对齐一个标题。我认为,如果不使用 JS :(,这是不可能的。
每个时代都有自己的技术。几年前,我们知道浏览器的局限性,所以伪元素不是一种选择。Bruno Fassino 测试了 display: table-cell 用于“现代”浏览器,并结合了用于 IE 的 display: inline-block hack。http://www.brunildo.org/test/vertmiddle.html 和 http://www.brunildo.org/test/img_center.html
Gary Turner 的文章很好地描述了这种技术。Chris Hester 已经指出 Stu 做了类似的测试和解决方案。
从今天看来,将这些解决方案视为“非语义化”是目光短浅的。这是当时你能做到的最好的事情——你是站在巨人的肩膀上。
嘿 Chris,这里有一个在任何可能的浏览器中轻松居中网页上 div 的方法 :),或者至少在我测试的所有浏览器中。
这篇文章的全部内容在这里:http://www.kensfi.com/how-to-align-center-a-div-with-no-width-declared/
顺便说一句,只有两行 CSS 和有效的标记 :)。
再次说一遍,对不起… 今天之后有点累。
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
<title>无标题文档</title>
<style type=”text/css”>
ul { text-align: center; }
li { display:inline; padding:0 10px 0 0 }
</style>
</head>
<body>
<div>
<center>
<ul>
<li><img src=”http://www.kensfi.com/images/pict.jpg” width=”200″ height=”166″ /> </li>
</ul>
</center>
</div>
</body>
</html>
终于!我尝试过很多技术来将元素居中到包装器内,这是我见过的最好的方法。
恭喜并感谢您分享!
有趣的是,昨天我遇到了完全相同的问题,最后使用了烦人的旧表格。我确实需要支持 IE7,所以我想现在就保留它。
感谢分享 :)
非常有用!
真正的问题是:为什么 W3C 这么多年来都没有尝试解决这个问题?也许是因为垂直居中不是与样式相关的问题,或者 W3C 是这样看待的!对我来说,垂直居中到未知的父元素是一个非常动态的视觉效果,因此属于行为层… 也就是 JavaScript。例如,lightbox,你已经需要 JS 来弹出框,你也可以让 JS 来定位它。
视觉效果可能假设知道父元素的宽度。
该死,CSS 真是丑陋。看看 AXR 项目 (http://axr.vg)。这个东西只需要你三行代码。
那为什么你又会来 CSS-Tricks 呢…?
那为什么你又会来 CSS-Tricks 呢…?
只是为了清楚起见,使用纯粹用于布局目的的 *非语义* 代码是正确的。
我们使用 div 来包裹我们的内容,因为它们没有任何语义含义,而不是因为它们具有 *正确* 的语义含义。span 也一样。
在这种情况下,使用表格是不正确的,因为表格具有固有的语义含义。
通过使用 span 和 div,我们没有弄错语义;我们只是根本没有语义。在这种情况下,这是一件好事。
我说的对吗,Chris?
我使用的解决方案与 Chris 的原始解决方案相同,但扩展到与浏览器和版本兼容……因此,Chrome、Firefox、Opera 和 IE(6 到 10)。
您无需知道任何高度或宽度,并且在过去 10 年的每个主要浏览器及其版本中都适用。
没有 JS,只有 CSS hack……
演示
http://www.mattpass.com/lab/hCenterVCenter
CSS……
我不能说是我创建了这个解决方案,但我认为应该与大家分享!:)
酷
这将派上用场!但是内联块的行为如何?我之前使用过内联表格和内联。
在居中“table-cell”元素时,不要忘记移除 float:right | left。
否则垂直对齐不起作用。
嘿,感谢分享!
我想知道什么时候需要垂直居中某个东西,而文本必须左对齐?
我有一个收集诗歌的网站,我无法找到一个万无一失的解决方案,因为每首诗歌的行宽都不同。
此外,从排版角度来看,每首诗歌的标题都应该位于平均行宽的中心。
如果您能帮我考虑一下这个问题,我会非常高兴。
干杯!
Greg
只晚了短短几年,但解决方案实际上很简单
.verse pre {
display: table;
margin: 0 auto;
}
干杯!
gary
我发现了一种更简单的方法,不需要伪元素:http://codepen.io/edge0703/pen/iHJuA
只需将容器的高度和行高设置为相同的值。
如果有多行呢?
干杯!
gary
多行不是问题。我已经更新了演示,以便您可以看到内联块可以具有任何所需的高度:http://codepen.io/edge0703/pen/iHJuA
如果父级高度为 250px 呢?
即使设置了 .block 容器的高度,幽灵元素技术也不适用于绝对定位的 .block 容器。我还不确定 CSS 表格的方式,现在要试一试。感谢您的提示!
@ Chris Coyier
感谢您的提及。我刚注意到这个网站作为本月的引用。
gary
这似乎在文件中不起作用。
它水平居中,但垂直对齐只有在没有 . 的情况下才起作用。
非常感谢您的帮助!:)
最简单的方法,只需定义尺寸并活得更久,这篇文章毫无意义。
.Absolute-Center {
margin: auto;
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
width: 100px;
height: 100px;
}
哦,真的吗?恭喜你一个月前这个方法就流传开了,你现在才发现它。
太棒了,你的评论就像魔法一样!:)
在移动尺寸下,这种幽灵方法似乎会将居中的内容强制到其父级之外和下方,而 display: table 方法则非常棒。
在 Win7 上,Michal 的方法在 Chrome v31.0.1650.57 m、Opera v12.16 和 Safari v5.1.7 (7534.57.2) (abandonware) 上运行完美。
它在 Internet Explorer v9.0.8112.16421 Update v9.0.22 和 Firefox v25.0 上失败。要垂直居中的元素被推到其容器之外。它的顶部与底部相接。:)
我们仍然不得不耍这些花招,这真是太丢脸了。
这篇文章发布后 2 年多,Gary Turner 的文章发布后 7 年多。
到达火星的旅行时间为 250-300 天。
由距离(每隔 2 年就会变化数百万公里)、宇宙飞船的大小、旅行速度、发动机以及可以携带的燃料量(燃料越少,速度越低,旅行时间越长)决定。
假设 NASA(或任何其他航天机构)的家伙有一个酒鬼。他们喝了一些燃料。好的,所以燃料减少了,因此速度也降低了。假设宇宙飞船需要 365 天才能到达火星。由于 Gary Turner 在(7 年多前的 2006 年中旬)发表了他的文章,这意味着至少有两艘宇宙飞船到达了火星。甚至可能还有 3 艘,具体取决于两颗行星之间最近点何时到达。
而这些浏览器供应商甚至无法为我们提供一个“vertical-center”属性。
NASA(和其他航天机构)的人一定在笑得前仰后合:“这并不是真正的火箭科学。”
附注:我们不能确定任何事情。即使 W3C 确实为“vertical-center”属性制定了规范,我们的浏览器供应商朋友(在 W3C 或者不在 W3C)可能会对它进行自己的解释和实现。
天啊!好的,我刚发现原因。在
我使用了
width: 100%
而不是px
值。将100%
更改为实际的880px
解决了问题。现在在所有 5 个浏览器中都可以运行。但这并不是我想要的。没有px
值。它是用于响应式导航栏的。您在备注中说右边的边距有点奇怪,我也这么认为,为什么不利用这两个伪元素呢?http://codepen.io/mikevoermans/pen/hvwfn
这也会让它们居中。
嗨,Chris,
这种方法似乎不适用于图像。我在这里遗漏了什么吗?
http://jsfiddle.net/TmHe5/1/
在 Safari 中发现了一个小 bug。
如果您希望居中的元素(居中)与父元素(块)的宽度相同,并且使用无衬线字体,则定位将无法正常工作。为了使其正常工作,您可以使用文章末尾描述的“font-size: 0-method”。
如果有其他更好的解决方案……请告诉我。:-)
感谢这些技术。但是在进行了一些实验之后,我意识到这些解决方案中的许多在不同的场景下会造成一些麻烦。
坚持使用传统的表格居中,对我来说似乎是最快最可靠的方法。
我仍在等待完全的 flexbox 和网格支持,以避免此类问题。
我非常喜欢
vertical-align:middle
方法。不幸的是,它有一个缺点。虽然这不是障碍:如果您使用此技术来显示position:fixed
图层,并且浏览器宽度变得小于居中元素,它就会消失。可以使用媒体查询解决这个问题:)我的问题可以通过 white-space:nowrap 解决。:)
当在 FF [27.0.1] 中将居中元素设置为 `width:100%` 时,它会被推到 `:before` 下面,为了防止这种情况,我将轻微调整(`margin-right:-0.3em;`)应用于居中元素。
感谢 Chris 的分享……当您需要在响应式网站上将垂直居中的 div 层叠到图像上时,这是一个非常优雅的解决方案 :)
我发现它在较小的屏幕上失效了,但通过这个简单的微小编辑,垂直居中问题就解决了 :)
`/* 幽灵,轻微调整以保持完美居中 /
.block:before
{
content: ”;
display: inline-block;
height: 100%;
width:1px; / 将宽度设置为 1% 以便 .block-item div 不会换行 /
vertical-align: middle;
margin-right: -0.25em; / 调整间距 */
}
/* 要居中的元素,可以
也具有任何宽度和高度 /
.block-item
{
display: inline-block;
vertical-align: middle;
max-width:99%; / 将其设置为 99% 以便它不会换行 */
}
`
您为我省去了很多脑力劳动。谢谢!
非常感谢这些!
不幸的是,当您没有在 .center 上设置宽度,只使用填充时,伪元素解决方案似乎在 iOs (Chrome / Safari) 上不起作用。顶部被推到父元素的底部。我不知道为什么
真的——在 iOs 设备上不起作用。有了 Waseem 提供的修复,它不会溢出容器,但也不会居中。
这似乎仍然需要设置显式高度。没错,该高度可以是可变的,但这里有一个 示例 不起作用。在其中,父元素是一个具有清除浮动属性的容器,没有设置高度(高度由其中的浮动元素决定)。在这种情况下,为生成的内容设置的 `height: 100%` 似乎没有效果。
如何将一个溢出设置为隐藏的元素居中。例如,如果您想让一个元素作为大型图像的视窗。如何将“窗口”设置为图像的中心?
很棒的信息!经过一些调整,它完美地满足了我的需求。
另外,要使父 div 的高度以百分比形式工作,请将其位置设置为绝对。
这是一个很棒的解决方案!感谢您和 Michał Czernow 的分享!另外,感谢您提供这个很棒的网站!我几天前发现了它,并且经常访问这里!
很棒的技巧!
然而,当父元素(在您的示例中为“.block”)的高度设置为百分比时,::before 技术不起作用。解决方法是用一个 div 而不是伪元素 :)
干杯 :)