CSS - Div does not follow animated parent element - html

I'm trying to have a block of text overlay an animated (keyframed) image.
So far, I have tried combinations of display attributes such as inline-block with no luck. I have also attempted to play around with the positions, setting both the heading and the image to relative and absolute.
I would like the heading text (h4) to follow the animated image behind it.
html {
overflow: hidden;
}
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
vertical-align: bottom;
}
h4 {
position: absolute;
background-color: red;
width: 128px;
display: inline-block;
color: white;
font-size: 24px;
}
.transactionBG {
position: absolute;
left: 0;
overflow: hidden;
}
.transaction {
width: 64px;
height: 64px;
position: absolute;
animation: upDown 1.5s alternate infinite ease-in-out;
}
#keyframes upDown {
to {
transform: translateY(100px);
}
}
<div class="transactionBG" style="top: 10%;left: 50%;width: 128px;height: 278px;">
<img class="transaction" src="https://seeklogo.com/images/I/instagram-circle-logo-E285122AB7-seeklogo.com.png" style="width: 102.4px; height: 102.4px;">
<h4>test</h4>
</div>
Current State Demo: http://jsfiddle.net/4huj31fb/2/

you gave the animation to the image only. move this line :
animation: upDown 1.5s alternate infinite ease-in-out;
to the .transactionBG selector
html {
overflow: hidden;
}
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
vertical-align: bottom;
}
h4 {
position: absolute;
background-color: red;
width: 128px;
display: inline-block;
color: white;
font-size: 24px;
}
.transactionBG {
position: absolute;
left: 0;
overflow: hidden;
animation: upDown 1.5s alternate infinite ease-in-out;
}
.transaction {
width: 64px;
height: 64px;
position: absolute;
}
#keyframes upDown {
to {
transform: translateY(100px);
}
}
<div class="transactionBG" style="top: 10%;left: 50%;width: 128px;height: 278px;">
<img class="transaction" src="https://seeklogo.com/images/I/instagram-circle-logo-E285122AB7-seeklogo.com.png" style="width: 102.4px; height: 102.4px;">
<h4>test</h4>
</div>

transactionBG is the parent of h4. So you have to add the animation to transactionBG
.transactionBG {
position: absolute;
left: 0;
overflow: hidden;
animation: upDown 1.5s alternate infinite ease-in-out;
}

Related

Cannot animate width of an element using CSS Animation

I am using animations in CSS but it is not working. If I check in the inspect menu it is showing invalid syntax even though the syntax is normal. I have other two animations but they are working fine.
Only a particular animation in which I am trying to adjust the width isn't working.
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
.bg-div {
background: url(imgs/sky.png);
height: 100vh;
background-size: 79% 792px;
background-position-y: -332px;
width: 900vw;
}
.sea-div {
background: url(imgs/sea.jpg);
height: 37vh;
position: absolute;
bottom: 0;
width: 900vw;
background-size: 10% 403px;
}
.bg-ani-class {
animation: seaMove linear infinite 3s;
background-repeat: repeat-x;
}
.sea-ani-class {
animation: seaMove linear infinite 6s;
background-repeat: repeat-x;
}
.obst-ani-class {
animation: obstMove linear 5s;
}
.mountain-div {
position: absolute;
top: 10vh;
/* width: 18vh; */
/* height: 20vh; */
left: 108vw;
}
.mountain-div img {
width: 148vh;
}
.hanuman-div {
position: absolute;
top: 28vh;
left: 3vw;
}
.hanuman-div img {
width: 20vw;
}
#gada {
position: absolute;
left: 0;
/* top: 56px; */
transition: 0.1s ease all;
}
.gada-rot {
left: 8vw !important;
transform: rotate(180deg);
top: -22px !important;
}
.laser {
position: absolute;
transform: rotateZ(189deg);
/* top: -14vh; */
left: 282px;
/* width: 45vw !important; */
width: 0% !important;
/* transition: 0.4s ease-out; */
animation: laserAnimation infinite 3s;
}
.dragon-1-div {}
.dragon-2-div {}
/* Animations */
/* These 2 Animations are working */
#keyframes seaMove {
100% {
transform: translateX(-500vw);
}
}
#keyframes obstMove {
0% {
left: 108vw;
}
100% {
left: -100vw;
}
}
/* This animation isn't working */
#keyframes laserAnimation {
from {
width: 0 !important;
}
to {
width: 45vw !important;
}
}
<div class="bg-div bg-ani-class"></div>
<div class="sea-div sea-ani-class"></div>
<div class="hanuman-div">
<img src="imgs/hanuman.png" alt="">
<img src="imgs/gada.png" alt="" id="gada">
<img src="imgs/laserbeam.png" alt="" class="laser">
</div>
<div class="mountain-div">
<img src="imgs/mountain.png" alt="">
</div>
<div class="dragon-1-div"></div>
<div class="dragon-2-div"></div>
It's generally not a good idea to animate width and height. Always try to use composite animations e.g. opacity, transforms. To achieve width animation use scale transform.
Here is a laser show for you:
body {
overflow: hidden;
}
.laser {
position: absolute;
left: 0;
top: 50%;
height: 10px;
width: 100%;
background: #d7272b;
animation: laserAnimation 2s ease-out infinite;
}
.greenLaser {
position: absolute;
left: 0;
top: 0;
height: 10px;
width: 100%;
background: #0063d5;
animation: laserAnimation 2s ease-out infinite;
}
.blueLaser {
position: absolute;
bottom: 0;
left: 0;
height: 10px;
width: 100%;
background: #00d53b;
animation: laserAnimation 2s ease-out infinite;
}
#keyframes laserAnimation {
from {
transform: scaleX(0);
}
to {
transform: scaleX(1);
}
}
<div class="laser">
</div>
<div class="greenLaser">
</div>
<div class="blueLaser">
</div>

