I have successfully animated a div using #keyframes but I need to alter properties of child elements of that div at the same time. Is there a way to address a child element from within a keyframe?
HTML
<div class="layoutBlocks" id="layoutBlock1">
<div class="Wrappers">
<div class="transparentBG"> <!--semi=transparent underlay-->
</div>
</div>
<div class="Wrappers">
<div class="articles" id="article1">
<table>
<tr><th>heading</th></tr>
<tr><td>article</td></tr>
</table>
</div>
</div>
CSS
#layoutBlock1 {
left: 0%;
top: 0%;
width: 49.75%;
height: 49.25%;
-webkit-animation: LlB1 1s;
animation: LlB1 1s;
}
#-webkit-keyframes LlB1 {
0% {width:50%; height:50%; z-index: 1;}
100% {width:100%; height:100%; z-index: 100;}
}
#keyframes LlB1 {
0% {width:50; height:50%; z-index: 1;}
100% {width:100%; height:100%; z-index: 100;}
}
(All the extra wrappers are to make the semi-transparent background and rounded corners work on Android.)
(I think transforms might be easier than keyframes here but my ultimate goal is to add a few more effects down the line.)
As my keyframe moves & resizes the layoutBlock1 div, I want to make the semi-transparent underlay opaque, but since it's a child element, I can't figure out how to address it. Is this possible?
Addressing the child node from the keyframe is not possible.
But, there might be a few hacks:
Having another animation with the same duration, but with animation and settings for the child node
Another way to achieve this is to use some of the JS libraries for animation. Eg.: https://animejs.com
You cannot change a child element from within a keyframe unless that keyframe has been called on the element. You could have another animation going on, and you could assign that to the child element and set it to have the same duration.
If you want the same animation to happen to the child element, you could just call the keyframe on the child element.
Related
I am using css transitions to lay out a bunch of divs on top of each other. At any point, one of the divs may collapse. And all of the divs below it are supposed to move up to fill its spot.
Here is a codepen that describes the situation.
The css I am using is the following:
div {
height: 100px;
width: 100px;
margin: 15px;
}
.top {
background-color: red;
transform-origin: top;
animation: move 2s infinite;
}
.bottom {
background-color: blue;
}
#keyframes move {
0% {
transform: rotateX(0deg);
}
50% {
transform: rotateX(90deg);
}
}
With this, the top div will expand and contract. I want the divs below it to move up as the top one collapses.
If I switch transform for height, like this:
#keyframes move {
0% {
height 0;
}
50% {
height: 100px;
}
}
The bottom divs do move, but this is not a good solution for me because in the actual application, each div has a dynamically calculated size.
How can the bottom divs move smoothly with the top div?
With transform you won't be able to do that, as when an element is transformed, the surrounding elements won't see any change in the DOM, as DOM-wise nothing have happened.
What you can do to optimize it all, is to prepare the browser that the height will change, with the property will-change: height
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/will-change
This new CSS property aim's to do what transform does, make smoother and more optimized animations.
Do note though:
will-change is intended to be used as a last resort, in
order to try to deal with existing performance problems. It should not
be used to anticipate performance problems.
Another possible solution (read hack), is to trick the browser to use GPU instead of CPU, shown in this answer (see its p.1):
CSS `will-change` - how to use it, how it works
Updated
In case of the height is auto, or similar, this will work with the max-height trick, and here is a couple of answers of mine, showing how-to:
CSS Animation on max-height change
Can't use the same animation in reverse for class toggle
CSS transition auto width
And the last resort, if none of the above is applicable, is to use a small script and either create a styles dynamically (links below), or set them inline.
Dynamically styling pseudo-elements using jQuery or Javascript
How to prevent css from getting converted to inline css
Image Example for Reference
Making a website and really getting into CSS3 animations for the first time. Ideally, I want those two gray borders animating outwards from the logo in the center. I currently have them animating but they only animate left to right. They are done by having a div on both sides with a border-bottom. Because of this, I thought animating the div's width from 0 to 100 was the best approach. It's working great... just not in the right direction lol.
Note: the CSS is in stylus so there isn't normal syntax.
Animation Keyframes:
#keyframes widthExpand {
0% {
width: 0%;
}
100% {
width: 100%;
}
}
Assigning Class:
.fadewidth
animation-name widthExpand, fadeIn
animation-duration 2000ms, 2000ms
transition-timing-function ease-in
animation-direction normal
I've tried different animation directions and having the 0% start at width 100% then reversing it, hoping it would fix it. Always animates left to right no matter what I do.
It's also position horizontally centered with flexbox. Here's the HTML:
<div id="centernav" class="">
<div class="left-links">
<div class="top-links fadewidth">
</div>
<div class="bottom-links">
</div>
</div>
<img src="assets/images/cv-logo-yellow-nodate.svg" id="cvlogo-main" class="fadeindown">
<div class="right-links">
<div class="top-links fadewidth">
</div>
<div class="bottom-links">
</div>
</div>
</div>
CSS: Stylus
.left-links,
.right-links
width 30%
.top-links
border-bottom 1px solid #fafafa
#centernav
display flex
align-items center
justify-content center
flex-direction row
height 85%
color nardo
& h1
font-family heading
color gold
font-size 6.5rem
font-weight 100
margin-bottom -22px
& img
margin 0 50px
I feel like this is probably something really simple I'm missing in maybe the keyframe declaration. Thanks for your help!
Figured it out. Since they are positioned center, the animation will force outwards if you give them an absolute position. I gave the parent div a relative position and the inner divs an absolute position.
Note: you have to give it an absolute position within the keyframe declaration. I tried applying an absolute position in the CSS for the class but it created a weird effect once the animation sequence was done.
I simply did the following:
#keyframes widthExpand {
from {
width: 0%;
position: absolute;
}
to {
width: 100%;
position: absolute;
}
}
If there's a better way of doing what I'm about to ask, please let me know, but so far this is the best I could come up with
I want to have a set of divs that contain a sliding div inside of them. The sliding divs would contain content pulled from the latest post. So they might not always be exactly the same height.
The start position would be to have the title showing, then have the whole div show when the parent is hovered over.
The problem I'm having with only using bottom position is that when the screen gets too thin, more than just the title shows up. Using top, I do lose some of the title, but I'm willing to sacrifice that.
So instead I decided to use both top and bottom, and just flip where auto is in order to make the complete div show. (I don't want to have the sliding div to be the same height as the containing div)
When I do this though, the transition doesn't work. I tried using top, bottom, and all in the transition, but it's all the same result - no transition.
Can someone please explain a) Why this isn't working b) what would make it work without going to jQuery.
HTML:
<div class="innerLeftPosts">
<div class="mainPostHome">
<div class="postSlideCover">
<h3>Hello this is a test</h3>
<p>This is some test content that would go in here and take up some space</p>
</div>
</div>
<div class="secondaryPostHome">
<div class="postSlideCover">
<h3>Hello this is a test</h3>
<p>This is some test content that would go in here and take up some space</p>
</div>
</div>
</div>
CSS:
.postSlideCover{
width:calc(100% - 20px);
height:auto;
position:absolute;
transition:all 0.4s ease-out;
-webkit-transition:all 0.4s ease-out;
}
.mainPostHome .postSlideCover{
top:83%;
bottom:auto;
}
.mainPostHome:hover .postSlideCover{
top:auto;
bottom:0;
}
Fiddle for full and visual example: https://jsfiddle.net/60nxpfs8/
Here:
.postSlideCover{
width:calc(100% - 20px);
height:auto;
position:absolute;
transition:all 0.4s ease-out;
-webkit-transition:all 0.4s ease-out;
bottom: 0;
}
.mainPostHome .postSlideCover{
transform: translateY(60%);
}
.mainPostHome:hover .postSlideCover{
transform: translateY(0);
}
With a JSFiddle
We can use the transform property translateY to use the height of the element as the metric which we move it (100% relates to 100% of the element height). This has the added benefit of being able to use hardware acceleration (as opposed to software) to animate.
To witness the bug, hover on the right-side of the overlay box here (don't move your mouse even 1px after hovering):
http://jsfiddle.net/V99rf/
<style>
.container, .hoverMover {width:100px; height:100px; background:rgba(0,0,0,.2);}
.container {position:relative;}
.hoverMover {position:absolute; top:0; left:50px;}
.container:hover .hoverMover {background:green; left:0;}
.trans {-webkit-transition: all 1s ease-in-out; transition: all 1s ease-in-out;}
</style>
<div class="container">
<div class="hoverMover trans">
</div>
</div>
Notice that even after the dom element moves to the left, it remains green with a ":hover" being set. This gets unset as soon as you move the mouse. How do I make it unset when the dom element moves from under the mouse, even if the mouse isn't moved?
A recursive javascript timeout would be unsatisfying, but may be the only way...?
This is only possible with an event, so you will need some sort of iterative loop to accomplish what you are looking for.
I'm trying to create images that will drop out in any direction when hovered over, using just HTML and CSS.
What it's meant to look like:
not hovered over: a section of the image is displayed
hover: the remaining section of the image slides out (in a CSS specified direction)
What I've tried doing:
a <div> to hold a background-image that cuts off at a certain height and slides out using css animations on hover
<html>
<body>
<style>
#-webkit-keyframes resize {
0% {
}
100% {
height: 446px;
}
}
#pic {
height: 85px;
width: 500px;
background-image: url(http://images5.fanpop.com/image/photos/31400000/Cow-cows-31450227-500-446.jpg);
}
#pic:hover {
-webkit-animation-name: resize;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-delay: 0.5s;
-webkit-animation-direction: normal;
-webkit-animation-fill-mode: forwards;
}
</style>
<div id="pic"></div>
<p class="center">Hover over me</p>
</body>
</html>
The problem with this approach is that this moves other content out of the way which I don't want.
This approach also doesn't work if I want to slide the image to the left or the right or upwards.
Any suggestions?
I put your code on fiddle an worked out a few examples for you:
move down: http://jsfiddle.net/rcCeP/
move up: http://jsfiddle.net/rcCeP/1/
move right: http://jsfiddle.net/rcCeP/2/
move left: http://jsfiddle.net/rcCeP/3/
for fun:
from center: http://jsfiddle.net/rcCeP/4/
in the document flow: http://jsfiddle.net/rcCeP/5/ (note the xtra wrapper with relative positioning)
how i would do it, with transitions in stead of animations, to work in two directions and degrade gracefully on older browsers: http://jsfiddle.net/rcCeP/6/
I could keep going on like this all day, this is real fun...
The key to prevent the content from getting pushed is making the picture position absolute. This will lift it out of the flow of the document. Then the direction just becomes a matter of playing around with the position and backround-position values.
Hope this helps!