Reputation: 31
I am struggling to get a modal get animated when a button is clicked. The modal must not take space when its hidden. So I want to use display none when its not shown. And when the button is clicked the modal needs to fade in. Now I have found a solution I think to make it work. But still it's not working. Could anyone tell me why its not working? An how I could get it to work?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<h2>Animating from <code>display:none</code> to <code>display:block</code></h2>
<div id="box" class="box"></div>
<button>TOGGLE VISIBILITY</button>
</body>
<script src="script.js"></script>
</html>
.box {
background: goldenrod;
width: 300px;
height: 300px;
margin: 30px auto;
transition: all 2s linear;
display: none;
}
.show {
display: block;
}
.visuallyshow {
opacity: 0;
}
button {
display: block;
margin: 0 auto;
}
let box = document.getElementById('box'),
btn = document.querySelector('button');
btn.addEventListener('click', function () {
if (box.classList.contains('show')) {
box.classList.remove('show');
setTimeout(function () {
box.classList.remove('visuallyshow');
}, 20);
} else {
box.classList.add('visuallyshow');
box.addEventListener('transitionend', function (e) {
box.classList.add('show');
}
// , {
// capture: false,
// once: true,
// passive: false
// }
);
}
}, false);
Upvotes: 0
Views: 2138
Reputation: 129
The problem is that your .box stylesheet does not have "opacity: 0;"
by default and that's why it is not transitioning smoothly. Other than that your transition speed is set to 2000 ms which is very slow.
I have made a working solution in this fiddle link: https://jsfiddle.net/32oyu6wf/3/
What I did is I have modified the .box stylesheet to have "opacity: 0;"
& adapted the javascript eventlistener to trigger the classes accordingly.
Inspect the fiddle a little and you can re-use the same method in your project.
let box = document.getElementById('box'),
btn = document.querySelector('button');
btn.addEventListener('click', function() {
if (box.style.display == "block") {
box.classList.remove("visuallyshow")
setTimeout(function() {
box.style.display = "none"
}, 210);
} else {
box.style.display = "block";
setTimeout(function() {
box.classList.add("visuallyshow")
}, 20);
}
}, false);
.box {
background: goldenrod;
width: 300px;
height: 300px;
margin: 30px auto;
transition: all 0.3s linear;
display: none;
opacity: 0;
}
.visuallyshow {
opacity: 1;
}
button {
display: block;
margin: 0 auto;
}
<h2>Animating from <code>display:none</code> to <code>display:block</code></h2>
<button>TOGGLE VISIBILITY</button>
<div id="box" class="box"></div>
Upvotes: 1
Reputation: 92719
Here's what you need to do:
opacity: 0
, and the .visuallyshow
class should change it to 1.setTimeout
should be 2000, not 20. 2 seconds equals 2000 milliseconds.display: block
, and then opacity: 1
.transitionend
event handler, you should use setTimeout
with 1 ms delay. This will allow the browser to rerender the layout, and so the transition will be able to happen.let box = document.getElementById('box'),
btn = document.querySelector('button');
btn.addEventListener('click', function () {
if (box.classList.contains('show')) {
box.classList.remove('visuallyshow');
setTimeout(function () {
box.classList.remove('show');
}, 2000);
} else {
box.classList.add('show');
setTimeout(() => {
box.classList.add('visuallyshow');
}, 1);
}
}, false);
.box {
background: goldenrod;
width: 300px;
height: 300px;
margin: 30px auto;
transition: opacity 2s linear;
display: none;
opacity: 0;
}
.show {
display: block;
}
.visuallyshow {
opacity: 1;
}
button {
display: block;
margin: 0 auto;
}
<h2>Animating from <code>display:none</code> to <code>display:block</code></h2>
<div id="box" class="box"></div>
<button>TOGGLE VISIBILITY</button>
Upvotes: 1
Reputation:
.modal {
display: none;
opacity: 0;
transition: opacity: 1s;
}
.modal.show {
display: block;
opacity: 1;
}
Should work if you ...classList.add('show')
to the modal.
I think the reason yours isn't working is because in order to apply a transition it first needs an initial value before it can know what to transition to. In the above case you first need to tell it that the opacity is 0, after which you can actually "transition" it to 1.
Upvotes: 1