让EPUB中的点线引导不影响文本换行

前端开发 2026-07-07

我正在把一本旧书转换成 EPUB 格式的电子书。书中有些条目使用点线(dot leader)来对齐。部分条目在点线前的文本相当长。我需要让点线始终把条目的最后一行填满文本(点线应紧贴最后一个单词,并适应电子书阅读器的宽度)。下面有一个示例,说明应当的呈现方式(注意不同的宽度):

Desired behaviour

我想出了下面的代码(长的点线溢出部分会被截断):

.expanded-text {
  letter-spacing: 0.25rem;
  margin-right: -0.25rem;
}

.no-break {
  white-space: nowrap;
}

.toc-item {
  overflow: hidden;
  display: flex;
  align-items: flex-end;
}

.text-container {
  width: 90%;
  min-width: 0;
  overflow: hidden;
}

.text-container p {
  margin: 0;
}

.tag-container {
  width: 10%;
  text-align: left;
}

.page-tag {
  white-space: nowrap;
  margin-left: 0.5rem;
}
<div class="toc-item">
  <div class="text-container">
    <p>
      <span>This is an example of a <span class="no-break">line<span class="expanded-text">....................................................................</span></span></span>
    </p>
  </div>

  <div class="tag-container">
    <span class="page-tag">321</span>
  </div>
</div>

然而,结果并不总看起来自然,因为最后一个单词总是会被挪到新的一行(与第一张图对比):

Current behaviour

从第一张图可以看出(期望的效果),整句话很容易在一行内显示完整。然而,加入一个 no-break <span> 以及点线后,最后一个单词却移到了新的一行。

What I tried and/or why I don't think will be good:

我尝试过的做法以及为何我认为不太可行:

  1. I don't want to use JavaScript, since I think e-book readers will mostly prevent executing scripts.
  2. 我不想使用 JavaScript,因为我认为电子书阅读器大多会阻止执行脚本。

  3. Using a bottom dotted border doesn't look good since it interferes with text (I changed dot colour for better visibility):

  4. 使用底部的虚线边框看起来不太好,因为它会干扰文本(为提高清晰度,我把点的颜色改了):

Bottom dotted border

  1. Applying a background colour to the text part (to hide a dot leader), since most e-book readers apply their own styles, the background colour may be removed.
  2. 给文本部分应用背景色来隐藏点线,因为大多数电子书阅读器会应用自己的样式,背景颜色可能会被移除。

如何阻止最后一个单词被强行挪到新的一行(以实现期望的效果)?

补充示例:
正确的做法:
OK

错误的做法:
Not OK

解决方案

特别感谢 @KIKOSoftware的评论。最终,我终于得到可用的结果。点线的颜色仅用于呈现效果。最后一个(绿色)点被添加,以确保始终至少显示一个点。

Working example

.dl-div {
  text-indent: 0;
  padding: 0;
}
.dl-div p {
  margin: 0;
  display: grid;
  grid-template-columns: auto max-content;
  align-items: end;
}
.dl-div p > .dl-label {
    text-align: left;
  position: relative;
  overflow: hidden;
}
.dl-div p > .dl-value {
  text-align: right;
}
.dl-div p .leaders::after {
  position: absolute;
  letter-spacing: 0.5rem;
  content:
    ". . . . . . . . . . . . . . . . . . . . . . . "
    ". . . . . . . . . . . . . . . . . . . . . . . "
    ". . . . . . . . . . . . . . . . . . . . . . . "
    ". . . . . . . . . . . . . . . . . . . . . . . "
    ". . . . . . . . . . . . . . . . . . . . . . . "
    ". . . . . . . . . . . . . . . . . . . . . . . "
    ". . . . . . . . . . . . . . . . . . . . . . . "
    ". . . . . . . . . . . . . . . . . . . . . . . "
    ". . . . . . . . . . . . . . . . . . . . . . . ";
  text-align: right;
}
.last-dl {
  margin-left:0.5rem;
  margin-right:0.5rem;
}
<div class="dl-div">
  <p>
    <span class="dl-label">This is an example of a very long line with a dot leader working as expected<span class="leaders"></span></span><span class="dl-value"><span class="last-dl">.</span>789</span>
  </p>
</div>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章