Rotating and fade in/out different content in divs with one pausing longer than the others

Hi there,

I am trying to create a section of 6 boxes that will rotate content at different times. Something similar to the Sitepoint homepage at the moment with the various icons:

I have the following fiddle, but I can’t seem to get the animation frames right on the 3rd box.

I would like to have the third box pause longer on the content with the red background as this will have some text in and the other 3 will have an image in.

I believe I don’t seem to have this part correct:

 @keyframes fade-3 {

   25% {
     opacity: 0;

   50% {
     opacity: 1;

   75% {
     opacity: 0;

   100% {
     opacity: 1;

This is my fiddle:

Would it be possible to help me create this box with the red div pausing longer than the others and also stop the other divs from overlapping each other?

Many thanks!

This is how I would do it: using animation delays so only two @keyframe rules are needed.

I have left box items appearing from left to right so you can see the animation working for each item.


Thanks for the reply.

I kind of needed each of the other boxes to remain where they were as each of the boxes has rotating items within each box rather than showing all of the items at once.

It was the item in the 3rd box with the red background that I need to show for a longer period and then continue to rotate through the other items.

I will have a play and see if I can work it out.

I have updated the CodePen above using animation delay instead of alternate direction. This allows the third item to have four phases.


That looks fantastic, thank you so much :slight_smile: I will make some changes as I would like the other boxes to have various delays too and will post back the end result :slight_smile:

Thanks again!

Note in my CodePen the @keyframes rule for the third item holds the opacity of each element at 1 for 10% of the animation duration. You may like the @keyframes rule for the other items to hold at 1 for while. You could also consider changing the percentage figures so there’s a crossover of fading: so one element starts to appear before the other has fully disappeared.

The animation timng function defaults to ‘ease’. For opacity animation, it may be slightly better to use ‘linear’ but I have not tried it. If you change to ‘linear’ I expect you would need the opacity to remain at 1 for a while.

Apart from the third item, the animation could reverse as you had it (with only one @keyframe rule required). I changed it to always go forward so it’s working in the same way as the rule for the third item.

1 Like

Hi there,

I have made some changes to the below fiddle, but have a few issues:

  1. When the text items in red get to the 5th and 6th item, there seems to be a weird overlap and also an additional “1” and “4” outside of the red text, like this:


I have checked all the classes and order of the items, but I can’t seem to work out what is wrong.

  1. Between the transitions, they all disappear with the background going white. Is threre a way to have each item fade equally between each other in each box? For example, so the third box, have the red text fade into the black text so there is no white?

  2. @Archibald mentioned about using transition-timing-function: linear; however, I am not sure where to place this. I have tried adding it to each of these:

.js-nametag-1:nth-child(1) {
  animation: fade-1 40s infinite;
transition-timing-function: linear;

But it doesn’t seem to change anything.

Lastly, you also mentioned that with just one keyframe, I can reverse it. What keyframe would this be?

Sorry for all the questions!

Thank you for your time.

Your code here . . . .

.js-nametag-1:nth-child(5) {
  animation: fade-1 40s 40s infinite;

. . . . means that after 40 seconds from page load the 5th child will start at the same time that the 1st child restarts after its first animation run. That’s an example of why you are sometimes getting two items appearing on top of one another.

Another issue is that the @keyframes rule was designed for four “phases” (my terminology) with the opacity being above zero for 25% of the time. You now have six phases.

In the CodePen below I have changed the @keyframes rule so opacity is above zero for 16% of the time (rounding down from 100/6). For convenience to avoid decimals, I have also changed the animation duration to 36 seconds. Each animation now starts after delays of 0s, 6s, 12s 18s, 24s.& 30s.

As you are using nth-child, there is no need for all those classes. I have therefore deleted them.

Also your six @keyframes rules are all the same, so I have deleted five of them.

Yes, but let’s not complicate things further yet :grinning:.

It can go as you have shown or anywhere within the shorthand animation property:
animation: fade 36s infinite linear;


Hi @Archibald

Thank you very much for that, that is great. I see what you mean about the phases.

I think that all works perfectly :slight_smile:

I am wondering how I have the first item of each phase fade into the next one so there is no white gap between fades. My idea is to have them all rotating at different times so the white won’t be there across all 6 items, but I think it will still be there when i have them at different times.

What would be the best way to fade one into the other? Would I need to somehow add another keyframe that loads the next one with 0 opacity into 100% opacity?

Thanks again!

Let’s first consider how to get fading to cross over so when one element starts to fade out the next one starts to fade in. It’s simply extending the time each element is displayed for. However you need to carefuuly work out when the opacity changes need to happen. Let’s stick for the moment with having 6 phases in 36 seconds, all of equal duration. In the graphs below I have chosen to have the fading take place over a period of one second (I think something between 0.5 seconds and 1.0 seconds tends to look good). The graphs do not show the whole animation duration of 36 seconds. Linear fade is shown but you could stick with using ‘ease’.
The times in seconds need to be converted to percentages of 36 seconds for the @keyframe rule. So 1/36 is 2.79%, 6/36 is 16.67% and 7/36 is 19.44%. The @keyframe rule therefore becomes:

@keyframes fade {
  0% {
    opacity: 0;

  16.67% {
    opacity: 1;

  19.44% {
    opacity: 0;

This is demonstated in the CodePen below:

Let’s now consider keeping the animation repeating every 36 seconds but not having equal duration of the phases. Say three phases are 4 seconds and three phases are 8 seconds (not including the fade out duration when the fading out crosses over with the fading in). You would then need two @keyframe rules and would need to work out the animation delays required.

The animation of each ‘box-item’ on your web page does not have to repeat every 36 seconds and you don’t have to have six phases for every ‘box-item’. However you will need to carefully work out the timing of fade in and fade out, then convert to percentages taking into account differing animation durations.

It’s worth noting that if you later decide to change the number of phases of a ‘box-item’ or to change the animation duration, or to change the fading speed you will need to go back and recalculate all the percentages needed for @keyframe. If you keep the phases of equal duration for each ‘box-item’, I think it would be possible and realistic to use CSS variables and CSS calc() to avoid having to recalculate manually.

Now you know why I did not include all this in my previous post :grinning:

H @Archibald,

Thanks once again for the awesome reply, and thanks for explaining with the graphs.

It sounds very complicated, but I understand how the percentage side of things work, although my maths isn’t great!

I can see how complicated that would be to have the overlap and then have it repeat every 36 seconds, so I think i will have it just all equal phases :slight_smile:

Thank you for all your help with this, I really do appreciate your help.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.