如何使段落内的最后一个 span 元素不换行?

5
我有一段被装饰引号包围的段落。布局是流式的,对于某些宽度,只有装饰引号换行,我想避免这种情况。
截图:
代码:http://jsfiddle.net/84EDh/1/(注意:未在Chrome之外进行测试)
<p>
    <span class="bigchar ldquo"></span>
    Begin paragraph [...paragraph content...] end paragraph.
    <span class="bigchar rdquo"></span>
</p>

CSS:

p { position: relative; }
.bigchar {
    display: inline-block;
    width: 20px;
}
.bigchar:after {
    color: #aaa;
    font-size: 50px;
    position: absolute;
}
.ldquo:after {
    content: '“';
    top: -10px;
}
.rdquo:after {
    content: '”';
    bottom: -30px;
}

可能的解决方案:
用另一个span将最后一个单词及其结束标签包裹起来。
[...paragraph content...] end 
<span class="nowrap">
    paragraph.
    <span class="bigchar rdquo"></span>
</span>

问题:

有没有更优雅的方法来实现段落中最后一个 span 不换行?

这种方式不太语义化,也不容易实现,因为正如您所期望的那样,段落内容是动态的,因此在模板层面上分割并不容易。

编辑:添加了 CSS。


你能否也发布一下你的CSS代码? - vtamm
你尝试过使用 last-child 吗?p span:last-child { white-space:nowrap; } - CaptainCarl
我尝试将nowrap应用于span,但没有成功:http://jsfiddle.net/84EDh/2/ - Pandaiolo
你为什么不使用 q 元素呢? - Mr Lister
好问题,我确实应该使用q,但我仍然需要覆盖特定于浏览器的:before:after CSS以满足我的需求,这就引导我们到下面Kisiou的答案。 - Pandaiolo
Kisiou的回答仍然有缺陷,最重要的是你试图摆脱的那个。我认为我的更好。 - Mr Lister
5个回答

2

使用q元素比使用span更好,因为q元素就是为此而设计的!

因此,HTML变成了:

<p><q class="bigchar">This text is surrounded by quotes. I want
the text to wrap according it's parent width. This is no problem,
it's the default behaviour. However, I would like to avoid the
last span, containing a decoration quote, to wrap.</q></p>

通过CSS
q.bigchar::before {content:'\201C'; font-size:2em; line-height:0;
position:relative; top:.3em; margin-right:.13em;}

q.bigchar::after {content:'\201D'; font-size:2em; line-height:0;
position:relative; top:.3em; margin-left:.13em;}

导致这个示例的结果。

不需要额外的标记。

请注意,由于我保留了p标记,您可以在其上放置各种样式(如text-indent),它将表现正常。


这是一种更方便的方法,但是否有办法在使用较大字体时避免段落行高的影响?比如在这个代码片段中:http://jsfiddle.net/eShuS/6/。此外,除了语义目的外,使用 q 有技术上的意义吗?它是否比带有伪类的 p 更多功能? - Pandaiolo
嗯,我已经尝试过了,但是我无法解决行高问题。除非将 ::before::after 转换为内联块,但这样又会出现换行问题(即结束引号可能单独出现在一行上)。唯一的替代方案似乎是增加 qline-height。抱歉。 - Mr Lister
哦,q 是一个内联元素,而 p 是块级元素,因此它们的行为方式有几个不同之处。除此之外,纯粹是语义上的区别。 - Mr Lister

1

嵌套span标签会怎样呢?

这样做的效果是让rdquo像普通文本一样(也就是说:如果在rdquo和最后一个单词之间不加空格或者不换行,它不会被分成两行)。

演示在这里: http://jsfiddle.net/HFE9T/1/


看起来工作了,怎么回事?在我的 fiddle 上简单地添加一个包装的 span 就不行!有什么区别吗?我看你也简化了 CSS。 - Pandaiolo
关键概念是外层 span 具有 position: relative,内层具有 position: absolute。因此,您可以轻松地使用 topleft 将内层中的位置相对于外层进行定位,同时外层随文本流动。 - Michał Rybak
尽管存在一些小问题:双重的“span”元素、文本缩进和填充(在我的调试中已修复,请见下方),但我会接受你的答案。感谢你的帮助。 - Pandaiolo

0

你可以在引号前后添加非换行空格\00a0

<style>
  element:before {content: "“\00a0";}
  element:after {content: "\00a0”";}
</style>

如果不想显示那些空间,可以使用负边距解决问题。


0

不要使用额外的span元素,尝试像这样在段落上使用:before和:after:

p:after {
    color: #aaa;
    font-size: 50px;
    position: absolute;
    content: '”';
    bottom: -30px;
}
p:before {
    color: #aaa;
    font-size: 50px;
    position: absolute;
    content: '“';
    top: -10px;
}

更新的 fiddle 在这里


哇,这太棒了!但请注意它无法很好地处理 text-indent,所以唯一缩进文本的方法是在开头放置空的 span,就像你所做的那样。 - Michał Rybak
这很不错,但在仅引用包装时仍存在问题,这是您在fiddle(Chrome)中的屏幕截图:https://www.diigo.com/item/image/4d97a/i3xa 有什么建议可以修复吗? - Pandaiolo
我的最佳尝试:http://jsfiddle.net/84EDh/4/ ... 通过浮动:before元素来修复文本缩进,但是:after元素的blockinline-block属性使其无法粘贴到最后一个单词,除非添加其他标记。 - Pandaiolo

0
这是最终的标记和CSS,以实现期望的行为,灵感来自Michal Rybak,但没有妥协(除了标记中的两个):

HTML:

<p>
    <span class="quote" attr-char="&ldquo;">&nbsp;</span>
    Paragraph content Here. 
    Note the no-line-break here.<span class="quote" attr-char="&rdquo;">&nbsp;</span>
</p>

attr-char 属性非常方便,可以更改不同语言的引号字符,就像 q 元素一样(有点)

CSS:

p .quote { 
    position: relative;
    margin-right: 30px; /* Indent text at paragraph beginning */
}
p .quote:before {
    position: absolute; 
    top: 10px;
    line-height: 20px;
    font-size: 50px;
    content: attr(attr-char); /* Take the character from markup */
}
p .quote:last-child:before {
    margin-left: 10px; /* Give the closing quote some space */
}

Fiddle:

http://jsfiddle.net/HFE9T/4/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接