Home > Back-end >  How can I animate size change from unknown width to 100%?
How can I animate size change from unknown width to 100%?

Time:03-29

I have the following situation: I'm displaying multiple div boxes, each with differing width depending on the context. For example:

.demand-2 {
    width: 29%;
}
.demand-3 {
    width: 43%;
}

A div with demand-2 is supposed to only be 29% of its parent width.

Now, there's a button that increases all the boxes to a width of 100%. With the following CSS I make sure that the transition is smooth:

maxLevelOff {
    animation-duration: 1s;
    animation-name: maxOff;
    animation-fill-mode: forwards;
}
@keyframes maxOff {
    from {
        width: 29;
    }
    to {
        width: 100%;
    }
}

This works perfectly fine, however, as you can see, only for demand-2 since I had to hard code it.

My question now, is there a way I can do this dynamically? Otherwise I'd have to create an animation for all the different widths and that seems tedious. This should also go the other way. In other words, if I click the button again, all the boxes should transit from 100% back to their original size.

CodePudding user response:

As an alternative, you can use css transitions as well. When the width changes, it smoothly transitions to that new width. You just need to add a class of .full-width to each .demand that you want to be of 100% width.

I provided a simple demo below. If you click on the button once, the widths expand and it returns to the original width if you click it a second time.

let button = document.querySelector('button');

button.addEventListener('click', () => {
  let demand = document.querySelectorAll('.demand');
  demand.forEach(el => {
    if(el.classList.contains('full-width')) el.classList.remove('full-width')
    else el.classList.add('full-width')
  });
});
.demand {
  height: 100px;
  transition: width 0.3s ease-in;
}

.demand-2 {
  background: blue;
  width: 29%;
}

.demand-3 {
  background: red;
  width: 49%;
}

.demand-4 {
  background: green;
  width: 69%;
}

.demand.full-width {
  width: 100%;
}
<div ></div>
<div ></div>
<div ></div>
<button>Click</button>

CodePudding user response:

You don't need to have a start position in your keyframe

@keyframes maxOff {
    to {
        width: 100%;
    }
}

For example

@keyframes maxOff {
  to {
    width: 100%;
  }
}

.first {
  width: 300px;
  height: 100px;
  background: red;
  animation: maxOff 1s ease infinite alternate;
}

.second {
  width: 100px;
  height: 100px;
  background: blue;
  animation: maxOff 1s ease infinite alternate;
}

.third {
  width: 50%;
  height: 100px;
  background: yellow;
  animation: maxOff 1s ease infinite alternate;
}
<div ></div>
<div ></div>
<div ></div>

If you want to have backward animation, you should have 2 separate keyframe ones (one for forwarding, one for backwarding)

And with this solution, you need to have javascript to handle click

For example (you need to click on the swimlane area for the animation)

function activateAnimation(self) {
   if(self.classList.contains("active")) {
      self.classList.remove("active")
      self.classList.add("deactive")
   } else {
      self.classList.add("active")
      self.classList.remove("deactive")
   }
}
@keyframes maxOff {
  to {
    width: 100%;
  }
}

@keyframes maxBack {
  from {
    width: 100%;
  }
}

.third {
  width: 50%;
  height: 100px;
  background: yellow;
}

.third.active {
  animation: maxOff 1s ease 1 forwards;
}

.third.deactive {
  animation: maxBack 1s ease 1 alternate;
}
<div  onclick="activateAnimation(this)"></div>

  • Related