I have a div with some images in it. When I move the mouse over one of the images, I want it to grow, when I move the mouse out I want it to shrink again. I know that there isn't a mouseout ore something like that in CSS, so I put the reverse animation into the normal style of the images. Now my problem is, that when I load the site all images do the shrinking animation.
Is there a way to do this only with CSS or do I have to use Javascript?
My HTML:
<div id="picmen">
<img src="/images/b1.png" />
<img src="/images/b2.png" />
<img src="/images/b3.png" />
<img src="/images/b4.png" />
<img src="/images/b5.png" />
<img src="/images/b6.png" />
<img src="/images/b7.png" />
</div>
My CSS:
#picmen img {
float: right;
margin: 3px 1px 3px 1px;
height: 50px;
width: 50px;
animation: shrink 0.5s;
}
#keyframes shrink {
from{ width: 60px; height: 60px; }
to{ width: 50px; height: 50px; }
}
#picmen img:hover {
animation: grow 0.5s;
width: 60px;
height: 60px;
}
#keyframes grow {
from{ width: 50px; height: 50px; }
to{ width: 60px; height: 60px; }
}
Try using:
transition-duration: 0.5s;
instead of creating #keyframe animations.
Your code would look like:
#picmen img {
float: right;
margin: 3px 1px 3px 1px;
height: 50px;
width: 50px;
transition-duration: 0.5s;
}
#picmen img:hover {
transition-duration: 0.5s;
width: 60px;
height: 60px;
}
If you want to add easing, you can use:
transition-timing-function: ease-in-out;
More information about transition css3 can be found on the w3schools website.
See it in action.
Why it works:
When you define and use an #keyframe animation, your code will run the animation every time it is seen.
A browser will read your code like this:
#picmen img{ //define all images inside 'picmen' div
... //all of the basics (float, margin)
height:50px; //set height to 50px (iff no further instructions about height follow)
width:50px; //set width to 50px (iff no further instructions about width follow)
animation: shrink 0.5s; //run an animation called shrink for 0.5 seconds
//every time this state is entered
--run animation called 'shrink'--
#keyframes shrink { //defines 'shrink'
from{ width: 60px; height: 60px; } //redefines starting width and height
to{ width: 50px; height: 50px; } //defines ending width and height
}
--end animation--
} //end image definition
transition, will only make those changes on (as the name suggests) transitions.
The first time your images are loaded, they don't go through any state changes, thus no transition.
Related
I have a container that contains a div inside it. By clicking on that div square, it begins moving and ends up being outside the container.
My problem is that this inner block is being trimmed out really harsh while going beyond the borderline. How could this transition be done more smoothly using CSS means? I want to get an effect when this square disappearing becomes gentle for the eyes.
Maybe I'm supposed to use some kind of an image mask for the main container or a fade effect for the square. I'm not exactly sure how to achieve that behaviour.
Thank you in advance!
Codepan sandbox
.borderline {
position: relative;
text-align: center;
vertical-align: middle;
line-height: 150px;
width: 400px;
height: 150px;
overflow: hidden;
}
.square {
position: absolute;
width: 150px;
height: 150px;
background-color: #0087ff;
}
.square:focus {
transform: translateX(500px);
transition: all 2s;
}
<div class='borderline'>
<div class='square' tabindex="1">Click me</div>
</div>
maybe you could add an animation to your css with opacity like:
.square:focus {
transform: translateX(500px);
transition: all 2s;
animation-name: example;
animation-duration: 1s;
}
#keyframes example {
0% {opacity:1}
50% {opacity:1}
100% {opacity:0}
}
https://codepen.io/anon/pen/rzppON
Im trying to understand CSS Transition - but I cant make it happen. I want to make a line go from 0 to 100% width with a small delay on pageload. I understand that CSs transition needs a trigger, and tried to read up to a jQuery or Vanilla Js solution, but get stuck.
Why is this ot working? Jsfiddle: https://jsfiddle.net/1fzzgnwy/
<div class="container">
<span class="h-line"></span>
</div>
.h-line {
position: absolute;
z-index: -1;
width: 0%;
height: 10px;
right: 0;
background-color: #000;
top: 400px;
transition: right 1.5s linear;
transition-delay: 2s;
}
.h-line.ready {
width: 100%;
background-color: #000;
}
.container {
height:100%;
width:100%;
}
$(function(){
$('.h-line').addClass('ready');
});
In your transition line, you are telling it to transition right, but that doesn't change in the added class. Your width does. So you need to transition the width like transition: width 1.5s linear;: JS Fiddle
And if you want it to expand left to right, remove right: 0: JS Fiddle
In your jsfiddle link (https://jsfiddle.net/1fzzgnwy/) there are some errors.
Here a simplified example of your code that work https://jsfiddle.net/50t3qwmL/ .
.h-line {
position: absolute;
top: 0;
right: 0;
width: 20px;
height: 20px;
background-color: #000;
transition: .3s;
transition-delay: 2s;
}
.h-line.ready {
width: 100%;
}
I have an animation of a box, where it's width increases on hover:
JSFiddle: https://jsfiddle.net/hbpncv34/
HTML:
<div></div>
CSS:
div {
background-color: red;
height: 10vh;
width: 10vw;
}
div:hover {
animation: change_width 0.7s forwards;
}
#keyframes change_width {
from {
width: 10vw;
}
to {
width: 15vw;
}
}
Issue:
I also want the box to smoothly move back when I hover off of it.
There are two ways I could do this:
Method 1:
JSFiddle: https://jsfiddle.net/hbpncv34/1/
HTML:
<div></div>
CSS:
div {
background-color: red;
height: 10vh;
width: 10vw;
animation: change_width_back 0.7s forwards;
}
div:hover {
animation: change_width 0.7s forwards;
}
#keyframes change_width {
from {
width: 10vw;
}
to {
width: 15vw;
}
}
#keyframes change_width_back {
from {
width: 15vw;
}
to {
width: 10vw:
}
}
Issue:
The change_width_back animation also runs on page load.
Also, mousing on / off rapidly is not smooth like it is with transition, so:
Method 2:
JSFiddle: https://jsfiddle.net/hbpncv34/2/
HTML:
<div></div>
CSS:
div {
background-color: red;
height: 10vh;
width: 10vw;
transition: width 0.7s;
}
div:hover {
width: 15vw;
}
Issue:
The animation also runs on zooming in and out.
I can fix this by using px or % instead of vw for my widths, but it's crucial in my actual issue that I keep it as viewport units.
So, is there any way to play an animation on hover on and off, and only hover on and off?
Since I don't know Javascript, please keep answers HTML / CSS only. If JS is absolutely needed, make it simple enough to just copy + paste with minimal editing.
Thanks for any help.
You need "ready" state flag in order to accomplish this:
$(function(){
$("div").attr("ready",true);
});
div {
background-color: red;
height: 10vh;
width: 10vw;
}
div[ready] {
transition: width 0.7s;
}
div[ready]:hover {
width: 15vw;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>.</div>
There may be a better way, but with very little js combined to your Method 1, you can do this:
<div onmouseover="this.classList.add('animate')"></div>
And in your css:
div {
background-color: red;
height: 10vh;
width: 10vw;
}
div.animate
{
animation: change_width_back 0.7s forwards;
}
https://jsfiddle.net/vhyfewnt/
EDIT
First solution is meant to work with animate, not with transition. There's a way to make transition work, but it needs a little more javascript.
<body onresize="document.getElementsByTagName('div')[0].classList.add('zoom'); setTimeout(function(e){document.getElementsByTagName('div')[0].classList.remove('zoom')}, 100)">
<div></div>
</body>
div {
background-color: red;
height: 10vh;
width: 10vw;
}
div:not(.zoom)
{
transition: width 0.7s;
}
div:hover {
width: 15vw;
}
https://jsfiddle.net/cdj7L5r3/
2nd EDIT:
To apply to more elements, you can add the class to body (or any ancestor) and change the rule. Like this:
<body onresize="document.body.classList.add('zoom'); setTimeout(function(e){document.body.classList.remove('zoom')}, 100)">
<div></div>
<div></div>
<div></div>
<div></div>
<section></section>
</body>
div, section{
background-color: red;
height: 10vh;
width: 10vw;
}
body:not(.zoom) div, body:not(.zoom) section
{
transition: width 0.7s;
}
div:hover, section:hover {
width: 15vw;
}
https://jsfiddle.net/cdj7L5r3/1/
RE: animate on zoom in/out, I don't think you're going to find a way around the animation issue with the CSS transition solution, because zooming changes the viewport size, and your units are in terms of the viewport. So when the viewport changes, those units have to be recalculated/repainted and that change is animated, as specified in the transition property.
If you could provide some background on the use case for this effect, we might be able to help think of another way to solve this problem.
If you are willing to add a litter js code maybe this help you, the key is that classes have the animation behavior, when the animation ends you remove the classes, so there is no transition when the page is zoom or loaded
var element = $("div");
element.bind("mouseover", function(){
$(this).removeClass('sh');
$(this).addClass('lg');
});
element.bind("mouseout", function(){
$(this).addClass('sh');
$(this).removeClass('lg');
});
/*this is for remove the class when animation ends*/
element.bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){
$(this).removeClass('sh');
});
div {
background-color: red;
height: 10vh;
width: 10vw;
}
.lg{
width: 15vw;
-webkit-transition: .3s;
}
.sh{
width: 10vw;
-webkit-transition: .3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div></div>
Here a jsfiddle example to play with
I'm trying to remove blur effect that is happening during scaling transition. Picture during transition is passable but this font transition is so ugly... Is there any method to fix it? I have tried with "translateY(0) translateZ(0)" but no effect at all. When the effect is done, everything is going back to normal.
.circlee
{
display: inline-block;
margin-right: 50px;
/*margin-top: 200px;*/
width: 200px;
height: 200px;
border-radius: 50%;
border: 2px black solid;
background-image: url(http://lorempixel.com/200/200/);
transition: all 1s ease-in-out;
}
.circlee:hover
{
transform: scale(1.15);
}
<div class="circlee">wwww</div>
<div class="circlee">xxxx</div>
<div class="circlee">ssss</div>
From the looks of it your image is only 200px by 200px . The hover effect is causing the image to stretch which results to quality loss / blur. You can either get a higher quality image so when it stretches it doesn't lose quality for an example ...an image of 210px by 210px with a resolution of 72 pixels . OR you could make your circle 190px by 190px and scale it up to 200px on hover resulting in the exact size of your background image.
OR just change the width and height on hover instead. Example:
.circlee
{
display: inline-block;
margin-right: 50px;
/*margin-top: 200px;*/
width: 190px;
height: 190px;
border-radius: 50%;
border: 2px black solid;
background-image: url(http://lorempixel.com/200/200/);
background-size:100% 100%;
transition: all 1s ease-in-out;
}
.circlee:hover
{
width:200px;
height: 200px;
}
<div class="circlee">wwww</div>
<div class="circlee">xxxx</div>
<div class="circlee">ssss</div>
Works like butter!
Main question
I have two divs, one nested inside the other and i wish to shift inner div outside (upwards) of outer div and slide-in it on a hover.
Markup is looking like so:
<div class="body">
<div class="inner">Green is variable-height text which slides in on viewport hover</div>
Blue is a viewport (<body>, visible part of a page), which content should be compressed upon green slide-in
</div>
And (a little pseudo) css:
.body {
background: #aaf;
height: 300px;
width: 300px;
overflow: hidden;
}
.inner, .body:hover .inner {
-webkit-transition:all linear 0.2s;
transition:all linear 0.2s;
}
.inner {
background: #afa;
width: 300px;
margin-top:-some-magic-to-get-this-div-height;
}
.body:hover .inner {
margin-top: 0;
}
And a final result animation i'd like to get, without using fixed height of green div:
Also, this example (with a guessed and hard-coded height value of 2.5em) on jsfiddle to experiment with:
http://jsfiddle.net/n7vyLoh4/20/
Possible partial work-around (not satisfactory)
It is possible to partially implement what i want, using transitioning max-height instead of transitioning margin-top, the transition of max-height: 0; -> max-height: 100%; with overflow: hidden; set at all times
works, but has two draw-backs:
it doesn't slide in, it's more like drops the curtain
it doesn't stop transition at the end of green div, it transits till the end of outer blue div, which especially noticeable at reverse transition, when it first travels all the way from bottom of blue div to bottom of green div before any effect is visible. Also, this means that despite transition time set to 0.2s, it will spend only fraction of this time on transiting trough green div, because this 100% are 100% of parent div, not inner one (and my question could be answered if there is a way to calculate the 100% of inner div height).
Here is an illustration:
And fiddle for that:
http://jsfiddle.net/bsd7vnwu/1/
This is the pure css solution, which means it does not require any scripts, just a browser that support transitions:
.body {
background: #aaf;
height: 300px;
width: 300px;
overflow: hidden;
}
.inner {
-webkit-transition:all cubic-bezier(0,.81,.4,1) 0.5s;
transition:all cubic-bezier(0,.81,.4,1) 0.5s;
}
.inner {
background: #afa;
width: 300px;
position: absolute;
margin-top: -100%;
float: left;
}
.body:hover .inner {
position: relative;
margin-top: 0;
}
And Fiddle is here
I think this is the effect you want. CSS doesn't allow you to get the height of an element to use in calc() for positioning and margins, so a little JS is needed.
CSS:
.body {
background: #aaf;
height: 300px;
width: 300px;
overflow: hidden;
}
.inner, .body:hover .inner {
-webkit-transition:all linear 0.2s;
transition:all linear 0.2s;
}
.inner {
background: #afa;
width: 300px;
overflow: hidden;
}
.body:hover .inner {
margin-top : 0 !important;
}
JS:
Array.prototype.forEach.call(document.getElementsByClassName('inner'), function (item) {
item.style.marginTop = (item.clientHeight * -1) + 'px';
});
Demo:
http://jsfiddle.net/09tyLr9b/
I added transition to your fiddle to get what i think you are looking for
.inner {
background: #afa;
width: 300px;
overflow: hidden;
max-height: 0;
transition:0.5s ease-out;
}
.body:hover .inner {
max-height: 100%;
transition:0.5s ease-in;
}
JSFIDDLE
and by lowering the time for transition:ease-out you will get a more responsive slide up when you mouse out of the div
like this JSFIDDLE
Another CSS solution after 2.5 years, using flex layout:
.body {
background: #aaf;
height: 300px;
width: 300px;
overflow: hidden;
}
.inner {
display: flex;
align-items: flex-end;
-webkit-transition: all cubic-bezier(0, 1, 0, 1) 0.5s;
transition: all cubic-bezier(0, 1, 0, 1) 0.5s;
background: #afa;
max-height: 0;
overflow: hidden;
}
.body:hover .inner {
-webkit-transition: all ease-in-out 0.5s;
transition: all ease-in-out 0.5s;
max-height: 100%;
}
<div class="body">
<div class="inner">Green is variable-height text which slides in on viewport hover</div>
Blue is a viewport (<body>, visible part of a page), which content should be compressed
Also on JSFiddle.