Nested line-through in css

427 views Asked by At

In my scenario, I have sections of text with deleted sections, visualized by line-through. Sometimes, these sections are nested. I would like to produce an output like this (please run snippet):

span.strike1 {
  text-decoration:line-through;
  text-decoration-style:solid;
}

span.strike2 {
  text-decoration:line-through;
  text-decoration-style:double;
}
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. <span class="strike1">Aenean commodo ligula
eget dolor. </span><span class="strike2">Aenean massa.
Cum sociis natoque penatibus et magnis dis parturient
montes, nascetur ridiculus mus. Donec quam felis,
ultricies nec, pellentesque eu, pretium quis,
sem.</span><span class="strike1"> Nulla consequat
massa quis enim.</span> Donec pede justo, fringilla
vel, aliquet nec, vulputate eget, arcu.</p>

However, I would like to reproduce the same result with nested elements. Without applying javascript, is this actually achievable? Nesting text-decoration-style:double into text-decoration-style:solid will produce a triple line (double + solid), see here:

span.strike {
  text-decoration:line-through;
  text-decoration-style:solid;
}

span.strike span.strike {
  text-decoration:line-through;
  text-decoration-style:double;
}
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. <span class="strike">Aenean commodo ligula eget
dolor. <span class="strike">Aenean massa. Cum sociis
natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus. Donec quam felis, ultricies
nec, pellentesque eu, pretium quis, sem.</span> Nulla
consequat massa quis enim.</span> Donec pede justo,
fringilla vel, aliquet nec, vulputate eget, arcu.</p>

Further, it seems impossible to influence the position of text-decoration. I have also tried a workaround with border and :after, but this does not work with more than one line. I appreciate any help.

3

There are 3 answers

3
G-Cyrillus On BEST ANSWER

You could use a background linear-gradient painted via currentcolor to match text color instead text-decoration:

p {
line-height:1.6em;
font-size:16px;
}
span.strike {background:linear-gradient(
to top, 
transparent 35%, 
currentcolor 35%, 
currentcolor calc(35% + 1px ) , 
transparent calc(35% + 1px ) 
);
}

span.strike span.strike {
background:linear-gradient(
to top, 
transparent 5px, 
currentcolor 5px, 
currentcolor 6px , 
white 6px, /* hide other bg */
white 9px,  /* hide other bg */
currentcolor 9px, 
currentcolor  10px, 
transparent 10px
);
}
/* why currentcolor ? , hover tripleed striked span */
span span:hover {
color:purple;
}
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. <span class="strike">Aenean commodo ligula eget
dolor. <span class="strike">Aenean massa. Cum sociis
natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus. Donec quam felis, ultricies
nec, pellentesque eu, pretium quis, sem.</span> Nulla
consequat massa quis enim.</span> Donec pede justo,
fringilla vel, aliquet nec, vulputate eget, arcu.</p>

@BoltClock says : This works provided the background is a solid color and you don't mind the less-than-precise "lines" ;)

1
BoltClock On

Unfortunately, it is not possible to prevent decorations from being drawn over descendant inline boxes (see CSS2.2 and css-text-decor-3). Your only recourse, if you don't want to (or can't) cheat by drawing fake decorations yourself, is splitting your outer .strike element at the boundaries of the inner .strike element in such a way as to produce a structure similar to your reference example.

0
friedemann_bach On

I have found another solution that works well in my case. I post it here as it might be of interest for others. While the background-gradient solution displayed excellently in browsers, it did not work well when printing the document. This solution separates the second strikethrough line from its text by surrounding it by another <span> element, which is moved a little upwards by scaling the font size. The font size is then reset in the nested span element to display the text correctly.

p {
  line-height:1.5em;
}

span.strike {
  text-decoration:line-through;
  text-decoration-style:solid;
}

span.strikeLine {
  text-decoration:line-through;
  text-decoration-style:solid;
  font-size:1.43em;
  line-height:0;
}

span.strikeText {
  font-size:0.7em;
  line-height:1.5em;
}
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing
elit. <span class="strike">Aenean commodo ligula eget
dolor. <span class="strikeLine"><span class="strikeText">Aenean massa. Cum sociis
natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus. Donec quam felis, ultricies
nec, pellentesque eu, pretium quis, sem.</span></span> Nulla
consequat massa quis enim.</span> Donec pede justo,
fringilla vel, aliquet nec, vulputate eget, arcu.</p>