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

欢迎关注我的公众号:前端侦探

分享一些CSS处理文本小技巧。

比如,有一些书名或者标题,默认是没有书名号的,结构如下

html 复制代码
<h3 class="books">灵境行者</h3>
<h3 class="books">斗破苍穹</h3>
<h3 class="books">我师兄实在太稳健了</h3>
...

有没有什么办法在不改变HTML的情况下加上书名号呢?🤔(例如某些情况下HTML由其他框架生成,无法直接改底层源码)

进一步,还需要书名号内部实现文本超出省略,如下

这就需要CSS动态生成技术了,你有什么想法呢?一起看看吧

一、使用伪元素生成书名号

没错,很多同学可能会想到用伪元素,前后各添加一个就好了

css 复制代码
.books::before{
  content: '《'
}
.books::after{
  content: '》'
}

效果如下

除了手动使用伪元素生成伪元素外,还可以用 CSS quotes 来生成书名号

css 复制代码
.books{
  quotes: "《" "》"
}

但是,普通元素直接写这个没什么效果,只有q标签才会显示书名号

html 复制代码
<q class="books">灵境行者</q>
<h3 class="books">斗破苍穹</h3>
<h3 class="books">我师兄实在太稳健了</h3>
...

原因是,q标签会自带默认样式,自动创建了伪元素

所以,普通元素如果也想用quotes属性,可以手动添加

css 复制代码
.books::before{
  content: open-quote
}
.books::after{
  content: close-quote
}

效果如下

不过这样好像还不如直接使用伪元素方便了吧?😂

二、书名号内文本超出省略

CSS 单行文本超出省略很容易,只需要下面 3 行

css 复制代码
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

当宽度比较小时,部分标题也发生了省略,如下

有设计师表示,这样不是很好看🙅🏻‍♀️,这个省略号能否在书名号里面呢,就像这样

正常情况下,我们会选择给中间的文本额外新增一层标签,然后把文字省略设置在这个标签上

html 复制代码
<q class="books"><span>灵境行者</span></q>
<h3 class="books"><span>斗破苍穹</span></h3>
<h3 class="books"><span>我师兄实在太稳健了</span></h3>
...

但是如果无法更改HTML结构,这里有办法只用一层标签实现吗?

当然也是有的,下面介绍两个思路

三、好用的绝对定位

书名号之所以会连同文本一起被省略,在于和标题文本处于同一文本流中,所以需要将这个书名号提取出来,脱离这个文本流。

首先可以想到的是绝对定位,需要注意给右侧留一点内边距(不然就重叠了),这里给一个字号宽度

css 复制代码
.books{
  position: relative;
  padding-right: 1em;/*只能大概给一个固定距离*/
}
.books::after{
  position: absolute;
  right: 0;
}

效果如下

由于是块级元素,宽度默认撑满,所以书名号跑到最右边了,可以给元素加一个最大宽度为文本宽度

css 复制代码
.books{
  /**/
  max-width: fit-content;
}

这样就正常了

完整代码可以查看:codepen.io/xboxyan/pen...

四、有些冷门的浮动

除了前面的绝对定位,浮动也能实现类似的效果。

css 复制代码
.books::after{
  float: right
}

效果如下

但是当文本过长时,浮动元素掉下来了,并没有实现环绕效果。

其实,这个跟文档的顺序有关,浮动元素必须位于前面才行,也就是::before元素才可以,我们试试

css 复制代码
.books::before{
  float: right
}

效果如下,很好的位于最右侧(红色部分)

那么现在问题来了,::before被用掉了,用于生成右书名号,那通过什么来生成左书名号呢?

思索了一番,整个CSS中还有一个伪元素可以生成文本,那就是::marker,而且也位于左侧。不过需要设置display属性为list-item才会出现

css 复制代码
.books{
  /**/
  display: list-item;
  list-style-position: inside;
}
.books::marker{
  content: '《';
}
.books::before{
  content: "》";
  float: right;
  color: red;
}

这样就能代替原本的::before生成左书名号了(左侧是::marker,右侧是::before

同样还有最大宽度的问题

css 复制代码
.books{
  /**/
  max-width: fit-content;
}

同样能实现类似的效果,相比绝对定位来说,无需给一个"大概"的右内边距

完整代码可以查看:codepen.io/xboxyan/pen...

五、总结一下

以上就是本文的全部技巧了,你学到了?下面总结一下

  1. 某些情况下HTML由其他框架生成,无法直接改底层源码,这就需要使用CSS动态生成技术了
  2. 使用两个伪元素可以很轻松生成前后两个书名号
  3. 还可以用 CSS quotes 来生成书名号,不过只针对q元素生效
  4. 默认情况下,文本省略会把右侧的书名号也省略
  5. 书名号之所以会连同文本一起被省略,在于和标题文本处于同一文本流中,需要把右侧书名号脱离文本流。
  6. 绝对定位居右定位可以脱离文本流,不过需要预留一点空间,不然会和下面的文本重叠
  7. 块级元素宽度默认撑满,可以设置宽度为fit-content自适应文字宽度
  8. 浮动布局也可以脱离文本流,不过要求浮动元素在HTML结构中的左侧,::after元素在文本右侧,无法使用浮动实现该效果
  9. 除了伪元素,还可以通过::marker来生成内容,而且也位于文本左侧
  10. 使用::marker生成左侧书名号,::brfore生成右侧书名号,相比绝对定位的优势是,无需给定一个"大概"的右内边距

希望能对你的工作带来帮助和不一样的思考,最后,如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发 ❤❤❤

欢迎关注我的公众号:前端侦探

相关推荐
iOS阿玮2 分钟前
待业的两个月,让我觉得独立开发者才是职场的归宿。
前端·app
八了个戒10 分钟前
「数据可视化 D3系列」入门第六章:比例尺的使用
前端·javascript·信息可视化·数据可视化·canvas
少糖研究所18 分钟前
ACPA算法详解
前端
Mores29 分钟前
开源 | ImageMinify:轻量级智能图片压缩工具,为你的项目瘦身加速
前端
执梦起航31 分钟前
webpack理解与使用
前端·webpack·node.js
ai大师31 分钟前
Cursor怎么使用,3分钟上手Cursor:比ChatGPT更懂需求,用聊天的方式写代码,GPT4、Claude 3.5等先进LLM辅助编程
前端
Json_34 分钟前
使用vue2技术写了一个纯前端的静态网站商城-鲜花销售商城
前端·vue.js·html
1024熙34 分钟前
【Qt】——理解信号与槽,学会使用connect
前端·数据库·c++·qt5
少糖研究所35 分钟前
ColorThief库是如何实现图片取色的?
前端
冴羽36 分钟前
SvelteKit 最新中文文档教程(22)—— 最佳实践之无障碍与 SEO
前端·javascript·svelte