有没有办法使用 CSS 以 wedge/triangle 装饰行尾?

Is there a way to decorate line ends with a wedge/triangle using CSS?

我正在为使用 wkhtmltopdf 转换为 pdf 的发票制作 HTML/CSS 模板。设计的一部分是如下所示的元素:

元素内的文本可以是可变长度的。该元素背后的逻辑非常简单:只要出现换行符,就用楔形装饰行尾。我使用 css-tricks.com 中的 Matthew Pennell's Triple Element Method 向每一行添加了填充。我已经根据需要进行了调整:

.padded-multiline {
    line-height: 1.4;
    padding: 0.005in 0;
    border-left: 0.16in solid #E7E7E9;
}
.padded-multiline p {
    background-color: #E7E7E9;
    padding: 0.02in 0;
    display: inline;
    margin: 0;
}
.padded-multiline p span {
    position: relative;
    left: -0.08in;
}

问题是我不知道如何用楔子装饰线条。我想要一个 CSS 解决方案,但我不确定这是否真的可以实现。如果文本是单行,我可以很容易地在元素后添加一个灰色 CSS 三角形。或者我可以添加一个背景图像,该图像由白色背景上的三角形组成,可以达到相同的效果。但是由于元素是多行的,所以我 运行 没有想法。

在嵌套元素上使用 background-repeat: repeat-y 似乎并不像我期望的那样工作,因为它只将背景添加到它的最后一行。 我知道有一个 ::first-line 伪选择器,但据我所知,没有 ::nth-line 或其他相同类型的量词。

目前我认为唯一可行的解​​决方案可能是使用 JavaScript 将文本分解为单个元素并将它们视为多个单行元素而不是多行元素。但我想避免使用 JavaScript,因为这会增加 PDF 生成的开销,而且我觉得有点 hacky

有什么想法吗?

注:

wkhtmltopdf and wkhtmltoimage are open source (LGPLv3) command line tools to render HTML into PDF and various image formats using the Qt WebKit rendering engine.

如果我们考虑到您不会手动插入换行符这一事实,那么只有最后一行不会被填充到最后,而之前的所有内容都会被填充。然后我们可以单独考虑最后一条边,同时考虑其他边。

这是一个想法:

p {
 line-height:20px;
 padding:0 30px;
 background:
  linear-gradient(to top left,#fff 49%,transparent 50%) top right/20px 20px repeat-y,
  grey;
  overflow:hidden;
}
span {
  position:relative;
  display:inline-block;
  vertical-align:bottom;
}
span:before {
  content:"";
  position:absolute;
  left:30px; /*equal to padding*/
  bottom:0px;
  height:20px; /*equal to line-height*/
  background:
    linear-gradient(to top left,#fff 49%,grey 50%) top left/20px 20px no-repeat,
    #fff;
  right:-100vw;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tellus ipsum, posuere a tincidunt non, consectetur et mi. Sed congue ornare lorem, et placerat velit tempus nec. Phasellus fringilla eleifend vestibulum. Nunc lobortis ipsum a nisi dignissim sollicitudin. Ut elit leo, ultrices mollis metus non,<span></span> </p>

如果您需要一些换行符,请不要使用 <br>,而是使用许多 p 标签:

p {
 line-height:20px;
 padding:0 30px;
 background:
  linear-gradient(to top left,#fff 49%,transparent 50%) top right/20px 20px repeat-y,
  grey;
  overflow:hidden;
  margin:0;
}
span {
  position:relative;
  display:inline-block;
  vertical-align:bottom;
}
span:before {
  content:"";
  position:absolute;
  left:30px; /*equal to padding*/
  bottom:0px;
  height:20px; /*equal to line-height*/
  background:
    linear-gradient(to top left,#fff 49%,grey 50%) top left/20px 20px no-repeat,
    #fff;
  right:-100vw;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tellus ipsum, posuere a tincidunt non,  Ut elit leo, ultrices mollis metus non,<span></span> </p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tellus ipsum, posuere a tincidunt non, consectetur et mi. Sed congue ornare lorem, et placerat velit tempus nec. Ut elit leo, ultrices mollis metus non,<span></span> </p>

更新

您可以使用简单图像或 SVG 代替渐变:

p {
  line-height: 20px;
  padding: 0 30px;
  background: url('data:image/svg+xml;utf8,<svg viewBox="0 0 20 20" width="20" height="20" xmlns="http://www.w3.org/2000/svg"><polygon points="20 20,0 20, 20 0" fill="white" /></svg>') top right/20px 20px repeat-y;
  background-color: grey;
  overflow: hidden;
  margin: 0;
}

span {
  position: relative;
  display: inline-block;
  vertical-align: bottom;
}

span:before {
  content: "";
  position: absolute;
  left: 30px; /*equal to padding*/
  bottom: 0px;
  height: 20px; /*equal to line-height*/
  background: url('data:image/svg+xml;utf8,<svg viewBox="0 0 20 20" width="20" height="20" xmlns="http://www.w3.org/2000/svg"><polygon points="0 0,0 20, 20 0" fill="grey" /></svg>') top left/20px 20px no-repeat;
  background-color: #fff;
  right: -100vw;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tellus ipsum, posuere a tincidunt non, Ut elit leo, ultrices mollis metus non,<span></span> </p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tellus ipsum, posuere a tincidunt non, consectetur et mi. Sed congue ornare lorem, et placerat velit tempus nec. Ut elit leo, ultrices mollis metus non,<span></span> </p>