css3 animation addition assignment for to{} - css

I am looking for way to make addition assignment in #keyframe.
for example I want background position change infinity and just go on.
.waterwave{
background-image: url("../img/waterwave.png");
height: 215px;
margin-top: -78px;
width: 100%;
animation-name: example;
animation-duration: 100s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-direction: normal;
}
#keyframes example {
to {background-position: 100px;}
}
But I don't want to make absolute value like 100px .
I want something like backgroundPosition: "+=100" in js animation.
Is there any possibility to doing sth like that in css ?

If you have a repeating background, the position starts over at the width of the background graphic. For example, if the graphic is 300px wide, then background-position:50px looks exactly the same as background-position:350px.
So that's what you can use: move the background animation precisely the same width as the graphic, and then it will seamlessly start over. At least if you use the linear function rather than ease-in-out.
.waterwave {
background-image: url("http://lorempixel.com/300/215"); /* a 300px wide image */
height: 215px;
margin-top: -78px;
width: 100%;
animation-name: example;
animation-duration: 5s;
animation-timing-function: linear; /* changed from ease-in-out */
animation-iteration-count: infinite;
animation-direction: normal;
}
#keyframes example {
to {
background-position: 300px; /* this should be the same as the image */
}
}
<div class="waterwave"></div>
(in the example I used 5 seconds for the duration, to make the effect visible, but you get the idea.)

Related

Auto shrink a button without interaction

I'd like to add a menu button in the top right corner of my site - just a simple circle with an icon. I'd like to to load at a certain height and width and then automatically shrink, a few moments later, to another height and width - all without any user interaction.
Is this possible?
Any CSS gurus out there?
Many thanks,
You can do it with the CSS3 Animation:
div {
width: 50px;
height: 50px;
background: #00f;
border-radius: 50%;
animation-name: shrink; /* "calling" the animation */
animation-duration: 1s; /* adjust */
animation-timing-function: linear; /* specifies the speed curve of an animation / also try other values */
animation-delay: 3s; /* adjust */
animation-fill-mode: forwards; /* retains in the state set by the last keyframe */
}
#keyframes shrink { /* let's call it "shrink" */
0% {width: 50px; height: 50px}
100% {width: 25px; height: 25px} /* final state */
}
<div><div>
Experiment and adjust to your needs.
Note: There are also other animation properties & values so you might take a closer look to see what you can do.

Move DOM elements off screen without increasing body width

I am using bootstrap 3 for my web application, and I am running into and issue.
My navbar is wrapped in a container div,
my main content is wrapped in a container div adjacent to the navbar like so:
<body>
<div class="container">
//Navbar stuff
</div>
<div class="container">
//Navbar stuff
</div>
</body>
I have an animation on the body content that slides all of the content off of the screen while transitioning to a new screen. to do so I animate the left attribute to be off screen.
From what I can gather, this is causing the body width to expand beyond it's normal size, and this is causing my navbar to be affected by the position of content during the animation.
Is there a way to implement a sliding animation without increasing the width of the body, so that my navbar does not get moved during the animation?
EDIT:
To clarify how I am doing the animations, I am using CSS3 animation keyframes, and applying the class to the element I am sliding of screen. Here is the LESS that is doing this
#animation-duration: 300ms;
#animation-timing-function: ease-in-out;
#animation-fill-mode:forwards;
#animation-iteration-count: 1;
.slide-in-right{
animation-name: slideInRight;
animation-duration:#animation-duration;
animation-timing-function: #animation-timing-function;
animation-fill-mode: #animation-fill-mode;
animation-iteration-count: #animation-iteration-count;
}
.slide-out-right{
animation-name: slideInRight;
animation-duration:#animation-duration;
animation-direction: reverse;
animation-timing-function: #animation-timing-function;
animation-fill-mode: #animation-fill-mode;
animation-iteration-count: #animation-iteration-count;
}
.slide-in-left{
animation-name: slideInLeft;
animation-duration: 300ms;
animation-timing-function: linear;
animation-fill-mode: forwards;
animation-iteration-count: 1;
}
.slide-out-left{
animation-name: slideInLeft;
animation-direction: reverse;
animation-duration:#animation-duration;
animation-timing-function: #animation-timing-function;
animation-fill-mode: #animation-fill-mode;
animation-iteration-count: #animation-iteration-count;
}
#keyframes slideInRight{
0%{
position:relative;
left: 150%;
}
100%{
position:relative;
left:0%;
}
}
#keyframes slideInLeft{
0%{
position:relative;
left: -150%;
}
100%{
position:relative;
left:0%;
}
}
If you use transform: translateX(-100%); (where -100% is whatever you have to do to move it off screen), it shouldn't affect body width.
Also, using position: absolute; left: -100%; (again, -100% is whatever you have to do to move the element off screen), the body width shouldn't be affected, either.

