如果您只有一行文本或一个单词,则可以使用一种巧妙的方法通过 CSS 将其在块级元素中垂直居中。 将该文本的 **line-height** 设置为等于该框的 **height**。 效果很好,但如果该文本需要换行,则会失败。
“气泡” 是一个经典的示例,我们可能希望文本在水平和垂直方向上都居中,并且能够适应多行。 使用 CSS 表格有一个简单的小 CSS 技巧可以实现这一点。 以下是结果
HTML 代码很简单。“区域” 只是我们正在处理的区域,我们可以在其中设置 position: relative;,以便我们可以绝对定位气泡内的文本区域。
<div class="area">
<div class="bubble">
<p>To look best, text should really be centered inside this bubble both vertically and horizontally.</p>
</div>
</div>
我们将“气泡” 设置为 display: table;,它本身并没有做太多事情,但随后我们可以将内部的 <p> 元素设置为 table-cell,**这允许我们对其使用 vertical-align 属性。**
.area {
width: 300px;
height: 300px;
background: url(../images/abe-bg.png) no-repeat;
position: relative;
}
.bubble {
position: absolute;
left: 93px;
top: 21px;
width: 135px;
height: 84px;
display: table;
}
.bubble p {
display: table-cell;
vertical-align: middle;
text-align: center;
}
我认为这个技巧非常棒。 当前版本的 CSS-Tricks 在页脚处有一个小型的 Twitter 气泡,我用它实现了这一点。
IE <= 7 怎么办?
IE 8 支持 CSS 表格,但 IE 7 及更低版本不支持。 太可惜了。 相反,您会看到这个
… 情况可能更糟。 我希望 Dean Edwards 的 ie8.js 可以解决这个问题,但没有成功(至少目前还没有)。
更新 1
Boris Kuzmic 在下方评论了一个完美的解决方案,可以使 IE 6 和 7 完美工作
<!--[if lt IE 8]>
<style>
.bubble { position: absolute; left: 93px; top: 21px; width: 135px; height: 84px; text-align: center;}
.bubble p { position: relative; font-size: 11px;
margin-top: expression(this.offsetHeight < this.parentNode.offsetHeight ? parseInt((this.parentNode.offsetHeight - this.offsetHeight) / 2) + "px" : "0");
}
</style>
<![endif]-->
更新 2
Boris 再次提供了一种方法,可以防止 IE 表达式泄漏内存(这样它只需要评估一次,而不需要持续运行)。
.bubble p { position: relative; font-size: 11px;
margin-top: inherit;
*clear: expression(
style.marginTop = "" + (offsetHeight < parentNode.offsetHeight ? parseInt((parentNode.offsetHeight - offsetHeight) / 2) + "px" : "0"),
style.clear = "none", 0
);
}
更新 3
James John Malcolm 也提供了一种针对 IE 的技术。 它的语义性略差(需要一个额外的 div),但不需要表达式。
首先将内部的 <p> 包裹在一个新的 <div> 中,然后
<!--[if lt IE 8]>
<style>
.bubble div { position: absolute; top:50%;}
.bubble div p {position: relative; top: -50%}
</style>
<![endif]–>
我以为你不喜欢 CSS 表格?
哈哈!是的,确实如此,总的来说我不喜欢它们。 但我不喜欢它们是因为它们没有提供表格标记本身已经提供的任何东西。 *哇,我可以让这个 div 充当表格单元格!* 为什么不直接使用表格单元格呢?
在这种情况下,我们通过使用它并利用它允许垂直对齐的独特属性来节省标记。 所以这不是欺骗,而只是一个不错的技巧。
我是否理解正确,CSS 基本上可以将 HTML 简化为最小的规模?
例如,假设我有 斜体和粗体文本
我是否可以使用 CSS 完全去除这两个标签的样式,然后将它们变成我想要的任何样式? 因此, 标签现在可以使某些内容变为斜体,而 <i> 标签现在是一个段落标签?
如果是这样,那么理论上你可以将任何标签变成表格标签 :)
干得好,Chris。 我喜欢上面提到的“我以为你不喜欢 display:table?”。 无论你是否喜欢它,你仍然深入研究它以发现它实际上如何有用。 绝对是 CSS 狂热者的标志 :) 干得好。
“幻觉,迈克尔! 技巧是妓女为了钱……或糖果而做的事情!” – GOB
忍不住。 ;-)
一如既往地很棒。 只希望从 IE7 迁移到 IE8 的过程更加顺利和快速。 该死的遗留软件。
看起来不错,如果 Dean Edward 的脚本支持它,那将非常棒!
如果您不介意不同的高度框,则顶部和底部的等边距也可以。
好技巧,但 IE6 太糟糕了……。
我使用 Dean Edwards 脚本没有任何运气。 非常令人沮丧!
不过技巧不错。
感谢你的提示,但由于大约 40% 的用户仍在使用 IE6 和 IE7,因此对于我来说,有太多用户无法正确查看,我无法切换到它。
这是我最喜欢的技巧之一! 非常棒的总结 :)
嗯。 如果使用一些 jQuery 会怎么样? 您有两个框,计算每个框的大小,然后进行两次减法,您就知道在哪里放置气泡内的段落。
Bogdan,那将是在使用 javascript 进行表现层控制。 只要有可能
xhtml 应该以语义的方式标记所有内容
css 应该处理所有内容的表现形式
javascript 仅应分配行为
你的意思是
IE <= 7 怎么办?
这是一个开始,但只是解决方案的一半——如果它在邪恶的浏览器 IE6 和 IE7 上不起作用,那么在现实世界中它就没有用……。
使用条件注释和位置技巧(一个在顶部/左侧为 -50% 的相对定位的 div,位于一个顶部/左侧为 50% 的绝对定位的 div 内),它可以在跨浏览器中正常工作。
在 IE 6 和 7 中,您可以这样做
<!--[if lt IE 8]>
<style>
.bubble { position: absolute; left: 93px; top: 21px; width: 135px; height: 84px; text-align: center;}
.bubble p { position: relative;
display: inline-block;
margin-top: expression(this.offsetHeight < this.parentNode.offsetHeight ? parseInt((this.parentNode.offsetHeight - this.offsetHeight) / 2) + "px" : "0");
}
</style>
<![endif]-->
只需将其放在此行下方的 <head> 元素中
<link rel="stylesheet" type="text/css" href="css/style.css" />
您不需要“display: inline-block;”——我一直在尝试使用 span 标签而不是 p 标签来使其工作
万岁!Boris 今天获得了三颗闪闪发光的金星!
它运行良好,我已经更新了实时示例以包含此内容。
提醒:如果您要复制粘贴上面的代码,WordPress 可能会将直引号替换成斜引号,所以请将“px”和“0”周围的引号修改为直引号。
Chris,我想我找到了一个终极的技巧 :-)。我今天能得到多少颗星?! :-)
看看这个
.bubble p { position: relative; font-size: 11px;
margin-top: inherit;
*clear: expression(
style.marginTop = "" + (offsetHeight < parentNode.offsetHeight ? parseInt((parentNode.offsetHeight - offsetHeight) / 2) + "px" : "0"),
style.clear = "none", 0
);
}
这将强制 IE 只执行一次表达式,从而避免内存和性能问题。
灵感的来源是这篇很棒的文章
IE CSS 表达式的单次执行
很棒的技巧,我得把它加入我的技巧包里!:D
谢谢,
Anthony Proulx
Chris!请注意,使用 IE 表达式会导致严重的内存泄漏(它一直在运行)。
DN 是对的,表达式会导致内存泄漏。在这种情况下不会发生,但存在一个性能问题:表达式一直在运行(当您移动鼠标时,当您滚动时,等等)。因此,为了避免这种情况,您可以为 IE 6 和 7 使用这段简短的 Javascript 代码(将其放在 HTML body 的末尾)
<!--[if lt IE 8]>
<script type="text/javascript">
// 使所有气泡垂直居中
var ps = document.getElementsByTagName("p");
for (var i=0;i<ps.length;i++) {
if (ps[i].parentNode.className=='bubble') {
ps[i].style.marginTop = ps[i].offsetHeight < ps[i].parentNode.offsetHeight ?
parseInt((ps[i].parentNode.offsetHeight - ps[i].offsetHeight) / 2) + "px" : "0";
}
}
ps = null;
</script>
<![endif]-->
此外,从 .bubble p 类中删除 margin-top 样式。
对于一个简单的技巧来说,这开始变得代码量很大了。尽管做得很棒,但我个人倾向于忽略 IE 的这些小显示错误……并鼓励人们更新他们的浏览器 :)
很棒的技巧!谢谢!
我非常喜欢那个对话气泡。
您介意我将该图形用于我的网站吗?
是的,这绝对是一个技巧。我更愿意只使用一个简单的表格。HTML 代码更多,但代码更清晰。
不,这不是技巧。它是在使用 CSS 进行表现……这就是它的用途。在这种情况下使用表格才是技巧。而且代码一点也不复杂,除非你对 CSS 还不太了解。
当需要并且在所有浏览器中都能正常工作时,我使用表格。为什么这些人不惜一切代价避免使用表格,最终却创造了一个更复杂的解决方案?
这并不是完全避免,而只是正确地使用它。由于由单个段落组成的对话气泡不能被视为表格数据,因此在这种情况下使用它是不合适的。另一方面,表格非常适合存储多列、多行数据。
你完全正确。
众所周知,在所有主要浏览器都支持之前,不应使用高级 CSS。
这篇文章对任何人来说都没有什么新意,这里也没有什么技巧。
它只是每个人都一直知道的 CSS,但不会使用它,因为
IE 不支持。所以……我现在仍然不会使用它。:)
我个人认为没有必要让所有浏览器中的所有内容看起来都完全相同,这是一个很好的例子,说明在某些情况下,细微的差异可以让现代浏览器看起来很好,而旧版浏览器仍然可以正常运行。
为了折衷,您可以使用 display:table-cell 和 vertical-align 结合一些垂直填充——这样即使是旧版浏览器也不会显得拥挤和难看。
非常棒的技巧!谢谢!
当我第一次发现 CSS 中没有简单的方法来像这样垂直居中文本时,我感到震惊。水平居中没有问题,但为什么垂直居中必须如此复杂?
它应该像 vertical-align:middle 或 margin:auto 0 一样简单
要在 ie6 和 ie7 中使其正常工作,唯一的选择是使用表格或一团乱麻的 css。
我们能够找到一种方法使其在 IE 6 和 7 中工作,这很棒,但我认为我们不能称之为“CSS 友好”,所以我们应该尽量避免它 :(
这就是为什么它被称为技巧——丑陋但必要。无论如何,我发布的最后一个解决方案 是 IE CSS 友好的,并且使开发人员的生活更轻松。
好的技巧,但在 CHROME 中看起来不好 ;-)
您使用的是哪个版本的 Chrome?- 我刚刚用 1.0.154.65 尝试过,它工作正常。也许您指的是第一个气泡中的文本(应更改字体大小)。
如果要使用图像而不是文本怎么办?
我创建了一个简单的居中登录页面来展示如何使用此技巧。
查看:CSS 居中登录页面
对一个常见问题的绝妙解决方案。大小可变的块级元素在水平和垂直居中时会出现一些古怪的问题。CSS 表格将为这些问题提供(不太理想的)解决方法。
嗯,CSS 中垂直居中的常规方法 已由 Dušan Janovský 记录在案。它的 IE 解决方案需要一个额外的 div,但它不需要任何表达式,只需要常规的 css。
我已更新示例以使用条件注释而不是技巧。HTML 变成
<div class="area" id="two">
<div class="bubble">
<div>
<p>这样做可能不像我们希望的那样简单或直观。</p>
</div>
</div>
</div>
样式表变为
#page-wrap { width: 600px; margin: 0 auto;
.area { width: 300px; height: 300px; background: url(abe-bg.png) no-repeat; position: relative; float: left; }
.bubble { position: absolute; left: 93px; top: 21px; width: 135px; height: 84px; display: table; }
.bubble div { display: table-cell; vertical-align: middle; text-align: center;}
IE 特定的 css 变为
<!--[if lt IE 8]>
<style>
.bubble div { position: absolute; top:50%;}
.bubble div p {position: relative; top: -50%}
</style>
<![endif]-->
这真的很酷,James John Malcolm 的技巧是处理 IE 的一个很好的解决方案。顺便说一句……它不会跨浏览器工作吗?既然无论如何都需要额外的标记,为什么不只使用 James 的 CSS 并跳过表格技巧?
Chris,我喜欢您创建的对话气泡示例 :)
再说一次,我在 2009 年 4 月 7 日写过类似的话题。如果您喜欢中文版本,这里有一个链接
http://www.61dh.com/blog/2009/04/css.html
是时候每个开发人员在显示在 <=IE7 用户机器上的每个页面顶部都放置一个巨大的可怕警告了。然后希望我们很快就能摆脱这些微软互联网犯罪,并节省大量时间!
我发现,如果您要在 IE7 或 IE8 中使用 offsetHeight 或 offsetWidth,请确保使用某些尺寸设置 HTML 标记……例如,或者在 css 中设置标记;
例如。
html { height: 100%; width:100%; }
希望这个小信息能帮助到一些人。
真是太搞笑了,我们竟然在使用 CSS(IE8!)来模拟表格单元格的行为,而之前我们却被告知表格是魔鬼的玩具。为了得到 v4 浏览器使用表格就能轻松实现的结果(而且是跨浏览器兼容的),我们不得不跳过多少障碍和条件语句啊!我们都疯了吗?
哇……真希望 IE 能意识到它们带来的问题比解决方案更多,然后让 Firefox 接管它们……。
很棒的博客!已订阅 RSS。会定期阅读。干得好。
优秀的博客!文章非常有趣。我将一直阅读它。也订阅了 RSS。
很棒的文章。在我看来,CSS3 开发人员需要创建一个 multi_center 选项。我理解这样的选项需要更多的渲染计算,所以为了性能考虑,将其与简单的 'center' 区分开来是合理的。也就是说,这是我的第三个 CSS3 项目,你可能会认为这不会是一项如此困难的任务。轻松成为最“看起来简单但实际上很难”的样式之一。