Photo by Luca Bravo on Unsplash.com
We are not going to lie to ourselves, it's hot at the moment. But it doesn't change anything for the Badsender team which continues to work from home, as usual. And we won't stay silent! No! One more day of silence seemed inconceivable to me. I continue to develop new techniques that are not always well supported on most mail clientsToday, the house offers you, suspense and riddle:
The rewriting of a word
Yes, because the title of the article does not mean anything. Or rather, it is the "scientific" name given to this reaction. But a "typewriter" effect for a text written, then deleted, then rewritten, is anything but what it is possible to do via a typewriter... So, let's talk instead about a smooth transition in HTML and CSS languages in an email that will simulate the rewriting of a word by one or more vocables. Hop and boom.
Why?
I've done this many times via an animated gif. And there, drama! I can say that it is not obvious. And quite complex to update. In truth, the expected solution is usually much easier to generate via javascript, but here, I say no, and I weigh my word: javascript can only impact negatively your deliverability, and this is probably not what you want.
Many similar effects are available about Codepen for example, but they are in no way adapted to emailing. This made me curious. I absolutely wanted to reproduce this result in an email but without using the first technique mentioned above (and even less of the second one, so let's not say it). So I made the grandiloquent choice to work on its realization in code supported by messaging software : you will not see a record of absence of trumpeting ineptitude.
Here I go again.
I have chosen to make this rendering by calling on to a friend to the CSS property animation
. Because what is a rewrite if not the fact of applying an animation to its text by deleting it? What do you mean, no? Every word disappears (for a while) to make room for another.
I see it this way, at least technically: the letters of each word will first be dissociated in block tags. The first letters of each word will be presented in a 1st cell of a table. The second letters will be grouped in a 2nd cell of the same table. The third letters will be grouped in a 3rd cell of the same table. And so on, a little seriousness all the same. I'm waiting for you to get a picture of this.
<table border="0" cellspacing="0" cellpadding="0" align="center" style="margin:0px auto;" role="presentation" bgcolor="#FFCE3D">
<tr>
<td><h1>t</h1>
<h1>e</h1>
<h1>a</h1></td>
<td><h1>o</h1>
<h1>n</h1>
<h1>u</h1></td>
<td><h1>u</h1>
<h1>c</h1>
<h1>s</h1></td>
<td><h1>j</h1>
<h1>o</h1>
<h1>s</h1></td>
<td><h1>o</h1>
<h1>r</h1>
<h1>i</h1></td>
<td><h1>u</h1>
<h1>e</h1>
<h1> </h1></td>
<td><h1>r</h1>
<h1> </h1>
<h1> </h1></td>
<td><h1>s</h1>
<h1> </h1>
<h1> </h1></td>
</tr>
</table>
You're so surprised! Do you see the words "always", "again" and "also"? So you've understood the basics, and I'm glad you do. Gosh, let's go further into the complexity of the exercise: let's assign an identifier id
to each <h1>
as well as a style that allows the content to be visible at first glance. <h1>
of each cell, and CSS properties that will make the others "invisible".
<table border="0" cellspacing="0" cellpadding="0" align="center" style="margin:0px auto;" role="presentation" bgcolor="#FFCE3D">
<tr>
<td><h1 id="texte01" style="font-size:46px; color:#000000; font-family:Arial, Helvetica, sans-serif;">t</h1>
<h1 id="texte09" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">e</h1>
<h1 id="texte17" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">a</h1></td>
<td><h1 id="texte02" style="font-size:46px; color:#000000; font-family:Arial, Helvetica, sans-serif;">o</h1>
<h1 id="texte10" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">n</h1>
<h1 id="texte18" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">u</h1></td>
<td><h1 id="texte03" style="font-size:46px; color:#000000; font-family:Arial, Helvetica, sans-serif;">u</h1>
<h1 id="texte11" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">c</h1>
<h1 id="texte19" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">s</h1></td>
<td><h1 id="texte04" style="font-size:46px; color:#000000; font-family:Arial, Helvetica, sans-serif;">j</h1>
<h1 id="texte12" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">o</h1>
<h1 id="texte20" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">s</h1></td>
<td><h1 id="texte05" style="font-size:46px; color:#000000; font-family:Arial, Helvetica, sans-serif;">o</h1>
<h1 id="texte13" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">r</h1>
<h1 id="texte21" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">i</h1></td>
<td><h1 id="texte06" style="font-size:46px; color:#000000; font-family:Arial, Helvetica, sans-serif;">u</h1>
<h1 id="texte14" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;">e</h1>
<h1 id="texte22" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;"> </h1></td>
<td><h1 id="texte07" style="font-size:46px; color:#000000; font-family:Arial, Helvetica, sans-serif;">r</h1>
<h1 id="texte15" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;"> </h1>
<h1 id="texte23" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;"> </h1></td>
<td><h1 id="texte08" style="font-size:46px; color:#000000; font-family:Arial, Helvetica, sans-serif;">s</h1>
<h1 id="texte16" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;"> </h1>
<h1 id="texte24" style="font-size:0px; color:#000000; font-family:Arial, Helvetica, sans-serif;"> </h1></td>
</tr>
</table>
If the sight of this code revolts you like a vegan at the sight of a rare rib steak, then I can't help you, we are only at the beginning. You will notice that the three unique identifiers of a cell are incremented by 8: logical, since the longest word, "always", has 8 letters. Yes, don't deny it!
Need help?
Reading content isn't everything. The best way is to talk to us.
As it is, we have the word "always" on the screen. Great! The other two words are well "hidden". Now we have to move on to the most difficult part: CSS animations. Fi! In my opinion, it is enough to apply a CSS animation to each letter of the words, and to decide, through these same animations, to enlarge the typography of the text, as well as the width of the element <h1>
concerned. I make it my business. Let's see first how to "call" an animation.
#texte01 { animation:typing01 10s infinite;}
Here, I assign to the 1st letter of my 1st word via the identifier #text01
the CSS animation named typing01. This animation will last 10 seconds and will run in a loop (hence the infinite
in conclusion of my statement... But tell me, if I dare say, you understand quickly!) But that's not enough, Let's now apply ourselves to understand how animation works.
@keyframes typing01 {
0% {width:100%; font-size:46px;}
20% {width:100%; font-size:46px;}
21% {width:0%; font-size:0px;}
62% {width:0%; font-size:0px;}
63% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
"Oula, what is this gibberish, what is the artist doing to us?" you might say. But it won't pass. Learn (at your expense) thatthis is only a detail of the steps of an animation. For a single letter, that is. But nothing very complex: the rule @keyframes
allows the developer to define the steps that make up the sequence of a CSS animation. This allows to control an animation more finely than what could be obtained with transitions.
And, joy, in our case, there is nothing simpler: from step 0% to step 20% of our typing01 animation of 10 seconds duration (i.e. 20% of 10 seconds, or 0.2 seconds) the letter included in the <h1>
has a font size of 46px, and the <h1>
concerned takes all its width. Then, from 21% to 62%, the letter becomes almost invisible since it is reduced to a size of 0 pixel, when the <h1>
sees its width decreased to 0%. Finally, from 63% to 100% of the animation, the letter and its container return to their original sizes. In other words, the letter "t" of the word "always" starts by being displayed for 0.2 seconds, then "disappears" for 0.4 seconds (to make room first for the letter "e" in the word "again", then for the letter "a" in the word "also")to finally reappear...
What do I hear? What do I hear? "I scratch myself to make myself laugh?" I despise you and laugh at you, you fools! Let's move on to the entire CSS style with all the animations for the 24 "letters".
h1 {color:#000000; font-family:Arial, Helvetica, sans-serif; overflow:hidden; margin:0 auto; font-size:0px; font-weight:bold;}
#texte01 {animation:typing01 10s infinite;}
#texte02 {animation:typing02 10s infinite;}
#texte03 {animation:typing03 10s infinite;}
#texte04 {animation:typing04 10s infinite;}
#texte05 {animation:typing05 10s infinite;}
#texte06 {animation:typing06 10s infinite;}
#texte07 {animation:typing07 10s infinite;}
#texte08 {animation:typing08 10s infinite;}
#texte09 {animation:typing09 10s infinite;}
#texte10 {animation:typing10 10s infinite;}
#texte11 {animation:typing11 10s infinite;}
#texte12 {animation:typing12 10s infinite;}
#texte13 {animation:typing13 10s infinite;}
#texte14 {animation:typing14 10s infinite;}
#texte15 {animation:typing15 10s infinite;}
#texte16 {animation:typing16 10s infinite;}
#texte17 {animation:typing17 10s infinite;}
#texte18 {animation:typing18 10s infinite;}
#texte19 {animation:typing19 10s infinite;}
#texte20 {animation:typing20 10s infinite;}
#texte21 {animation:typing21 10s infinite;}
#texte22 {animation:typing22 10s infinite;}
#texte23 {animation:typing23 10s infinite;}
#texte24 {animation:typing24 10s infinite;}
@keyframes typing01 {
0% {width:100%; font-size:46px;}
20% {width:100%; font-size:46px;}
21% {width:0%; font-size:0px;}
62% {width:0%; font-size:0px;}
63% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
@keyframes typing02 {
0% {width:100%; font-size:46px;}
21% {width:100%; font-size:46px;}
22% {width:0%; font-size:0px;}
63% {width:0%; font-size:0px;}
64% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
@keyframes typing03 {
0% {width:100%; font-size:46px;}
22% {width:100%; font-size:46px;}
23% {width:0%; font-size:0px;}
64% {width:0%; font-size:0px;}
65% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
@keyframes typing04 {
0% {width:100%; font-size:46px;}
23% {width:100%; font-size:46px;}
24% {width:0%; font-size:0px;}
65% {width:0%; font-size:0px;}
66% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
@keyframes typing05 {
0% {width:100%; font-size:46px;}
24% {width:100%; font-size:46px;}
25% {width:0%; font-size:0px;}
66% {width:0%; font-size:0px;}
67% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
@keyframes typing06 {
0% {width:100%; font-size:46px;}
25% {width:100%; font-size:46px;}
26% {width:0%; font-size:0px;}
67% {width:0%; font-size:0px;}
68% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
@keyframes typing07 {
0% {width:100%; font-size:46px;}
26% {width:100%; font-size:46px;}
27% {width:0%; font-size:0px;}
68% {width:0%; font-size:0px;}
69% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
@keyframes typing08 {
0% {width:100%; font-size:46px;}
27% {width:100%; font-size:46px;}
28% {width:0%; font-size:0px;}
69% {width:0%; font-size:0px;}
70% {width:100%; font-size:46px;}
100% {width:100%; font-size:46px;}
}
@keyframes typing09 {
0% {width:0%; font-size:0px;}
21% {width:0%; font-size:0px;}
22% {width:100%; font-size:46px;}
40% {width:100%; font-size:46px;}
41% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing10 {
0% {width:0%; font-size:0px;}
22% {width:0%; font-size:0px;}
23% {width:100%; font-size:46px;}
41% {width:100%; font-size:46px;}
42% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing11 {
0% {width:0%; font-size:0px;}
23% {width:0%; font-size:0px;}
24% {width:100%; font-size:46px;}
42% {width:100%; font-size:46px;}
43% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing12 {
0% {width:0%; font-size:0px;}
24% {width:0%; font-size:0px;}
25% {width:100%; font-size:46px;}
43% {width:100%; font-size:46px;}
44% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing13 {
0% {width:0%; font-size:0px;}
25% {width:0%; font-size:0px;}
26% {width:100%; font-size:46px;}
44% {width:100%; font-size:46px;}
45% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing14 {
0% {width:0%; font-size:0px;}
26% {width:0%; font-size:0px;}
27% {width:100%; font-size:46px;}
45% {width:100%; font-size:46px;}
46% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing15 {
0% {width:0%; font-size:0px;}
27% {width:0%; font-size:0px;}
28% {width:100%; font-size:46px;}
46% {width:100%; font-size:46px;}
47% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing16 {
0% {width:0%; font-size:0px;}
28% {width:0%; font-size:0px;}
29% {width:100%; font-size:46px;}
47% {width:100%; font-size:46px;}
48% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing17 {
0% {width:0%; font-size:0px;}
41% {width:0%; font-size:0px;}
42% {width:100%; font-size:46px;}
62% {width:100%; font-size:46px;}
63% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing18 {
0% {width:0%; font-size:0px;}
42% {width:0%; font-size:0px;}
43% {width:100%; font-size:46px;}
63% {width:100%; font-size:46px;}
64% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing19 {
0% {width:0%; font-size:0px;}
43% {width:0%; font-size:0px;}
44% {width:100%; font-size:46px;}
64% {width:100%; font-size:46px;}
65% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing20 {
0% {width:0%; font-size:0px;}
44% {width:0%; font-size:0px;}
45% {width:100%; font-size:46px;}
65% {width:100%; font-size:46px;}
66% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing21 {
0% {width:0%; font-size:0px;}
45% {width:0%; font-size:0px;}
46% {width:100%; font-size:46px;}
66% {width:100%; font-size:46px;}
67% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing22 {
0% {width:0%; font-size:0px;}
46% {width:0%; font-size:0px;}
47% {width:100%; font-size:46px;}
67% {width:100%; font-size:46px;}
68% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing23 {
0% {width:0%; font-size:0px;}
47% {width:0%; font-size:0px;}
48% {width:100%; font-size:46px;}
68% {width:100%; font-size:46px;}
69% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
@keyframes typing24 {
0% {width:0%; font-size:0px;}
48% {width:0%; font-size:0px;}
49% {width:100%; font-size:46px;}
69% {width:100%; font-size:46px;}
70% {width:0%; font-size:0px;}
100% {width:0%; font-size:0px;}
}
And so on. Would you like to acknowledge the rendering of this developed code? You touch a sensitive point. Paf, unprecedented miracle:
What about the support? I'm being short-changed, but it doesn't matter, it was planned. In view of the support of the only animation property detailed by Campaign MonitorI think I'm not exaggerating when I say that you can count on a rather low support, since it's mainly iOS systems that will guarantee the expected effect... But of course, it depends on the target on which you are going to test! And yet, I want to reassure you: if the transition does not work, only the first word will be displayed, while the others will remain hidden.
Problems, questions, troubles, anguish and confusion, I am here to answer them.