ReedyBear's Blog

testing alternating text with css animations

My bestie had tried a <marquee> to scroll through different human rights for her Stand Up Fight Back newsletter, but she didn't like the results.

So I thought I'd try doing what she wanted via CSS animations. I've done a few CSS animations before, but never messed with them too extensively. This is a rough first draft, and it is by no means elegant, BUT it gets the job done (or at least what I understand the job to be!)

Anyway, here is that attempt:


Bears are the best animal Sharks are really good too They could be best friends And collect a parrot or two
And collect a parrot or two

How it works

(just for the nerds who are interested) There is a <span> for each bit of text that will flicker in/out. The spans all have absolute positioning so they are on top of eachother. Every span has the same amount of time for the total duration. Since there are 4 bits of text, each text will display for 25% of the total animation time. So from 0% - 25% we want black text for span1 (25-75% it is transparent), then 25%-50% span2 should be black text. So the text is not in a forever semi-faded state, I use 0% black, then 22% black, then 25% transparent, SO that means the transition from black to transparent is only for 3% of the total animation time. This approach is repeated for each of the spans. If we had five bits of text, then we would do 20% increments instead of 25%. Lastly, there is a <div> at the end of the custom marquee. That final div's text is transparent, so it is not visibile. The purpose of that div is to take up space, because absolute-positioned spans do not take up space and would then overlap with the previous node.

The Code

<div class="marquee">  
    <span>Bears are the best animal</span>  
    <span>Sharks are really good too</span>  
    <span>They could be best friends</span>  
    <span>And collect a parrot or two</span>  
    <div>And collect a parrot or two</div>  
</div>  
    

<style>  
.marquee {  
    position: relative;  
}  
.marquee > div {  
    color: transparent;  
    display: inline-block;  
}  
.marquee > span {  
    position: absolute ;  
}  

.marquee span:nth-child(1){  
    animation: flicker1 6s infinite;  
}  
.marquee span:nth-child(2){  
    animation: flicker2 6s infinite;  
}  
.marquee span:nth-child(3){  
    animation: flicker3 6s infinite;  
}  
.marquee span:nth-child(4){  
    animation: flicker4 6s infinite;  
}  

@keyframes flicker1 {  
  0% {  
    color: black;  
  }  
  22% {  
    color: black;  
  }  
  25% {  
    color: transparent;  
  }  
  100% {  
    color:transparent;  
  }  
}  
@keyframes flicker2 {  
  0% {  
    color: transparent;  
  }  
  22% {  
    color: transparent;  
  }  
  25% {  
    color: black;  
  }  
  48% {  
    color: black;  
  }  
  50% {  
    color: transparent;  
  }  
  100% {  
    color:transparent;  
  }  
}  
@keyframes flicker3 {  
  0% {  
    color: transparent;  
  }  
  48% {  
    color: transparent;  
  }  
  50% {  
    color: black;  
  }  
  72% {  
    color: black;  
  }  
  75% {  
    color: transparent;  
  }  
  100% {  
    color:transparent;  
  }  
}  
@keyframes flicker4 {  
  0% {  
    color: transparent;  
  }  
  73% {  
    color: transparent;  
  }  
  75% {  
    color: black;  
  }  
  97% {  
    color: black;  
  }  
  100% {  
    color:transparent;  
  }  
}  
</style>