CSS Keyframes animation without animating background-image

I am trying to perform a rotate on the Y axis of an element that contains a background-image. When I reach 50% of that animation, I would like to change the image.
The problem:
The background-image is also animated
I am trying to do this without the use of Javascript.
Is that possible?
Code:
.picture {
background-image: url('http://img3.wikia.nocookie.net/__cb20130216121424/adventuretimewithfinnandjake/images/2/29/Tom-cruise-funny-face.png');
display: inline-block;
vertical-align: top;
border: 5px solid red;
width: 250px;
height: 250px;
background-size: 100% 100%;
border-radius: 100%;
}
.animated {
-webkit-animation-name: turns;
animation-name: turns;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#-webkit-keyframes turns {
0% { background-image: url('http://img3.wikia.nocookie.net/__cb20130216121424/adventuretimewithfinnandjake/images/2/29/Tom-cruise-funny-face.png'); -webkit-transform: rotateY(0deg); }
1% { background-image: url('http://img3.wikia.nocookie.net/__cb20130216121424/adventuretimewithfinnandjake/images/2/29/Tom-cruise-funny-face.png'); }
50% { background-image: url('http://img3.wikia.nocookie.net/__cb20130216121424/adventuretimewithfinnandjake/images/2/29/Tom-cruise-funny-face.png'); }
51% { background-image: url('http://i3.mirror.co.uk/incoming/article172940.ece/alternates/s615/image-16-jim-carrey-50th-birthday-604638636.jpg'); }
100% { background-image: url('http://i3.mirror.co.uk/incoming/article172940.ece/alternates/s615/image-16-jim-carrey-50th-birthday-604638636.jpg'); -webkit-transform: rotateY(180deg); }
}
jsFiddle: http://jsfiddle.net/dmzj7cfh/1/
If the problem that you have is that the background image change does nt happen in the 50% of the rotation, it's because the timing funciont is applied for the individual steps in the case of the background (because it is set in every keyframe), but for the full animation in the case of the rotation.
The easiest way to solve it is to set
-webkit-animation-timing-function: linear;
so that it doesn't matter the above problem
I have also fixed a problem with the background size.
fiddle
You should probably use multiple animation keywords to simplify, as you need to change two different properties.
For background-image animation, use animation-timing-function: steps(2); and for transform: rotate;, use linear function to simplify the keyframes.
Using non-linear functions like ease and custom cubic-bezier()s can create a lot of complexities.
FIDDLE
Snippet :
div{
display: inline-block;
border: 5px solid red;
width: 250px;
height: 250px;
background-size: cover;
border-radius: 100%;
-webkit-animation-name: animate, background;
-webkit-animation-iteration-count: infinite;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear, steps(2);
animation-name: animate, background;
animation-iteration-count: infinite;
animation-duration: 2s;
animation-timing-function: linear, steps(2);
background-image: url('http://i.imgur.com/gmucjHi.png');
position: relative;
}
#-webkit-keyframes animate {
0% {transform: rotateY(90deg);}
100% {transform: rotateY(450deg);}
}
#-webkit-keyframes background {
0% {background-image: url('http://i.imgur.com/gmucjHi.png');}
100% {background-image: url('http://i.imgur.com/mZinlRQ.jpg');}
}
#keyframes animate {
0% {transform: rotateY(90deg);}
100% {transform: rotateY(450deg);}
}
#keyframes background {
0% {background-image: url('http://i.imgur.com/gmucjHi.png');}
100% {background-image: url('http://i.imgur.com/mZinlRQ.jpg');}
}
<div></div>
Note : I haven't added vendor prefixes other than -webkit-.

