Objective: Animate div on content resize.
Given:
Div height and width are not specified.
Div size depends on content size.
When content size changes, div size also changes (without animation, resizes within 0.5FPS).
Question: How do I apply animation/effect on div when it is dynamically changing size, depending on content?
NOTE: one good example of this is #gmail (card resizes on successful next)
There is a way for this. You need to use a one hidden element for that way. You have to set the content in both elements. try the following
HTML:
<span id="hiddenElement"></span>
<div id="displayElement"></div>
CSS:
#hiddenElement
{
max-width: 200px;
opacity: 0;
/* use different properties to completely hide. but do not give width:0 */
}
#displayElement
{
width: auto;
height: auto;
max-width: 200px;
-webkit-transition: width 0.5s, height 0.5s; /* Safari */
transition: width 0.5s, height 0.5s;
border: 1px solid black;
overflow: hidden;
}
JS method:
function setContent(content)
{
$("#hiddenElement").text(content);
$("#displayElement").text(content);
$("#displayElement").width($("#hiddenElement").width());
$("#displayElement").height($("#hiddenElement").height());
}
Apply a max-height and a max-width and a display property of inline-block.
div {
display: inline-block;
background:red;
transition: max-height 1s, max-width 1s;
max-height:0;
max-width:0;
}
div:hover {
max-height:200px;
max-width:400px;
}
<div>yada yada yada</div>
Related
I want to create an expand/collapse animation that's powered only by classnames (javascript is used to toggle the classnames).
I'm giving one class max-height: 4em; overflow: hidden;
and the other max-height: 255em; (I also tried the value none, which didn't animate at all)
this to animate: transition: max-height 0.50s ease-in-out;
I used CSS transitions to switch between them, but the browser seems to be animating all those extra em's, so it creates a delay in the collapse effect.
Is there a way of doing it (in the same spirit - with css classnames) that doesn't have that side-effect (I can put a lower pixel count, but that obviously has drawbacks, since it might cut off legit text - that's the reason for the big value, so it doesn't cut off legit long text, only ridiculously long ones)
See the jsFiddle - http://jsfiddle.net/wCzHV/1/ (click on the text container)
Fix delay solution:
Put cubic-bezier(0, 1, 0, 1) transition function for element.
scss
.text {
overflow: hidden;
max-height: 0;
transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);
&.full {
max-height: 1000px;
transition: max-height 1s ease-in-out;
}
}
css
.text {
overflow: hidden;
max-height: 0;
transition: max-height 0.5s cubic-bezier(0, 1, 0, 1);
}
.text.full {
max-height: 1000px;
transition: max-height 1s ease-in-out;
}
This is an old question but I just worked out a way to do it and wanted to stick it somewhere so I know where to find it should I need it again :o)
So I needed an accordion with clickable "sectionHeading" divs that reveal/hide corresponding "sectionContent" divs. The section content divs have variable heights, which creates a problem as you can't animate height to 100%. I've seen other answers suggesting animating max-height instead but this means sometimes you get delays when the max-height you use is larger than the actual height.
The idea is to use jQuery on load to find and explicitly set the heights of the "sectionContent" divs. Then add a css class 'noHeight' to each a click handler to toggle it:
$(document).ready(function() {
$('.sectionContent').each(function() {
var h = $(this).height();
$(this).height(h).addClass('noHeight');
});
$('.sectionHeader').click(function() {
$(this).next('.sectionContent').toggleClass('noHeight');
});
});
For completeness, the relevant css classes:
.sectionContent {
overflow: hidden;
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
transition: all 0.3s ease-in;
}
.noHeight {
height: 0px !important;
}
Now the height transitions work without any delays.
In case anyone is reading this, I have not found a solution and went with an expand-only effect (which was achieved by moving the transition style to the expanded class definition)
Use display:flex. This will work:
.parent > div {
display: flex;
flex-direction: column;
height: 0px;
max-height: 0px;
opacity: 0;
overflow: hidden;
transition: all 0.3s;
}
.parent > div.active {
opacity: 1;
height: 100%;
max-height: none; /* important for animation */
}
The solution is actually quite simple. Make a child div, that has the content. The parent div will be the one that expands collapses.
On load the parent div will have a max-height. when toggling, you can check the child height by writing document.querySelector('.expand-collapse-inner').clientHeight; and set the maxheight with javascript.
In your CSS, you will have this
.parent {
transition: max-height 250ms;
}
You can accomplish this just fine using jQuery Transit:
$(function () {
$(".paragraph").click(function () {
var expanded = $(this).is(".expanded");
if (expanded)
{
$(this).transition({ 'max-height': '4em', overflow: 'hidden' }, 500, 'in', function () {$(this).removeClass("expanded"); });
}
else
{
$(this).transition({ 'max-height': $(this).get(0).scrollHeight, overflow: ''}, 500, 'out', function () { $(this).addClass("expanded"); });
}
});
});
You can definitely tidy it up a bit to your liking, but that should do what you want.
JS Fiddle Demo
I'm trying to make a mac os like effect on a list, such that the size of list items expand on hover. Here is the fiddle: jsfiddle
The problem is that i cannot make the items pop outside as a horizontal scrollbar appears. I cannot set the parent to overflow: visible because the verticle height is to be of fixed value and must be scrollable. So the effect of list items popping out on hover with verticle scrolling enabled is desired. No horizontal scrollbar is needed.
try this
li {
cursor: pointer;
transition: 0.5s;
background: #d00;
display: block;
text-align:center; /* Make Text Centered */
padding:5px 0px; /* ADD PADDING to TOP AND BOTTOM */
/* ADD TRANSITION */
transition:transform 0.2s ease-in-out 0s;
}
li:hover {
transform: scale(1.4);
}
<!--- ADD overflow-x:hidden; to hide horizontal scroll bar --->
<div style="overflow-y: auto; overflow-x: hidden; width: 100%; height: 100%;">
I am trying to perform a transition (reducing or extending the height of a DIV). I would like to know how to go about altering a specific property (in this case 'height') associated with a specific class involved in the transition before invoking the transition by changing the CSS classname associated with the element using javascript?
So in the example below, I would like to change the 'height' property of '. sboxopen' from 130px to 360px. Then invoking the transition by changing the element's class name - > Object.className = 'sboxopen';
CSS classes:
.sbox{
height: 0px;
transition: height 1s ease-out;
overflow: hidden;
}
.sboxopen{
height: 130px;
transition: height 1s ease-out;
overflow: hidden;
}
TRANSISTION USING JAVASCRIPT:
Object.className = 'sbox';
or
Object.className = 'sboxopen';
If I cannot change the property of the classes, how do I go about creating a new CSS class dynamically using javascript so that I can incorporate the desired 'height' property for my desired transition?
I don't know what triggers your animation, but let's say it's a click on each of the .sbox elements.
As you can't change the CSS, you can instead use the script to add an inline style height using .style.height.
Here is a snippet:
var sboxes = document.querySelectorAll(".sbox");
sboxes.forEach(function(box, index){
box.onclick = function(){
box.style.height = "360px";
box.className = 'sboxopen';
}
})
.sbox {
height: 0px;
transition: height 1s ease-out;
overflow: hidden;
border: 8px solid gray; /* Added for better visibility */
}
.sboxopen {
height: 130px;
transition: height 1s ease-out;
overflow: hidden;
border: 8px solid gray; /* Added for better visibility */
}
<div class='sbox'>Box 1</div>
<br>
<div class='sbox'>Box 2</div>
<br>
<div class='sbox'>Box 3</div>
⋅
⋅
⋅
Then, we can imagine using custom heights from a custom attribute, for each of the .sbox:
var sboxes = document.querySelectorAll(".sbox");
sboxes.forEach(function(box, index){
box.onclick = function(){
box.style.height = box.getAttribute('myHeight');
box.className = 'sboxopen';
}
})
.sbox {
height: 0px;
transition: height 1s ease-out;
overflow: hidden;
border: 8px solid gray; /* Added for better visibility */
}
.sboxopen {
height: 130px;
transition: height 1s ease-out;
overflow: hidden;
border: 8px solid gray; /* Added for better visibility */
}
<div class='sbox' myHeight='30px'>Box 1</div>
<br>
<div class='sbox' myHeight='60px'>Box 2</div>
<br>
<div class='sbox' myHeight='360px'>Box 3</div>
Feel free to comment if any.
Hope it helps.
Borrowing from a number of examples I created a bootstrap navbar that is affixed to the top of the page, upon scrolling the navbar plus logo image shrink from 100 px to 50 px in height, working perfectly on a desktop pc, normal width browser.
With a smaller mobile device less than 767px I set the parameter to enable the hamburger menu and simple bootstrap dropdown menu.
With the browser very narrow or on a small device if you first access the page and are at the very top you click on the hamburger icon and the menu appears at about 50 px which is in the middle of the height of the logo (100px tall). Within a fraction of a second it jumps to under the logo at 100px where it should. It is this awkward short-lived behavior that I wish to eliminate. It also happens when you collapse the menu. Otherwise it works as planned.
My javascript:
$(window).scroll(function() {
if ($(document).scrollTop() > 50) {
$('img').addClass('shrink');
$('nav').addClass('shrink');
} else {
$('img').removeClass('shrink');
$('nav').removeClass('shrink');
}
});
The relevant CSS:
body {
padding-top: 100px;
}
.navbar {
min-height: 101px; /* to get the 100px tall image contained within navbar */
}
.navbar.shrink {
min-height: 51px;
background: white;
-webkit-transition: all 0.5s ease;
transition: all 0.5s ease;
}
img {
max-height: 100px;
-webkit-transition: all 0.4s ease;
transition: all 0.4s ease;
}
img.shrink {
max-height: 50px;
-webkit-transition: all 0.5s ease;
transition: all 0.5s ease;
}
/* adjust top position of menu on small device due to larger logo */
#media (max-width: 767px) {
.collapse { margin-top: 50px; }
nav.navbar.shrink .collapse {
margin-top: 0px;
-webkit-transition: all 0.8s ease;
transition: all 0.8s ease;
}
}
See demo:
http://www.dottedi.biz/demo/code/public/navbars/shrinking-navbar+logo-scroll.html
you are targeting wrong selector here
instead
.collapse {
margin-top: 50px;
}
in your media query, apply
.navbar:not(.shrink) .navbar-collapse {
margin-top: 50px;
}
and this will work for you
see attached img https://i.stack.imgur.com/uAVQr.jpg
I want to make animation using angular-animate. My css rules is:
.expanded {
transition: all ease 0.5s;
overflow: hidden;
}
.expanded.ng-hide {
height: 0px;
}
If I add, for example, height: 100px to .expanded class, then everything works fine. But how to make it works without height definition? I need this, because the content of .expanded container might be different.
use * as auto,
example :
state('in', style({
overflow: 'hidden',
height: '*',
width: '300px'
})),
Documentation
kirill.buga's post helped me out so after reading this post and some others I made some modification to kirill.buga's post. I got rid of the container height since it was supposed to be auto, slowed down the transition and then hid the overflow so that when the div collapsed, the content inside the div would no longer be visible.
#container {
max-height: 20px;
background: red;
overflow:hidden;
transition: max-height 2s ease-in;
}
#container:hover {
max-height: 800px;
}
plunker example
It's not possible to animate height to 'auto' in CSS (neither in angularJS). You can try to play with max-height instead. There are some impacts of that, but at least you can try. So animate not height from 0 to auto, but max-height. You can set max-height a much bigger than the height you need and that would work.
#container {
max-height: 0;
height: 100px;
background: red;
transition: max-height .3s ease-in;
}
#container:hover {
max-height: 500px;
}
<div id="container">
Hover me
</div>