Hover animation "jumps" while hovering out

I want to achive a simple animation on hover in css, but while hovering off, the animation jumps and makes it look silly. Is there a way to avoid that?
My wish would be that it is colapsing the same way it originaly transformed.
Codepen: https://codepen.io/misah/pen/abzRXvL
.item {
width: 20%;
height: 0;
padding-top: 20%;
background-color: blue;
position: relative;
transition: 800ms;
}
.item::after {
position: absolute;
bottom: 0;
height: 30%;
width: 100%;
content: "";
background-color: grey;
transition: transform 800ms ease-in-out;
}
.item:hover::after {
transform: scaleY(2);
transform-origin: bottom;
}
<div class="item">
</div>
This happens because the transform-origin: bottom; is only applied when the item is hovered. When not hovered it falls back to the default - center. Move the rule to the declaration of the ::after.
.item {
width: 20%;
height: 0;
padding-top: 20%;
background-color: blue;
position: relative;
transition: 800ms;
}
.item::after {
position: absolute;
bottom: 0;
height: 30%;
width: 100%;
content: "";
background-color: grey;
transition: transform 800ms ease-in-out;
transform-origin: bottom;
}
.item:hover::after {
transform: scaleY(2);
}
<div class="item"></div>

How to fix flickering from css keyframe animation

I am trying to stagger the opacity (fade) of three boxes via an infinite keyframe animation and the animation-delay property.
I am getting some unexpected behavior, as the third box fades away, it suddenly reappears faintly ("flickers") before the animation starts again. I am experiencing this across browsers.
I would like to use pseudo elements if possible, is there a known fix for this keyframe bug?
HTML
<div class="container">
<div class="child">
<div></div>
</div>
</div>
SCSS
.container {
position: fixed;
left: 150px;
top: 50px;
.child {
position: absolute;
animation:mymove 1s infinite;
&::before{
display: block;
position: absolute;
width: 25px;
height: 25px;
background-color: red;
content: "";
right: 40px;
animation: inherit;
animation-delay: .15s;
}
div {
width: 25px;
height: 25px;
background-color: red;
animation: inherit;
animation-delay: .30s;
}
&::after{
display: block;
position: absolute;
width: 25px;
height: 25px;
background-color: red;
content: "";
left: 40px;
bottom: 0px;
animation: inherit;
animation-delay: .45s;
}
}
}
#keyframes mymove {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
JS Fiddle
The reason they flicker is because you have set an animation on their parent, the child.
And since its animation doesn't have a delay, it starts before its children, but will then be overridden by them as soon as their delay has passed, hence one can see a quick flash.
The best way to avoid any future issue with this, is to remove the animation from the child
.container {
position: fixed;
left: 150px;
top: 50px;
}
.container .child {
position: absolute;
}
.container .child::before {
display: block;
position: absolute;
width: 25px;
height: 25px;
background-color: red;
content: "";
right: 40px;
animation: mymove 1s infinite;
animation-delay: 0.15s;
}
.container .child div {
width: 25px;
height: 25px;
background-color: red;
animation: mymove 1s infinite;
animation-delay: 0.3s;
}
.container .child::after {
display: block;
position: absolute;
width: 25px;
height: 25px;
background-color: red;
content: "";
left: 40px;
bottom: 0px;
animation: mymove 1s infinite;
animation-delay: 0.45s;
}
#keyframes mymove {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<div class="container">
<div class="child">
<div></div>
</div>
</div>

