Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Animation isn't working

I made 2 animation, the first one is working properly while the second isn't. Although both are almost identical, it just won't work. I would appreciate any help!

#menuAnim1 {
  height: 8px;
  background: black;
  position: relative;
  top: 50px;
  animation: widthStretch 4s ease-out;
  animation-fill-mode: forwards;
}

#menuAnim2 {
  width: 8px;
  background: black;
  position: relative;
  left: 50px;
  animation: heightStretch 4s ease-out;
  animation-fill-mode: forwards;
}

@keyframes widthStretch {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

@keyframes heightStretch {
  from {
    height: 0;
  }
  to {
    height: 100%;
  }
}
<div id='menuAnim1'></div>
<div id='menuAnim2'></div>

You could see what I mean now. The second one should be increasing in it's height, then cross the first one, but it's not.

like image 569
AzDeveloper Avatar asked Jan 29 '18 07:01

AzDeveloper


People also ask

How do you trigger an animation in CSS?

To trigger CSS animations in JavaScript, we just add the class that is set to animate the keyframes in CSS. We add the @keyframes property with the animation we want to animate. It'll animate from the from styles to the to styles.

How do you reset an animation in CSS?

To restart animation in CSS3 and JavaScript, we can get the offsetHeight property to trigger reflow. function resetAnimation() { const el = document. getElementById("animated"); el. style.

How do CSS animations work?

CSS animations make it possible to animate transitions from one CSS style configuration to another. Animations consist of two components, a style describing the CSS animation and a set of keyframes that indicate the start and end states of the animation's style, as well as possible intermediate waypoints.

Do CSS animations work on all browsers?

CSS Animation element is supported by all Microsoft Edge browser.


3 Answers

Both your elements are using percentage values for the height/width in their animation and these values will be calculated relatively to their container (containing block) which is the body.

By default, the body is a block level element and its width will not depend on its content so percentage width on the animated divs will work fine BUT since the height of the body depend on its content (which is the case of all the elements) percentage height on the animated div won't work and fail to auto.

more details here: https://www.w3.org/TR/CSS21/visudet.html


You have to explicitely specify a height for the body to make the animation working. You can try a fixed height and your element will grow from 0 to this height.

body {
  height:100px;
}
#menuAnim1 {
  height: 8px;
  background: black;
  position: relative;
  top: 50px;
  animation: widthStretch 4s ease-out;
  animation-fill-mode: forwards;
}

#menuAnim2 {
  width: 8px;
  background: black;
  position: relative;
  left: 50px;
  animation: heightStretch 4s ease-out;
  animation-fill-mode: forwards;
}

@keyframes widthStretch {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

@keyframes heightStretch {
  from {
    height: 0;
  }
  to {
    height: 100%;
  }
}
<div id='menuAnim1'></div>
<div id='menuAnim2'></div>

You can also specify height:100% on the body BUT this will also not work because the same logic will apply to body and its containing block (html) that has no height specified, so you have also to add height:100% to html. The last one will work because the containing block of html is the viewport where the dimension (height/width) are known and doesn't depend on the content.

body,html {
  height:100%;
}
#menuAnim1 {
  height: 8px;
  background: black;
  position: relative;
  top: 50px;
  animation: widthStretch 4s ease-out;
  animation-fill-mode: forwards;
}

#menuAnim2 {
  width: 8px;
  background: black;
  position: relative;
  left: 50px;
  animation: heightStretch 4s ease-out;
  animation-fill-mode: forwards;
}

@keyframes widthStretch {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

@keyframes heightStretch {
  from {
    height: 0;
  }
  to {
    height: 100%;
  }
}
<div id='menuAnim1'></div>
<div id='menuAnim2'></div>

Why using position:absolute works ?

Because adding position:absolute will make the element positioned relatively to the first non-static parent element and since there is no posisitioned parent element it will be positioned relatively to the viewport and percetange height behave differently with positon:absolute

Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'

This is logical since a position:absolute element will not contribute on the height of its containing block since it's removed from the flow.

Now the viewport has a height and width that are simply the height/width of your browser so height:100% will be all the screen height.

#menuAnim1 {
  height: 8px;
  background: black;
  position: relative;
  top: 50px;
  animation: widthStretch 4s ease-out;
  animation-fill-mode: forwards;
}

#menuAnim2 {
  width: 8px;
  background: black;
  position: absolute;
  left: 50px;
  animation: heightStretch 4s ease-out;
  animation-fill-mode: forwards;
}

@keyframes widthStretch {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

@keyframes heightStretch {
  from {
    height: 0;
  }
  to {
    height: 100%;
  }
}
<div id='menuAnim1'></div>
<div id='menuAnim2'></div>

Try to make your body position:relative. Your element will now be positionned relatively to the body and you will see that the animation will also work but with a strange reuslt.

Like I said before height:100% will refer to the containing block and in this case its the body and the height of the body is filled with the other element and it's exactly 8px.

body {
  position:relative;
}

#menuAnim1 {
  height: 8px;
  background: black;
  position: relative;
  top: 50px;
  animation: widthStretch 4s ease-out;
  animation-fill-mode: forwards;
}

#menuAnim2 {
  width: 8px;
  background: black;
  position: absolute;
  left: 50px;
  animation: heightStretch 4s ease-out;
  animation-fill-mode: forwards;
}

@keyframes widthStretch {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

@keyframes heightStretch {
  from {
    height: 0;
  }
  to {
    height: 100%;
  }
}
<div id='menuAnim1'></div>
<div id='menuAnim2'></div>
like image 61
Temani Afif Avatar answered Sep 29 '22 08:09

Temani Afif


menuAnim2 css postion needs to change from relative to absolute, Now its working...

<!DOCTYPE html>
<html>
<head>
<style>
#menuAnim1 {
	height: 8px;
	background: black;
	position: relative;
	top: 50px;
	animation: widthStretch 4s ease-out;
	animation-fill-mode: forwards;
}
#menuAnim2 {
	width: 8px;
	background: black;
	position: absolute;
	left: 50px;
	animation: heightStretch 4s ease-out;
	animation-fill-mode: forwards;
}
@keyframes widthStretch {
	from {width:0;}
	to {width:100%;}
}
@keyframes heightStretch {
	from {height:0;}
	to {height:100%;}
}
</style>
<script>
</script>
</head>
<body>
<div id='menuAnim1'></div>
<div id='menuAnim2'></div>
</div>
</body>
</html>
like image 25
Jasbir Avatar answered Sep 29 '22 08:09

Jasbir


Because, in #menuAnim2 the browser didn't have any info about 100% height (Maybe 100vh or 100px or 0px).

So, another solution is add the parent container with a width and height.

<!DOCTYPE html>
<html>
<head>
<style>
#container {
   width: 50vw;
   height: 50vh;
}
#menuAnim1 {
	height: 8px;
	background: black;
	position: relative;
	top: 50px;
	animation: widthStretch 4s ease-out;
	animation-fill-mode: forwards;
}
#menuAnim2 {
	width: 8px;
	background: black;
	position: relative;
	left: 50px;
	animation: heightStretch 4s ease-out;
	animation-fill-mode: forwards;
}
@keyframes widthStretch {
	from {width:0;}
	to {width:100%;}
}
@keyframes heightStretch {
	from {height:0;}
	to {height:100%;}
}
</style>
<script>
</script>
</head>
<body>
<div id='container'>
  <div id='menuAnim1'></div>
  <div id='menuAnim2'></div>
</div>
</body>
</html>
like image 21
Nodtem66 Avatar answered Sep 29 '22 08:09

Nodtem66