0

This is what I have so far... it works but text is not selectable on Firefox (works on Safari).

I am very open to discovering a more efficient way of achieving this (if possible) given using background-clip and -webkit-text-fill-color is a bit of a hack.

body {
  font-family: Arial, Helvetica, sans-serif;
}
a {
  position: relative;
  color: #fbd6cd;
  background-clip: text;
  -webkit-background-clip: text;
  -moz-background-clip: text;
  -webkit-text-fill-color: transparent;
  -moz-text-fill-color: transparent;
  background-image: linear-gradient(
    -45deg,
    #fbd6cd,
    #fdc0ee
  );
}
a:after {
  position: absolute;
  top: 0px;
  left: 0px;
  background-clip: text;
  -webkit-background-clip: text;
  -moz-background-clip: text;
  -webkit-text-fill-color: transparent;
  -moz-text-fill-color: transparent;
  content: "This is a test";
  background-image: linear-gradient(
    -45deg,
    #f7af9e,
    #fb8fe1
  );
  opacity: 0;
  transition: opacity 0.3s;
}
a:hover:after {
  opacity: 1;
}
<!DOCTYPE html>
<html lang="en">
  <body>
    <h1><a>This is a test</a></h1>
  </body>
</html>
t-jam
  • 811
  • 1
  • 6
  • 21
sunknudsen
  • 6,356
  • 3
  • 39
  • 76
  • no .................. – Temani Afif Dec 17 '20 at 00:34
  • @TemaniAfif I am trying to add a transition to darken gradient overlay text... using `:after`. Text is selectable in Safari but not in Firefox... I guess because the "real" text is under identical styled `:after` text. Do you have ideas on how to make that text selectable in Firefox? – sunknudsen Dec 17 '20 at 00:37
  • better adjust your question to show your real use case instead of having a generic question where the answer is clearly no. I am pretty sure there is a solution for your case. – Temani Afif Dec 17 '20 at 00:39
  • I was hoping the answer wasn't clearly no... but I would be happy to either create a new question or edit this one. What do you suggest? – sunknudsen Dec 17 '20 at 00:41
  • edit this one ... – Temani Afif Dec 17 '20 at 00:41
  • @TemaniAfif Done – sunknudsen Dec 17 '20 at 00:59
  • 1
    a trivial solution is to add `pointer-events: none;` to the ::after element – Temani Afif Dec 17 '20 at 01:06
  • also I don't understand the use of the pseudo element here, why not applying the opacity on the element and you are done. why duplicating the text? https://jsfiddle.net/yn0jtcb8/ – Temani Afif Dec 17 '20 at 01:08
  • @TemaniAfif Interesting! Looks like `pointer-events: none;` when hovered is handled differently on Firefox vs Safari. – sunknudsen Dec 17 '20 at 01:09
  • @TemaniAfif I believe the text is semi transparent (`opacity: 0.5;`) in the jsfiddle... in the above example, colors are solid. Perhaps I am missing something. – sunknudsen Dec 17 '20 at 01:13
  • @TemaniAfif Btw `pointer-events: none;` is brilliant. Thanks for sharing that tip. – sunknudsen Dec 17 '20 at 01:17
  • it's semi transparent but the visual result is almost the same (if not exactly the same) – Temani Afif Dec 17 '20 at 01:21
  • you deleted your question very fast, here is what you are looking for: https://stackoverflow.com/questions/42966641/how-to-transform-black-into-any-given-color-using-only-css-filters/43960991 – Temani Afif Dec 17 '20 at 10:02
  • Thanks @TemaniAfif. I had stumbled upon that answer... but it converts black to any color vs a given color to another. Do you believe this would work for my use case? Trying to make sense of the answer. – sunknudsen Dec 17 '20 at 10:16
  • 1
    If you want to have a lot of headaches dealing with complex formula then you can. Honestly I don't think it worth all this effort, your initial solution is already doing the job with opacity. – Temani Afif Dec 17 '20 at 10:18
  • @TemaniAfif Good advice... that rabbit hole is slippery though. – sunknudsen Dec 17 '20 at 10:20

1 Answers1

1

No need to create a pseudo element if you're wanting to animate the gradient, especially if you want the original state to be quite similar. Just use filters and transition those instead, then the text remains selectable.

For example:

body {
  font-family: Arial, Helvetica, sans-serif;
}
a {
  position: relative;
  color: #fbd6cd;
  background-clip: text;
  -webkit-background-clip: text;
  -moz-background-clip: text;
  -webkit-text-fill-color: transparent;
  -moz-text-fill-color: transparent;
  background-image: linear-gradient(
    -45deg,
    #f7af9e,
    #fb8fe1
  );
  filter: brightness(1.25) saturate(0.9);
  transition: filter 0.5s ease;
}
a:hover {
  filter: brightness(1) saturate(1);
}
<!DOCTYPE html>
<html lang="en">
  <body>
    <h1><a>This is a test</a></h1>
  </body>
</html>

Edit: you can also just transition opacity, but this approach keeps the text opaque, which allows you to control the text colours better if they're not always going to be on a white background.

t-jam
  • 811
  • 1
  • 6
  • 21
  • Interesting, thanks! Is there a way to find the right `brightness` and `saturate` values to convert `#fbd6cd` to `#f7af9e`? – sunknudsen Dec 17 '20 at 01:30
  • This is fine if you [don't care about IE](https://caniuse.com/css-filters), but you shouldn't. Finding the exact brightness / saturate values will probably take some eyeballing. Maybe some wizard has created a tool for it, but I haven't dug around. – t-jam Dec 17 '20 at 01:32
  • Would you happen to know how to add `text-decoration: underline;`? Somehow when I add this property, the underline is not visible when using gradient overlays. – sunknudsen Dec 17 '20 at 02:20
  • I'm assuming you could use an absolutely positioned pseudo element for an underline with the same background-gradient - the filter transition should apply to that also. That method just runs into issues if your links break across multiple lines. Alternatively if you're happy with a plain-colour underline, use the `text-decoration-color` CSS property to set the colour and it will appear. – t-jam Dec 17 '20 at 03:01
  • Thanks! So there is no way to have the gradient overlay apply to the underline right? – sunknudsen Dec 17 '20 at 09:56
  • 1
    If you don't expect these links to ever run over multiple lines (or don't care about how that looks), the pseudo-element underline approach is workable? https://jsfiddle.net/fzn7xwp9/ – t-jam Dec 18 '20 at 02:04
  • Thanks for your help! The only part missing to this answer is a predictable workflow to convert one hex color to another using filters. This [answer](https://stackoverflow.com/a/43960991/4579271) is interesting in this regard. – sunknudsen Dec 22 '20 at 10:39
  • No worries. I thought perhaps converting to HSB and checking the differences between the HSB values of two desired hex colours would be an option (since you can use CSS `filter` to adjust HSB values), but the results from a 2 minute test aren't what I'd expect. You may have more luck with some more time... – t-jam Dec 23 '20 at 01:27