Reputation: 550
I don't have a good enough understanding of web development to be able to tell if my question is already answered here, so apologies if this is a duplicate.
I'm planning to have a lot of different pages in my website, all structured differently, all of which need to look reasonable on a variety of different screen sizes. These pages will include and/or link-to code that makes various bits of content appear and disappear. On some of these pages however I'm finding there's too much appearing and disappearing all at once and the reader gets confused about exactly what has changed. To solve this, I'd love to write either some CSS or some JS for ensuring that when the position of an element changes, it smoothly moves into the new position instead of just jumping there. Hopefully, this will help the end-user better understand how the content has changed.
I'm currently trying to do this with CSS using a "transition" applied to the "position" attribute, but to no avail. Here's the code:
function toggleVisibility(elementId) {
var element = document.getElementById(elementId);
if (element.style.display === "none") {
element.style.display = null;
} else {
element.style.display = "none";
}
}
#lol {
position: relative;
transition: position 2s;
transition-timing-function: linear;
-webkit-transition-timing-function: linear;
}
<head>
<title>Title</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="foo"> foo </div>
<div id="bar"> bar </div>
<div id="lol"> lol </div>
<button onmouseup="toggleVisibility('bar')"> Click me</button>
</body>
This doesn't do anything helpful, unfortunately. There's no smooth transition; the text that says "lol" jumps around instantaneously.
Ideas, anyone? A javascript solution is fine, but I'm looking for something that's generic enough that it can be applied anywhere on the page without precomputing any values, if that makes sense.
Upvotes: 0
Views: 1328
Reputation: 5066
First of all according to W3C (read for more)display
is not a animateable property. So when you change the display
from block
to none
or vice versa you can not animate this change.
But in order to achieve what you want is you can use the height
property. When hiding the element you need to do is set the height to 0. And add transitions to that and that will do the trick.
Also in order for you to use this throughout your application use a class say hidden
and whenever you want any element to hide with animation add this class to that. Below is a working snippet of the same.
Also for the above to work you need to give your element some initial height as transitions wont work with height: auto
function toggleVisibility(elementId) {
var element = document.getElementById(elementId);
if (element.style.height === "0") {
element.classList.remove('hidden');
} else {
element.classList.add('hidden');
}
}
div.hidden {
-moz-transition: height .8s;
-ms-transition: height .8s;
-o-transition: height .8s;
-webkit-transition: height .8s;
transition: height .8s;
height: 0;
overflow: hidden;
opacity: 0;
}
div {
height: 20px;
opacity: 1;
}
<head>
<title>Title</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="foo"> foo </div>
<div id="bar"> bar </div>
<div id="lol"> lol </div>
<button onmouseup="toggleVisibility('bar')"> Click me</button>
</body>
Hope this helps :)
Upvotes: 1
Reputation: 2071
You need to define the height of your elements, auto
won't animate. Also you shouldn't use ids to style objects, is better to use a class so that you don't have specificity problems.
Here's a working example, I added also opacity
and overflow: hidden
to make the item disappear:
function toggleVisibility(elementId) {
var element = document.getElementById(elementId);
element.classList.toggle("hidden");
}
.item {
position: relative;
height: 20px;
overflow-y: hidden;
opacity: 1;
transition: height 0.5s, opacity 0.3s;
transition-timing-function: linear;
-webkit-transition-timing-function: linear;
}
.hidden {
height: 0;
opacity: 0;
}
<head>
<title>Title</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="foo" class="item"> foo </div>
<div id="bar" class="item"> bar </div>
<div id="lol" class="item"> lol </div>
<button onmouseup="toggleVisibility('bar')"> Click me</button>
</body>
Upvotes: 1