七夏 发表于 4 天前

使用CSS给标题添加书名号并超出省略

<p>分享一些 <code>CSS</code>处理文本小技巧。</p>
<p>比如,有一些书名或者标题,默认是没有书名号的,结构如下</p>
<pre><code>&lt;h3class=&quot;books&quot;&gt;灵境行者&lt;/h3&gt;
&lt;h3class=&quot;books&quot;&gt;斗破苍穹&lt;/h3&gt;
&lt;h3class=&quot;books&quot;&gt;我师兄实在太稳健了&lt;/h3&gt;
...
</code></pre>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rErw4XccJP3IeUFa7KypBia1c1OERfq3vld77B7Niczia1ljxqKhWtiaZFQ/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214145251509" /></p>
<p>有没有什么办法在不改变 <code>HTML</code>的情况下加上书名号呢?🤔(例如某些情况下 <code>HTML</code>由其他框架生成,无法直接改底层源码)</p>
<p>进一步,还需要书名号内部实现文本超出省略,如下</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rrKh9FibFpWjmdPc1LdibdGySqLViaf75bn2ojQm6vcmWx6w1RXzJzibjkg/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214163417873" /></p>
<p>这就需要 <code>CSS</code>动态生成技术了,你有什么想法呢?一起看看吧</p>
<h2>一、使用伪元素生成书名号</h2>
<p>没错,很多同学可能会想到用伪元素,前后各添加一个就好了</p>
<pre><code>.books::before{
content:'《'
}
.books::after{
content:'》'
}
</code></pre>
<p>效果如下</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rqj2IFT0n6e0AmTHVyEkpfY5BziabrGQDAYUGHRwfEM3gCEvlgicKPpMA/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214145343235" /></p>
<p>除了手动使用伪元素生成伪元素外,还可以用 <code>CSS quotes</code> 来生成书名号</p>
<pre><code>.books{
quotes:&quot;《&quot;&quot;》&quot;
}
</code></pre>
<p>但是,普通元素直接写这个没什么效果,只有 <code>q</code>标签才会显示书名号</p>
<pre><code>&lt;qclass=&quot;books&quot;&gt;灵境行者&lt;/q&gt;
&lt;h3class=&quot;books&quot;&gt;斗破苍穹&lt;/h3&gt;
&lt;h3class=&quot;books&quot;&gt;我师兄实在太稳健了&lt;/h3&gt;
...
</code></pre>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1ralhRFD73K8uvSicH5XjSapOZgorxj5zZlM2mZicQhsYDicKkm9jDUZBmA/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214160912725" /></p>
<p>原因是,<code>q</code>标签会自带默认样式,自动创建了伪元素</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rV75CdCJTBWQ6F5TEZwSql2T48JTxAY6nia2ibQtQXHAnKrKz6zbwx8RQ/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214161032037" /></p>
<p>所以,普通元素如果也想用 <code>quotes</code>属性,可以手动添加</p>
<pre><code>.books::before{
content: open-quote
}
.books::after{
content: close-quote
}
</code></pre>
<p>效果如下</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rqj2IFT0n6e0AmTHVyEkpfY5BziabrGQDAYUGHRwfEM3gCEvlgicKPpMA/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214145343235" /></p>
<p>不过这样好像还不如直接使用伪元素方便了吧?😂</p>
<h2>二、书名号内文本超出省略</h2>
<p><code>CSS</code> 单行文本超出省略很容易,只需要下面 3 行</p>
<pre><code>white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
</code></pre>
<p>当宽度比较小时,部分标题也发生了省略,如下</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rxITltwickccwv9c18IBdJ2TFmfq6Rku6GumQVLrDP4SrmdX8EuDUTQQ/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214161711117" /></p>
<p>有设计师表示,这样不是很好看🙅🏻‍♀️,这个省略号能否在书名号里面呢,就像这样</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rrKh9FibFpWjmdPc1LdibdGySqLViaf75bn2ojQm6vcmWx6w1RXzJzibjkg/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214163417873" /></p>
<p>正常情况下,我们会选择给中间的文本额外新增一层标签,然后把文字省略设置在这个标签上</p>
<pre><code>&lt;qclass=&quot;books&quot;&gt;&lt;span&gt;灵境行者&lt;/span&gt;&lt;/q&gt;
&lt;h3class=&quot;books&quot;&gt;&lt;span&gt;斗破苍穹&lt;/span&gt;&lt;/h3&gt;
&lt;h3class=&quot;books&quot;&gt;&lt;span&gt;我师兄实在太稳健了&lt;/span&gt;&lt;/h3&gt;
...
</code></pre>
<p>但是如果无法更改 <code>HTML</code>结构,这里有办法只用一层标签实现吗?</p>
<p>当然也是有的,下面介绍两个思路</p>
<h2>三、好用的绝对定位</h2>
<p>书名号之所以会连同文本一起被省略,在于和标题文本处于同一文本流中,所以需要将这个书名号提取出来,脱离这个文本流。</p>
<p>首先可以想到的是绝对定位,需要注意给右侧留一点内边距(不然就重叠了),这里给**「一个字号宽度」**</p>
<pre><code>.books{
position: relative;
padding-right:1em;/*只能大概给一个固定距离*/
}
.books::after{
position: absolute;
right:0;
}
</code></pre>
<p>效果如下</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rZ5QibVicU1x7k4PawuIOWkNJRDg5ZQTrDvAGA68MccVmF9AeiaAhFhddw/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214170705918" /></p>
<p>由于是块级元素,宽度默认撑满,所以书名号跑到最右边了,可以给元素加一个最大宽度为文本宽度</p>
<pre><code>.books{
/**/
max-width: fit-content;
}
</code></pre>
<p>这样就正常了</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rvkgngp5IjQ2qFQibTX1v1hbUaNJtYHtFRJlpibrMwncicCmsW0JVQqCtA/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214170952755" /></p>
<p>完整代码可以查看:https://codepen.io/xboxyan/pen/emOBeGa</p>
<h2>四、有些冷门的浮动</h2>
<p>除了前面的绝对定位,浮动也能实现类似的效果。</p>
<pre><code>.books::after{
float: right
}
</code></pre>
<p>效果如下</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1ria7x5SZJUMM33pjDCXRhBVtuFbmjeMhkOyIvp8DMGeMVpnuI3wF2D8g/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214172159041" /></p>
<p>但是当文本过长时,浮动元素掉下来了,并没有实现环绕效果。</p>
<p>其实,这个跟文档的顺序有关,浮动元素必须位于前面才行,也就是 <code>::before</code>元素才可以,我们试试</p>
<pre><code>.books::before{
float: right
}
</code></pre>
<p>效果如下,很好的位于最右侧(红色部分)</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rbibovWAsgs7xf97CXCdgicsAS8nTQ6cPUicFpxB15QJox2KaZn6UcEhVQ/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214173136789" /></p>
<p>那么现在问题来了,<code>::before</code>被用掉了,用于生成右书名号,那通过什么来生成左书名号呢?</p>
<p>思索了一番,整个 <code>CSS</code>中还有一个伪元素可以生成文本,那就是 <code>::marker</code>,而且也位于左侧。不过需要设置 <code>display</code>属性为 <code>list-item</code>才会出现</p>
<pre><code>.books{
/**/
display: list-item;
list-style-position: inside;
}
.books::marker{
content:'《';
}
.books::before{
content:&quot;》&quot;;
float: right;
color:red;
}
</code></pre>
<p>这样就能代替原本的 <code>::before</code>生成左书名号了(左侧是 <code>::marker</code>,右侧是 <code>::before</code>)</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1r43rcMCxsIiaroUrBibAicgyJLxhrQIZibN8XtI3ic2K2cTupk0l0KxINsew/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214173608753" /></p>
<p>同样还有最大宽度的问题</p>
<pre><code>.books{
/**/
max-width: fit-content;
}
</code></pre>
<p>同样能实现类似的效果,相比绝对定位来说,无需给一个“大概”的右内边距</p>
<p><img src="https://www.3bbs.cn/index-diy/img.php?url=https://mmbiz.qpic.cn/mmbiz_png/xvBbEKrVNtIHfrknePlmSoicmajibN2n1rvkgngp5IjQ2qFQibTX1v1hbUaNJtYHtFRJlpibrMwncicCmsW0JVQqCtA/640?wx_fmt=png&amp;from=appmsg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" alt="image-20241214170952755" /></p>
<p>完整代码可以查看:https://codepen.io/xboxyan/pen/ZYzBajg</p>
<h2>五、总结一下</h2>
<p>以上就是本文的全部技巧了,你学到了?下面总结一下</p>
<ol>
<li>某些情况下 <code>HTML</code>由其他框架生成,无法直接改底层源码,这就需要使用 <code>CSS</code>动态生成技术了</li>
<li>使用两个伪元素可以很轻松生成前后两个书名号</li>
<li>还可以用 <code>CSS quotes</code> 来生成书名号,不过只针对 <code>q</code>元素生效</li>
<li>默认情况下,文本省略会把右侧的书名号也省略</li>
<li>书名号之所以会连同文本一起被省略,在于和标题文本处于同一文本流中,需要把右侧书名号脱离文本流。</li>
<li>绝对定位居右定位可以脱离文本流,不过需要预留一点空间,不然会和下面的文本重叠</li>
<li>块级元素宽度默认撑满,可以设置宽度为 <code>fit-content</code>自适应文字宽度</li>
<li>浮动布局也可以脱离文本流,不过要求浮动元素在 <code>HTML</code>结构中的左侧,<code>::after</code>元素在文本右侧,无法使用浮动实现该效果</li>
<li>除了伪元素,还可以通过 <code>::marker</code>来生成内容,而且也位于文本左侧</li>
<li>使用 <code>::marker</code>生成左侧书名号,<code>::brfore</code>生成右侧书名号,相比绝对定位的优势是,无需给定一个&quot;大概&quot;的右内边距</li>
</ol>
<p>希望能对你的工作带来帮助和不一样的思考,最后,如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发 ❤❤❤</p>
页: [1]
查看完整版本: 使用CSS给标题添加书名号并超出省略