Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining gradient text with strikethrough / line-through in Chrome

Tags:

html

css

I've got a gradient text in CSS that I also want to be able to have a strikethrough span within. This works fine in Firefox, but sadly does not in Chrome. Anyone got an idea on how to get this to work in both browsers?

FIDDLE

.gradienttext {
    background: -webkit-linear-gradient(#fff, #999);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

.strike {
    text-decoration: line-through;
}

<p class="gradienttext">
    Does <span="strike">not</span> work.
</p>
like image 582
jsmars Avatar asked Jan 27 '17 09:01

jsmars


1 Answers

I was very surprised that the code in question worked with the -webkit- specific props and gradient syntax but just now learnt that Firefox had shipped compatibility with these -webkit- specific props.

A now-deleted answer seems to have come close to explaining why it doesn't work in Chrome but not close enough and since it is now deleted (I don't know why), I will add a more complete explanation.


Findings:

As per MDN, the -webkit-text-fill-color is defined as follows:

The -webkit-text-fill-color CSS property specifies the fill color of characters of text. If this property is not set, the value of the color property is used.

and as per the W3C Specs for text-decoration property the line through's color is specified as follows:

The color(s) required for the text decoration should be derived from the 'color' property value.

It seems like Chrome probably considers the text to be transparent and so applies transparent color to the line through also. Thus we don't get to see any line. But this is not correct because as per specs it should use the value belonging to the color property.

Chrome sets the color correctly (for the snippet in question the color is black but even changing it to another color doesn't work) but doesn't apply it correctly to the line through. For example, in the below snippet the color of the element is green (is inherited from body) and by inspecting the element with Dev console we can see that the color is set correctly but there is no line through.

body {
  background: black;
  color: green;
}
.gradienttext {
  background: -webkit-linear-gradient(#fff, #999);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
.strike {
  text-decoration: line-through;
}
<p class="gradienttext">
  The following dummy text should both be a long vertical gradient, and also be strikethrough, which works fine on firefox, but not chrome. <span class='strike'> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</span>
</p>

If we apply some color to the -webkit-text-fill-color property, Chrome applies that same color to the line through also. This sort of seems to confirm that it is setting the line color as transparent for the code in question. But this is not a viable solution for your case as you need the gradient text.

body {
  background: black;
  color: green;
}
.gradienttext {
  background: -webkit-linear-gradient(#fff, #999);
  -webkit-background-clip: text;
  -webkit-text-fill-color: red;
}
.strike {
  text-decoration: line-through;
}
<p class="gradienttext">
  The following dummy text should both be a long vertical gradient, and also be strikethrough, which works fine on firefox, but not chrome. <span class='strike'> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</span>
</p>

When we set some color to the -webkit-text-stroke-color property, Chrome again uses this same color for the line through but it seems to work only when we give -webkit-text-stroke-width a non zero value and that again creates an undesirable output.

body {
  background: black;
  color: green;
}
.gradienttext {
  background: -webkit-linear-gradient(#fff, #999);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
.strike {
  text-decoration: line-through;
  -webkit-text-stroke-color: red;
  -webkit-text-stroke-width: 1px;
}
<p class="gradienttext">
  The following dummy text should both be a long vertical gradient, and also be strikethrough, which works fine on firefox, but not chrome. <span class='strike'> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</span>
</p>

Even setting a color explicitly to span.strike has no effect whatsoever.


Workaround:

As a workaround you could use gradient background images to mimic the strike through effect like in the below snippets.

It uses a gradient background image which is 1em tall and is not transparent just for 1px when going from bottom to top. This creates an illusion of a strike through or line through (so, it is probably not good from the perspective of screen readers etc.)

With the Webkit Gradient Syntax:

body {
  background: black;
}
.gradienttext {
  background: -webkit-linear-gradient(#fff, #999);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
.strike {
  background: -webkit-linear-gradient(bottom, transparent calc(.5em - 1px), red calc(.5em - 1px), red .5em, transparent .5em);
  background-size: 100% 1em;
}
<p class="gradienttext">
  The following dummy text should both be a long vertical gradient, and also be strikethrough, which works fine on firefox, but not chrome. <span class="strike"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</span>
</p>

With Standard Gradient Syntax:

body {
  background: black;
}
.gradienttext {
  background: linear-gradient(#fff, #999);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
.strike {
  background: linear-gradient(to top, transparent calc(.5em - 1px), red calc(.5em - 1px), red .5em, transparent .5em);
  background-size: 100% 1em;
}
<p class="gradienttext">
  The following dummy text should both be a long vertical gradient, and also be strikethrough, which works fine on firefox, but not chrome. <span class="strike"> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</span>
</p>
like image 166
Harry Avatar answered Oct 01 '22 23:10

Harry