论坛用户 McAsh 想知道 他们如何才能编写一个设计,其中包含一个大型标题,下方是一个较小的副标题,副标题中包含双水平线,在居中文本的左右两侧伸出。这很容易以图像形式进行模拟,但在 CSS 中由于文本的变量特性(长度、大小等)而更难实现。
帖子模拟如下

我编写了一个有效的实现方法,但并不完美。我想我会在这里发布它,如果您能想到更好的方法,请随时提出。
如果背景是纯色,这将非常容易。将带线条的背景应用于副标题,并在中间居中一个 span,并在 span 中添加一些内边距和与纯色背景匹配的背景颜色。这里我们没有纯色背景。可能使用相同的背景图像但固定背景位置会起作用,但我没有尝试这种方法。
相反,我使用 ::before 和 ::after 伪元素创建左右两组线条。文本仍然在 span 中,该 span 处于相对定位状态。右侧线条是该 span 上的伪元素,从左侧 100% 开始,并带有一点边距将其推开,左侧线条则相反。两者都具有固定的高度,并使用 border-top 和 border-bottom 创建线条。因此,没有使用任何背景,所有内部都透明。
线条的长度足够长,始终会超出父容器,并且会通过父容器上的隐藏溢出被截断。
.fancy {
line-height: 0.5;
text-align: center;
}
.fancy span {
display: inline-block;
position: relative;
}
.fancy span:before,
.fancy span:after {
content: "";
position: absolute;
height: 5px;
border-bottom: 1px solid white;
border-top: 1px solid white;
top: 0;
width: 600px;
}
.fancy span:before {
right: 100%;
margin-right: 15px;
}
.fancy span:after {
left: 100%;
margin-left: 15px;
}
示例
Check out this Pen!
有两个我不喜欢的地方。
- 里面的 line-height: 0.5 用于将线条居中在文本周围,对我来说感觉像是“魔数”,它可能不适合所有字体。
- 伪元素线条的宽度并不完全符合要求,但比实际需要长得多,并被截断。
这些问题虽然不是特别严重,但可以巧妙地解决。
太棒了!将在我的下一个项目中使用!
一种简洁的方法是使用 CSS 渐变。可以使用无后备或 dataURL。
更改颜色。
“花哨的 span”哈哈,真聪明!
我刚刚完成了一个类似的实现,使用 span 居中文本并添加纯色背景以作为透明度,并添加了一些内边距。
我从来没有真正考虑过是否要在没有纯色背景的情况下使用它。
感谢 Chris 的分享。
Chris,为了解决你的“魔数”问题,你可以使用基于百分比的定位(top: 50%)在伪元素上。这也可以让你将 overflow: hidden 应用于 .fancy 元素而不是 <article>,这样很好,因为你可能需要让其他伪元素超出 <article>。
代码如下
由于你始终知道双线装饰的高度,你可以设置一个负 margin-top 等于该高度的一半。Sass 不是必需的,但我使用它来展示这种方法不需要估计数字。
我尝试测试你提供的代码。我从 Codepen 上尝试了它…没有使用自定义字体。我的结果是一条实线。而原始方法有效。我测试时没有更改“魔数”;所以我不知道这是否会改变。
这种方法在将线条偏移到左侧或右侧时尤其有用。
我在构建的网站中遇到了同样的问题,我这样编写了代码
http://codepen.io/ahmedelgabri/pen/lfjdJ
该网站有两种变化,一种跨越容器的整个宽度,另一种没有填满 100%。
这里唯一我不喜欢的地方是,无论何时我想要在不同的背景上使用它,我必须更改 span 的背景颜色。
感谢你的代码,我为我们的用例重构了它,它工作起来非常出色。…
不错的解决方案,但我有一个问题,如何将它应用于图像(例如徽标),而不是文本?
你可以看看这个
http://pepsized.com/demo/?id=614
她就是这样处理的
h1:after {
content: “”;
height: 2px;
display: block;
position: absolute;
left: 0;
right: 0;
top: .5em;
z-index: -1;
border-top: 1px solid #504331;
border-bottom: 1px solid #504331;
}
很棒地使用了“embiggen”作为类名!这是一个完全正确的词语。 :)
你能在伪元素上使用 flexbox 吗?这样似乎可以更容易地完成这类操作。
实际上,display: table(-cell) 可能会起作用:http://codepen.io/aaronjamesyoung/pen/nFiDq
技术简洁明了。
我之前也处理过类似的主题,它在标题的两侧使用了一条水平线。
http://www.impressivewebs.com/centered-heading-horizontal-line/
除了我的四种方法,所有方法都使用了一个额外的 span,评论中还有很多其他建议,包括这个
http://www.impressivewebs.com/centered-heading-horizontal-line/#comment-34913
由 Pablo Villoslada Puigcerber 提供,不需要 span,我认为它也能在各种背景下工作。我实际上在我的网站页脚中使用线性渐变方法(Hugo 在上面提到的方法),我认为如果你不介意额外的 span,这很容易实现。在当今时代,你不应该介意额外的 span,因为删除它对宇宙中的任何事物都不会有任何影响。:)
这是一个快速的分支,它让它像 Chris 的示例一样变成两条线。它与字体大小无关。
http://jsfiddle.net/F3UqW/
这是另一个分支,移植到 Chris 原始的 Pen 上
http://codepen.io/anon/pen/vLFnw
@Colin - 你的方法非常有效 - 负边距很有效,只需要匹配伪元素的宽度即可。太棒了。
以下是如何使用 flexbox(仅 Chrome)来完成它,如 Aaron 所建议:http://codepen.io/anon/pen/IKbFx
以下是如何在不使用 flexbox 的情况下完成它,这消除了 line-height 的“魔数”问题:http://codepen.io/anon/pen/crEJa
第二个解决方案将 p.fancy 的宽度设置为 200%,然后使用 text-indent 为 -50%(200% 的 50% = 100%)将文本移回。这允许使用内联块伪元素,而不是绝对定位的元素。
以下是如何使用 flexbox(仅 Chrome)来完成它,如 Aaron 所建议:http://codepen.io/anon/pen/IKbFx
以下是如何在不使用 flexbox 的情况下完成它,这消除了 line-height 的“魔数”问题:http://codepen.io/anon/pen/crEJa
第二个解决方案将 p.fancy 的宽度设置为 200%,然后使用 text-indent 为 -50%(200% 的 50% = 100%)将文本移回。这允许使用内联块伪元素,而不是绝对定位的元素。
使用表格显示技术意味着你可以在没有任何其他元素的情况下完成它。Aaron Young 找到了正确的方向,但你不需要使用 span。这里是我之前在 StackOverflow 上的一个答案,它展示了如何实现:http://stackoverflow.com/questions/13714432/create-css-header-with-centered-logo-and-lines-that-extend-out-from-the-right-l/13714634#13714634
我非常喜欢表格单元格技术。我认为这是最好的方法。没有过大的元素。水平和垂直居中都很容易。
怎么样?
它在调整大小和缩放时是否安全?
http://codepen.io/anon/pen/eqnrB
改变大小似乎没有任何作用,但我猜想它不可能那么简单。
它有什么缺陷?
唯一的问题是,除了使用不同的字体之外,你无法更改两条线之间的距离。
我对此做了一个快速演示,请告诉我你的想法:http://codepen.io/catalinred/pen/bwqta
我决定使用伪表格单元格技巧。我将它与转换结合起来,使顶部和底部边框更靠近。这意味着我不需要
overflow: hidden;
,没有“魔法数字”,并且线条恰好是它们所需的宽度。http://codepen.io/Merri/pen/jFALy
因为这个技巧不依赖于多个背景或线性渐变,所以它也适用于更广泛的浏览器。即使是 IE8 也可以接受 :)
太棒了!这是一个很棒的解决方案——用你的转换想法跳出框框思考。
唯一的问题是,这对于标题可能需要换行的响应式网站不起作用(
white-space: nowrap
,如果删除此规则,它就会中断)。我很想找到适用于换行的解决方案。
PS - caniuse.com 也表明 IE8 不支持转换。这不会成为太大的问题,但我只是想补充一点。
太棒了——感谢发布。
很聪明。Internet Explorer 的支持情况如何?
嘿,Chris,我发现如果我给 .fancy :after 和 :before 伪线设置 100% 的宽度,那么线条将与 fancy 标题的宽度相同,或者如果使用较小的百分比,比如 80%,那么它将是标题总宽度的那个百分比。
如果标题要获得或添加更多字符,线条将相应调整,这就是 overflow hidden 可能成为隐藏任何超出或位于内容容器之外的额外线条的有趣解决方案的地方,或者在那个时候,最好使用较小的固定像素宽度值。
很棒的例子!
另外,我发现如果你使用 100pts 或点值而不是像素或百分比,可能会比我刚刚发布的解决方案更好。
嘿,Chris,我阅读了文章的顶部部分,并在看到你的解决方案之前决定自己尝试一下。
这就是我想出来的:http://codepen.io/rzea/pen/ecrfL
关于此解决方案的一些说明
1.- 它不使用额外的标记
2.- CSS 比较短
3.- 侧线的宽度不依赖于“容器”,这意味着无论应用于哪个元素,它们的宽度都相同。
4.- 取决于如何实现这样的东西,我可能/可能不会使用“魔法数字”,但嘿,我不得不为此分配值,对吧?哈哈。
请告诉我你的想法。
对我来说看起来不错。只是侧面的线条有点不同的要求,它们是静态宽度,而不是“剩余”宽度(你在演示中说得很清楚)。
我最近不得不做完全相同的事情。首先,我简要搜索了如何做到这一点,但什么也没找到(主要是因为我不知道这种东西的技术名称)。所以我开始思考。最初,我使用了一个包含三个 td 的老式表格,中间一个使用 white-space: nowrap 和 width: 1px。这工作得很好,但后来我想删除表格,并想出了这个解决方案 http://cdpn.io/BcnaE 希望它能有所帮助。
:)
一个很好的方法,可以解决这个看似简单,当然也很棒的设计功能。
设计师享受的轻松与前端人员处理的复杂性之间的差异非常大!
垂直居中伪元素
top: 0;
bottom: 0;
margin: auto;
http://codepen.io/anon/pen/vaGoe
感谢 Chris,我在我的一个项目中使用了类似的东西…;)
感谢 Chris!!!我在我目前正在进行的项目中使用了它。你为我节省了很多时间:) 我使用了 @Денис 的方法来垂直居中伪元素,一切都完美地运行了。
额外的标记(h1 内部的 span 元素)有点糟糕。所以我试图摆脱 span,但与 Ricardo 的解决方案 不同,它使用侧面的线条填充整个宽度。
我进行了一些迭代,这些迭代依赖于背景颜色,即它们不适用于背景图像。例如:
论坛主题(德语,但你会找到指向示例的链接)。
最后,我想出了 这个解决方案。
它仅适用于
<h1>Heading</h1>
标记。基本思想是使用display: table-cell
,就像 Marush 所做的那样,但用于伪元素。糟糕。我发誓我以前没见过 Joshua 的评论。
Fieldset
和<legend>
html 标签是实现此目的的最简单方法,它甚至不是 hack,尽管你必须更改你的标记。简单使用
演示在这里:http://jsfiddle.net/F3UqW/
在 StackOverflow 上找到
是的,但这是一种完全无意义的实现方法。让我们尝试尊重我们都喜欢的标记:)
来自 MDN
更好的实现方法,使用
:before
和:after
。我是那个要求这个解决方案的人,我必须再次感谢你,Chris。如果你有兴趣查看结果,你可以在这里查看
http://malenemailand.dk
我试图实现类似的效果,但只有一个下划线,它从标题末端延伸出来,并填充该行上剩余的可用空间…
但是,我在将“下划线”包含在父容器内方面遇到了问题。
http://codepen.io/ajaykarwal/pen/JbKgt
有什么想法吗?