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>