With CSS is it possible to animate text-decoration?

I recently saw this animation made with SVG,

insert the description of the image here

But I was wondering, Is it possible to animate text-decoration-style: wavy in :hover in order to achieve the same result?

   body {
        font-family: sans-serif;
        font-size: 2rem;
    }
    p {
        font-weight: bold;
        display: inline-block;
        text-underline-position: under;
        text-decoration: underline orange;
    }
    p:hover {
        font-weight: bold;
        display: inline-block;
        text-underline-position: under;
        text-decoration-style: wavy;
    }
    
<p>Meu efeito</p> Lorem, ipsum.

OBS1: if you do not see the property text-decoration-style: wavy in your browser, see here support: https://caniuse.com/#search=text-decoration-style

OBS2: Mozilla documentation on text-decoration-style: wavy https://developer.mozilla.org/pt-BR/docs/Web/CSS/text-decoration-style#Valores

Author: David, 2018-11-01

3 answers

I made this code based on this CodePen but it only works perfectly in Firefox:

insert the description of the image here

Testing in Opera and Chrome, the waves are cut and smaller compared to what Firefox displays:

insert the description of the image here

Using this property text-underline-position: under; the code stops working in Chrome/Opera. It seems to me that these browsers do not support 100% ownership. In Edge / IE 11 nothing happens, there is no support. Not tested in Safari modern.

The idea is to create a pseudo ::after with overflow: hidden in the text and that pseudo have the same transparent text by pulling 2x of an attribute data with the same text, and use @keyframes to move the pseudo to the left continuously, giving the infinite motion effect:

body {
   font-family: sans-serif;
   font-size: 2rem;
}
p {
   font-weight: bold;
   display: inline-block;
   text-decoration: underline orange;
   position: relative;
   overflow: hidden;
   padding-bottom: 7px; /* só funcionou no Firefox */
   white-space: nowrap;
}

p:hover {
   text-decoration: none;
}

p::after {
   visibility: hidden;
   z-index: -1;
   position: absolute;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   content: attr(data-texto) attr(data-texto);
   color: transparent;
   text-decoration: underline;
   -webkit-text-decoration-style: wavy;
   text-decoration-style: wavy;
   -webkit-text-decoration-color: orange;
   text-decoration-color: orange;
}

p:hover::after {
   visibility: visible;
   -webkit-animation: wavy-slide 3s linear infinite;
   animation: wavy-slide 3s linear infinite;
}

@-webkit-keyframes wavy-slide {
   to {
      left: -51%;
   }
}

@keyframes wavy-slide {
   to {
      left: -51%;
   }
}
<p data-texto="Meu efeito wavy underline">Meu efeito wavy underline</p>

Limitations detected:

  • I only got the expected effect in Firefox, but the waves are larger than appearing in the Chrome / Opera. It leads me to believe that there is no standardization to property.
  • only fits an entire line and no line break due to overflow.
 3
Author: Sam, 2018-11-01 15:00:02

I got a move effect (very bad), the idea is to create a pseudo element that will have the same content and it will have the underline. This element will stretch, giving that slight movement Effect

Is not exactly what you want but already gives a basis for a better answer

body { margin:0; padding:0; }
p {
    position: absolute;
    left: 0;
    top: 10px;
    line-height: 2;
}
[under]::before {
    width: 100px;
    overflow: hidden;
    content: attr(under);
    color: transparent;
    position: absolute;
    text-underline-position: under;
    text-decoration: underline orange;
    text-decoration-style: wavy;
    opacity: 0;
}
[under]:hover::before {
    opacity: 1;
    animation: under 1s linear;
    animation-fill-mode: both;
}
@keyframes under {
    0% {
        transform: scaleX(1);
    }
    100% {
        transform: scaleX(2);
    }
}
<p>
    <span under="Meu efeito">Meu efeito</span> Lorem, ipsum.
</p>
 2
Author: Costamilam, 2018-11-01 13:37:21

I will post a solution I got here that I found interesting and solves some bugs.

The main thing here was to make a small hake for the cool underline render. For this I needed to use a transparent linear-gradient as the span background. I don't wonder why, as I discovered this accidentally... While I was testing the behavior of the animated element I put a background-color in it and noticed that the bug stopped, but using the color in rgba() the problem back, but with a background-imagem: linear-gradiend the bug does not happen, at least in Chrome !

I also needed to use the text-underline-position: under; property to fix this problem in Chrome :

insert the description of the image here

See the result in Chrome and FireFox

insert the description of the image here

I also needed to make a adjustments using display:inline-block, overflow and height to control how the line will get cut etc...

Follow the code used:

div {
    font-family: sans-serif;
    font-size: 2rem;
}
div span,
div .efeito{
    display: inline-block;
    height: 60px;
    overflow: hidden;
}
div .efeito{
    font-weight: bold;
    text-decoration: underline;
    text-decoration-color: orange;
    text-underline-position: under;
    position: relative;
}
div .efeito:hover{
    text-decoration: none;
}
div .efeito::after{
    content: attr(data-text);
    width: 100%;
    color: transparent;
    position: absolute;
    top: 0;
    left: 15px;
    transition: 0s linear;
    text-decoration: none;
    text-decoration-style: none;
    text-decoration-color: orange;
    display: inline-block;
    height: 60px;
    text-underline-position: under;
    background-image: linear-gradient(rgba(0,0,0,0.0), rgba(0,0,0,0.0));
    z-index: -1;
}

div .efeito:hover::after {
    animation: underx 500ms infinite linear;
    text-decoration: underline;
    text-decoration-style: wavy;
    text-decoration-color: orange;
}

@keyframes underx {
    to {
        left: 0px;
    }
}
<div>
    <span class="efeito" data-text="meuy texto 123">meuy texto 123</span> <span>segue conteúdo.</span>
</div>

Note: in fonts of different sizes you may need to adjust the values that are in PX

 0
Author: hugocsl, 2018-12-10 14:16:49