How to hide one html tag behind another at a certain coordinate

I have two div elements, within the one background div I have another div which uses CSS animation to display a box going up and down.
I want to make those parts of this div with the box 'disappear' as soon as any part of that box crosses over that background div.
I have an example here JSFidle, where as soon the red box exceeds the black box it should then go 'under' the black div rather than remaining at the top as it's presently.
This is the CSS code:
body{
z-index:100;
}
div{
background: black;
height:300px;
}
#scroll{
width: 200px;
height: 200px;
background: red;
position: relative;
-webkit-animation-name: test;
-webkit-animation-duration: 60s;
-webkit-animation-timing-function: linear;
-webkit-animation-delay: 0s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
-webkit-animation-play-state: running;
animation-name: test;
animation-duration: 30s;
animation-timing-function: linear;
animation-delay: 0s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-play-state: running;
}
#-webkit-keyframes test {
0% {left:0px; top:0px;}
50% {left:0px; top:270px;}
100% {left:0px; top:0px;}
}
#keyframes test {
0% {left:0px; top:0px;}
50% {left:0px; top:270px;}
100% {left:0px; top:0px;}
}
body {
overflow-x: auto;
overflow-y: hidden;
}
What is the best way to create this effect.
You just need to add overflow: hidden to the parent div.
I sped up your animation for testing purposes.
Like so
#scrollParent{
overflow: hidden;
}
Assign a z-index to the outer-most background(the white part in the fiddle) and make it higher than the z-index of the red box. Guess that should work.

CSS Animation and Display None