CSS animations transitioning from behind other elements broken in Firefox

Here's a simple example of what I mean.
HTML
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
CSS
.main-container {
width: 100%;
height: 200px;
margin: 250px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
100% {
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
transform: translateY(20px);
}
}
-
If you view in Chrome, both black bars slide out perfectly. The one transitioning from behind, and the one in front.
If you view it in Firefox, the bar transitioning from behind is broken. It sometimes works, but mostly it ignores the slide animation and just appears at the end of the animation duration.
I've re-created this a number of times and it seems that items that transition from behind another element are broken in firefox.
I've tried using -moz- which doesn't work. IS there anything else you can think of?
I've tried it without the absolute positioning, with z-indexs. and nothing seems to work.
EDIT ----
I appreciate work-around ideas, but I'd really like to know the route cause of this if anyone knows?
Thanks very much.
It seems Firefox is inconsistent when animate the transform property, and I can't say why (yet), most likely a bug though.
Here is 2 workarounds to achieve the same effect
.main-container {
width: 100%;
height: 200px;
margin: 50px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
0% {
transform: translateY(-1px);
}
0.1% {
transform: translateY(0px);
}
100% {
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
transform: translateY(20px);
}
}
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
.main-container {
width: 100%;
height: 200px;
margin: 50px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
}
.ht-tx2 {
width: 100%;
height: 0px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
}
#keyframes test-ani1 {
100% {
top: -20px;
}
}
#keyframes test-ani2 {
100% {
height: 20px;
bottom: -20px;
}
}
<div class="main-container">
<div class="ht-tx1"></div>
<div class="headtest"></div>
<div class="ht-tx2"></div>
</div>
The solution relies on the z-index property of your elements: if you don't specify it the elements lay out one on top of the others, following the flow of the HTML document, when their "position" is set to "absolute". So "ht-txt1" is underneath "headtest" and "ht-tx2" is on top of "headtest".
To correct this "ht-tx1" and "ht-tx2" should take a "z-index" value of -1, so they are hidden underneath "headtest".
As for FF compatibility you need to prefix your "transform" effect with -moz-, check http://caniuse.com/#feat=transforms2d for more details.
Here's the CSS style code:
.main-container {
width: 100%;
height: 200px;
margin: 250px 0 0 0;
position: relative;
background-color: yellow;
}
.headtest {
font-family: 'quicksand', helvetica;
background-color: #a2aba2;
width: 100%;
height: 200px;
position: absolute;
top: 0;
right: 0;
}
.ht-tx1 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani1 2s forwards;
position: absolute;
top: 0;
right: 0;
z-index: -1;
}
.ht-tx2 {
width: 100%;
height: 20px;
text-align: center;
background-color: #000;
animation: test-ani2 2s forwards;
position: absolute;
bottom: 0;
right: 0;
z-index: -1;
}
#keyframes test-ani1 {
100% {
-ms-transform: translateY(-20px);
-webkit-transform: translateY(-20px);
-moz-transform: translateY(-20px);
transform: translateY(-20px);
}
}
#keyframes test-ani2 {
100% {
-ms-transform: translateY(20px);
-webkit-transform: translateY(20px);
-moz-transform: translateY(20px);
transform: translateY(20px);
}
}

Set position of text after slide-in

I have the following code to have text slide in, but after the slide is over the text moves to the left. How would I make the text stay where it is when the slide is over?
<style>
div.slide-left {
width: 100%;
overflow: hidden;
}
div.slide-left p {
animation: slide-left 5s;
font-size: 300%;
color: #000;
position: absolute;
top: 50px;
}
#keyframes slide-left {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 50%;
width: 100%;
}
}
</style>
<div class="slide-left">
<p>hello</p>
</div>
You need to use animation-fill-mode: forwards to preserve the last animation state. Since there was no animation-fill-mode specified, it used the default properties of the class name, i.e. resets/jumps to the top value specified after the animation is completed.
<style>
div.slide-left {
width: 100%;
overflow: hidden;
}
div.slide-left p {
animation: slide-left 5s;
font-size: 300%;
color: #000;
position: absolute;
top: 50px;
animation-fill-mode: forwards;
}
#keyframes slide-left {
from {
margin-left: 100%;
width: 300%;
}
to {
margin-left: 50%;
width: 100%;
}
}
</style>
<div class="slide-left">
<p>hello</p>
</div>