与 CSS 垂直对齐

Posted

技术标签:

【中文标题】与 CSS 垂直对齐【英文标题】:Vertical alignment with CSS 【发布时间】:2011-06-12 08:49:29 【问题描述】:

是的,是的,我知道这是另一个关于 CSS 垂直对齐的问题,并且之前已经完成了一百万次。请放心,我已经多次遇到这个问题,并且我已经阅读了有关使用 CSS 垂直居中的各种方法。我在这里问是因为这些方法都不能完全满足我的要求,我只是想确保我的怀疑(CSS 垂直对齐被破坏并且不会做我想做的事)是绝对正确的。

首先,这是我的测试用例:http://www.game-point.net/misc/testAlign/

这是标准:

我想垂直对齐“居中文本”,相对于包含“TestTestTest...”文本的 DIV。 我不想指定任何高度。 我希望 'TestTestTest' 和 'Centred text' DIV 根据它们拥有的文本数量和宽度限制动态获取它们的高度。 我不想使用 javascript

这似乎在 CSS3 中也是不可能的,更不用说 CSS2了。烦人的是我快到了。 position:absolute; top:-50%; DIV 用于将该 DIV 的顶部设置为容器 DIV 的一半。问题是内部 DIV,样式为 position:relative; top:-50%; 并没有做任何事情来将内容向上移动一半高度,以使其完全居中,因为 CSS 说绝对定位的 DIV 没有高度,因此 @ 987654325@ 毫无意义。据我所知,这只是 CSS 中的一个根本缺陷,没有什么特别的原因。绝对定位的元素确实有高度,我不知道为什么 CSS 会假装它没有。我只是想问一下,根据我上面概述的标准,是否有人对我如何达到预期的效果有任何想法,如下图所示。具有讽刺意味的是,IE6/7/8 的“破碎”盒子模型,在怪癖模式下,给了我这种效果。可惜他们在 IE9 中“修复”它,所以它不会了。

【问题讨论】:

好吧,您总是可以使用 jQuery 来发挥作用。但据我所知,您的怀疑可能是正确的。 认为你现在可以用 flexbox 做到这一点css-tricks.com/snippets/css/a-guide-to-flexbox 【参考方案1】:

好的,我的怀疑确实是正确的,这是不可能的(我认为这是 CSS 中的一个缺陷,它们应该提供一种 DIV 内的垂直对齐方式,而无需指定内部元素高度)。

我最终得到的最不坏的解决方案是:指定“中间”DIV 的高度 - 即使用 position:absolute 显示并包含真实内容的 DIV。我已将其添加到 http://www.game-point.net/misc/testAlign/ 的测试用例页面中,标题为 With line-height:100% and hardcoded 'middle' DIV height。这种解决方案意味着您必须事先知道要垂直居中的内容的高度,这很糟糕,因为浏览器会计算这个并且您不需要指定它,但这是唯一的方法(直到 CSS 一起行动)。我也使用ems 来指定高度,这样放大和缩小文本不会破坏垂直居中。事实证明,对于我拥有的 2 行“居中文本”,这个高度正好等于 2 ems(至少在我的机器上)。如果我要更改该内容的高度,或者要动态更改为 3 行或 1 行,则父 div 的硬编码 em 高度也必须更改。

所以,如果有人感兴趣,这是我最终得到的代码:

    <div style="border:1px solid black; padding-left:60px; width:250px; position:relative; word-wrap:break-word;">
        TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest
        <!-- Unfortunately, must set this DIV's height explicitly or the contained DIV's relative positioning won't work, as this DIV is considered to have NO implicit height -->
        <div style="position:absolute; display:block; top:50%; left:0px; height:2em;">
            <div style="position:relative; top:-50%; background-color:#00aa00; line-height:100%;">
                Centred text<br/>
                Centred text
            </div>
        </div>
    </div>

【讨论】:

【参考方案2】:

使用margin-top: 而不是top:,如margin-top: -25%;

【讨论】:

这很好,但没有考虑居中框的高度变化。因为它应该是动态的,所以这可能是个问题。 有趣... margin-top 的百分比值与什么有关?那么,它是什么的-25%?如果我将居中的文本减少到 1 行文本,则它不会正确居中。【参考方案3】:

问题在于,出于显而易见的原因,以这种方式对内容进行垂直处理,我相信您已经意识到了这一点。但是你有点试图解决一个无法解决的问题,那不是真正的问题。 (当你知道事情为什么会这样时才有意义)

通过使用绝对位置,您只是将内容从自然流中取出。最好用浮点数和适当的尺寸或任何需要的东西来制作所有东西,这样它就可以很好地降级并且在所有设备中看起来都很好。然后在 jquery 中编写两行代码来检查高度并对齐所有内容(这也适用于“所有”设备)。没有 JS 的 2-3% 将需要忍受无聊的网站。

【讨论】:

是的,我正在从自然流中提取一些内容;这是将某些文本覆盖在其他文本之上的唯一方法。你有什么建议?您似乎在说要获得比 Netscape 3 更进一步的功能,您需要使用 Javascript。我认为 CSS 旨在比这更强大。 我的意思是,如果你把内容从自然流中取出,你就在某种程度上剥夺了 div 内容的动态能力以自然扩展。一个绝对定位的 div 在这个区域是有限的。所以完全像你说的那样解决它我很确定是不可能的。出于好奇,为什么没有 jQuery?现在它是如此快速和简单。 "这是将某些文本覆盖在其他文本之上的唯一方法。" z-index呢? @Knu z-index 使用绝对定位,你只是说绝对层应该在什么深度。 @nex 你是说我不能将position: relative 与 z-index 一起使用?【参考方案4】:

我已经开始使用以下代码到达某个地方......虽然需要工作。

基于在 http://www.jakpsatweb.cz/css/css-vertical-center-solution.html 上找到的项目

注意,您的代码运行在 quirks 模式下,我已将其更改为 html 5

<!DOCTYPE HTML>
<html>
<head>
    <title>Vertical align test</title>
</head>

<style type="text/css">


#outer  overflow: hidden; position: relative; border: 1px solid red; 
#outer[id] display: table; position: static;

#middle position: absolute; top: 50%; /* for explorer only*/
#middle[id] position: relative; display: table-cell; vertical-align: middle; width: 100%;

#inner position: relative; top: -50%; width: 100px /* for explorer only */
/* optional: #inner[id] position: static; */

</style>

<body>
<h1>New test</h1>

<div id="outer">
  <div id="middle">
    <div id="inner">
      any text<br>
      any height<br>
      any content, for example generated from DB<br>
      everything is vertically centered
    </div>

  </div>

test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test 
</div>


</body>
</html>

【讨论】:

不幸的是,这使用了 display:table。这会阻止人们使用 CSS word-wrap: break-word;(它不会在表格单元格内中断),所以我希望在没有 display:table 的情况下这样做。【参考方案5】:
.item 
    height: 40px;
    top: 50%;
    margin-top: -20px;

相对或绝对位置;

【讨论】:

OP:“我不想指定任何高度。” 还有其他解决方案使用边距设置为自动,但我认为它也需要指定高度。

以上是关于与 CSS 垂直对齐的主要内容,如果未能解决你的问题,请参考以下文章

CSS 垂直对齐类型与图像

与 css 垂直对齐时,何时使用绝对位置与相对位置

有没有办法将文本与 CSS 内容属性(chrome)中的图像垂直对齐?

如何在表格单元格的垂直中心对齐 CSS 箭头?

css在一个div中水平+垂直对齐3个元素

css实现垂直顶部与底部对齐上下两端对齐heightdisplayflexwrapaligncontentspacebetweennowrapreverse