I have a CSS Animation for a div that slides in after a set amount of time. What I would like is for a few divs to fill the space of the animated div that slides in, which it will then push those elements down the page.
When I attempt this at first div that slides in still takes up space even when it is not visible. If I change the div to display:none the div doesn't slide in at all.
How do I have a div not take up space until it is timed to come in (using CSS for the timing.)
I am using Animate.css for the animations.
Here is what the code looks like:
<div id="main-div" class="animated fadeInDownBig"><!-- Content --></div>
<div id="div1"><!-- Content --></div>
<div id="div2"><!-- Content --></div>
<div id="div3"><!-- Content --></div>
As the code shows I would like the main div to be hidden and the other divs show at first. Then I have the following delay set:
#main-div{
-moz-animation-delay: 3.5s;
-webkit-animation-delay: 3.5s;
-o-animation-delay: 3.5s;
animation-delay: 3.5s;
}
It is at that point that I would like the main div to push the other divs down as it comes in.
How do I do this?
Note: I have considered using jQuery to do this, however I prefer using strictly CSS as it is smoother and the timing is a bit better controlled.
EDIT
I have attempted what Duopixel suggested but either I mis-understood and am not doing this correctly or it doesn't work. Here is the code:
HTML
<div id="main-div" class="animated fadeInDownBig"><!-- Content --></div>
CSS
#main-image{
height: 0;
overflow: hidden;
-moz-animation-delay: 3.5s;
-webkit-animation-delay: 3.5s;
-o-animation-delay: 3.5s;
animation-delay: 3.5s;
}
#main-image.fadeInDownBig{
height: 375px;
}
CSS (or jQuery, for that matter) can't animate between display: none; and display: block;. Worse yet: it can't animate between height: 0 and height: auto. So you need to hard code the height (if you can't hard code the values then you need to use javascript, but this is an entirely different question);
#main-image{
height: 0;
overflow: hidden;
background: red;
-prefix-animation: slide 1s ease 3.5s forwards;
}
#-prefix-keyframes slide {
from {height: 0;}
to {height: 300px;}
}
You mention that you're using Animate.css, which I'm not familiar with, so this is a vanilla CSS.
You can see a demo here: http://jsfiddle.net/duopixel/qD5XX/
There are a few answers already, but here is my solution:
I use opacity: 0 and visibility: hidden. To make sure that visibility is set before the animation, we have to set the right delays.
I use http://lesshat.com to simplify the demo, for use without this just add the browser prefixes.
(e.g. -webkit-transition-duration: 0, 200ms;)
.fadeInOut {
.transition-duration(0, 200ms);
.transition-property(visibility, opacity);
.transition-delay(0);
&.hidden {
visibility: hidden;
.opacity(0);
.transition-duration(200ms, 0);
.transition-property(opacity, visibility);
.transition-delay(0, 200ms);
}
}
So as soon as you add the class hidden to your element, it will fade out.
I had the same problem, because as soon as display: x; is in animation, it won't animate.
I ended up in creating custom keyframes, first changing the display value then the other values. May give a better solution.
Or, instead of using display: none; use position: absolute; visibility: hidden; It should work.
You can manage to have a pure CSS implementation with max-height
#main-image{
max-height: 0;
overflow: hidden;
background: red;
-prefix-animation: slide 1s ease 3.5s forwards;
}
#keyframes slide {
from {max-height: 0;}
to {max-height: 500px;}
}
You might have to also set padding, margin and border to 0, or simply padding-top, padding-bottom, margin-top and margin-bottom.
I updated the demo of Duopixel here : http://jsfiddle.net/qD5XX/231/
The following will get you to animate an element when
Giving it a Display - None
Giving it a Display - Block
CSS
.MyClass {
opacity: 0;
display:none;
transition: opacity 0.5s linear;
-webkit-transition: opacity 0.5s linear;
-moz-transition: opacity 0.5s linear;
-o-transition: opacity 0.5s linear;
-ms-transition: opacity 0.5s linear;
}
JavaScript
function GetThisHidden(){
$(".MyClass").css("opacity", "0").on('transitionend webkitTransitionEnd oTransitionEnd otransitionend', HideTheElementAfterAnimation);
}
function GetThisDisplayed(){
$(".MyClass").css("display", "block").css("opacity", "1").unbind("transitionend webkitTransitionEnd oTransitionEnd otransitionend");
}
function HideTheElementAfterAnimation(){
$(".MyClass").css("display", "none");
}
When animating height (from 0 to auto), using transform: scaleY(0); is another useful approach to hide the element, instead of display: none;:
.section {
overflow: hidden;
transition: transform 0.3s ease-out;
height: auto;
transform: scaleY(1);
transform-origin: top;
&.hidden {
transform: scaleY(0);
}
}
How do I have a div not take up space until it is timed to come in (using CSS for the timing.)
Here is my solution to the same problem.
Moreover I have an onclick on the last frame loading another slideshow, and it must not be clickable until the last frame is visible.
Basically my solution is to keep the div 1 pixel high using a scale(0.001), zooming it when I need it. If you don't like the zoom effect you can restore the opacity to 1 after zooming the slide.
#Slide_TheEnd {
-webkit-animation-delay: 240s;
animation-delay: 240s;
-moz-animation-timing-function: linear;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-moz-animation-duration: 20s;
-webkit-animation-duration: 20s;
animation-duration: 20s;
-moz-animation-name: Slide_TheEnd;
-webkit-animation-name: Slide_TheEnd;
animation-name: Slide_TheEnd;
-moz-animation-iteration-count: 1;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
-moz-animation-direction: normal;
-webkit-animation-direction: normal;
animation-direction: normal;
-moz-animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
transform: scale(0.001);
background: #cf0;
text-align: center;
font-size: 10vh;
opacity: 0;
}
#-moz-keyframes Slide_TheEnd {
0% { opacity: 0; transform: scale(0.001); }
10% { opacity: 1; transform: scale(1); }
95% { opacity: 1; transform: scale(1); }
100% { opacity: 0; transform: scale(0.001); }
}
Other keyframes are removed for the sake of bytes. Please disregard the odd coding, it is made by a php script picking values from an array and str_replacing a template: I'm too lazy to retype everything for every proprietary prefix on a 100+ divs slideshow.
I have the same problem and solved putting everything bellow a div with position:relative and added position: absolute, top:0, left:0 to every child div.
In your case it will be like:
<div id="upper" style="position: relative">
<div id="main-div" class="animated fadeInDownBig" style="position: absolute; left:0; top:0;"><!-- Content --></div>
<div id="div1" style="position: absolute; left:0; top:0;""><!-- Content --></div>
<div id="div2" style="position: absolute; left:0; top:0;""><!-- Content --></div>
<div id="div3" style="position: absolute; left:0; top:0;""><!-- Content --></div>
</div>

Resources