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!
Related
Fiddle A:
I have a gallery of images (there are 4 right now) as shown here in this JSFiddle (lets call as Fiddle A)
in which every single image fades out after 3s second and there is transition delay of 800ms.
I have used JS to make the animation work. In JS, I have used the following constants in my JS.
transitionDuration => is the delay (white flash which we see) which happens on moving from one image to another.
transitionDelay => is the presenation time of an image (meaning the time span for which the image stay at their place).
totalDelay => is only for one image.
Fiddle B:
I also have another gallery of images as shown in this JSFiddle (let's call as Fiddle B) in which a CSS animation is going on.
Presentation time of one image in the fiddle is 3 seconds, and then it moves to another images.
Problem Statement:
I am wondering what changes I need to make in Fiddle B so that it looks like Fiddle A. In Fiddle B there is no transitionDuration. Is there a way we can add a transitionDuration (white flash which we can
see on moving from one image to another)?
In Fiddle B, I have used the following CSS:
a:nth-of-type(4), .featured-block a:nth-of-type(5), .featured-block a:nth-of-type(6) {
position: absolute;
animation: 9s infinite ease-in-out cf4FadeInOut;
opacity: 0;
z-index:1;
}
Adjusting opacity in keyframes to achieve transition duration works, which you have implemented.
Remove opacity: 1 and opacity: 0 so that it becomes
.featured-block a { display: inline-block; }
a:nth-of-type(4), .featured-block a:nth-of-type(5), .featured-block a:nth-of-type(6) {
position: absolute;
animation: 3s infinite ease-in-out cf4FadeInOut;
z-index:1;
}
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
I want to flip an image with a rotation animation when hovering over it (see the code below). When hovering over the image, it rotates around its x-axis for one second (and back when the mouse leaves the image).
The animation works as expected in Firefox and Safari. However, Chrome sometimes skips the animation and flips the image instantly. I don't know how to reliably reproduce the problem because it usually works a few times before the animation is skipped. I have recorded a video, so you can see what I mean: https://www.youtube.com/watch?v=bpgi46F_5RU
Is something wrong with this CSS? I first suspected that it's caused by the rotation angle but the same problem occurs even with other types of animations.
.flippable-container {
float: left;
perspective: 1000px;
}
.flippable {
transition: transform 1s;
}
.flippable-container:hover .flippable {
transform: rotateX(180deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="flippable-container">
<img class="flippable" src="http://lorempixel.com/200/200/food"/>
</div>
Edit: As commented by TylerH, it looks like a bug in Chrome. I see the same problem in this well-known tutorial by David Walsh: http://davidwalsh.name/css-flip. Video: https://www.youtube.com/watch?v=o_TViH4AmZ8. The issue must be related to mouse interaction because the 'Toggle Flip' button below the image works fine.
I have fixed this by putting a z-index and position:relative on all the flippable items. I have no idea why that would affect it but it seems to have done the job.
example: http://jsfiddle.net/L0duLu3c/2/
.flippable-container {
float: left;
perspective: 1000px;
}
.flippable {
transition: 0.6s;
z-index:10;
position:relative;
transform: rotateX(0deg);
}
.flippable-container:hover .flippable {
transform: rotateX(180deg);
z-index:20;
}
I am trying to delay a CSS transition, but it seems not to be working. Here is what I want to happen:
Start the video
Move the mouse pointer out of the video
The control bar shrinks, but the play-progress gets larger.
Move mouse pointer back in video, the control bar returns to normal.
As you can see in the CodePen pen, the play-progress bar gets larger before I want it to: http://codepen.io/mboles/pen/mJeJOO
Here is the CSS I am currently using:
#myPlayerID.vjs-has-started.vjs-user-inactive .vjs-progress-control {
-webkit-transform: translateY(-25px);
}
#myPlayerID.vjs-has-started.vjs-user-inactive .vjs-play-progress {
-transition-delay: height 3s;
height: 10px;
}
I have tried to change the order of the transition delay and height, but that did not solve the issue.
Many thanks-
Matt
It turns out with transition-delay you cannot put the property with the delay, it must be explicitly stated using transition-property. So the solution is:
#myPlayerID.vjs-has-started.vjs-user-inactive .vjs-play-progress {
height: 10px;
transition-property: height;
-transition-delay: 3s;
-webkit-transition-delay: 3s;
}
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.