CSS3 transform rotate a nested background image - css

I have a background which exists of 3 images in total. However the middle background image (wrapper2) is visually 'between' two background images (wrapper1 and wrapper2).
When I try to rotate that middle image (wrapper2), the top-most image (wrapper3) also moves.
How can I prevent this, so that only the middle background-image (wrapper2) can rotate and not also the other one (wrapper3)?
<div id="wrapper1">
<div id="wrapper2">
<div id="wrapper3">
<!-- blabla -->
</div>
</div>
</div>
#wrapper1 {
background-image: url("../media/bg1.png");
background-size: 300px 200px;
background-repeat: no-repeat;
}
#wrapper2 {
background-image: url("../media/bg2.png");
background-size: 300px 200px;
background-repeat: no-repeat;
}
#wrapper3 {
background-image: url("../media/bg3.png");
background-size: 300px 200px;
background-repeat: no-repeat;
}
#wrapper2:hover
{
animation: TestAnim;
animation-iteration-count: infinite;
animation-duration: 10s;
}
#keyframes TestAnim
{
0% { transform:rotate(0deg); }
25% { transform:rotate(-4deg); }
100% { transform:rotate(0deg); }
}
}

ok, wasn't possible the way I worked.
I could either position the divs (absolute/relative) and make them siblings instead of childs.
But i've choosen to create a sprite image of all the rotations that I wanted and using an css3 animation.
In the CSS keyframes animation I move the background position every time:
0% { background-position: 0 0; width: 300px; height: 200px; }
1% { background-position: 0 -200px; width: 300px; height: 200px; }
...
Important is that you have to define the step-start!
animation-timing-function: step-start;
This step-start works fine in Internet Explorer 10.
Remark: For older browsers, the animation will not work (CSS3 is not known or step-start is not known) and your first sprite will be displayed, so make sure your first sprite is your initial state.
For your information: I used The GIMP to create my animation and used a plugin called CSS WebSprites to automatically generate my sprites and CSS code:
The GIMP CSS WebSprites plugin

Related

CSS background animation width issue

I have a div and the width is 100%. It has a background image. I am doing a zoom in out effect with animation for the background image. So, it will continuously loop zooming in the background image and zooming out.
div {
background-image:url('images/home-background.webp');
background-attachment:fixed;
background-size:cover;
background-repeat:no-repeat;
background-position:center center;
display:flex;
align-items: center;
justify-content: center;
width:100%;
height:700px;
animation:topb 10s infinite alternate;
box-sizing:border-box;
padding:30px;
}
#keyframes topb {
0% {
background-size: 105%;
}
100% {
background-size: 100%;
}
}
This works perfectly but when I resize my screen, particularly below 1200px, I see the background image becomes smaller even the div is 100% width. When I remove the animation line, the background image works fine, covering the screen. Here is a screenshot how it looks on mobile devices. You will see the background image does not cover the screen entirely even width is 100%.
So, can someone help me why is this happening?
The Problem
This is happening because your animation is overriding the Background size attribute, thus it switches from
background-size: cover;
To
background-size: 105%:
Which will make the background 105% of the width
A Solution
Since we want the background to cover the div's area at all times, and we want it to have a scaling animation, we will need to be clever. To do this we are going to nest another div with our properly sized background image inside the first. Then we add overflow: hidden to the parent and add a scale animation to the second div (not the background-size attribute though)
Some Code
body{margin:0;padding:0;background-color:#2D2D2D;}
#background {
background-image: url(https://images.unsplash.com/photo-1439405326854-014607f694d7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1770&q=80);
background-size: cover;
background-position:center center;
width:inherit;
height:inherit;
animation: scaleAnimation 1s infinite alternate;
position:absolute;
z-index:-1;
}
#parentDiv {
width: 100vw;
height: 500px;
overflow: hidden;
}
#parentDiv h1 {
text-align: center;
margin-top:100px;
}
#keyframes scaleAnimation {
0% {
transform: scale(1);
}
100% {
transform: scale(1.1);
}
}
<div id="parentDiv">
<div id="background"></div>
<h1>Heading 1</h1>
</div>

Creating an Infinite Scrolling VERTICAL background

There are tons of horizontal scrolling backgrounds but that isn't my issue. Any time I create a vertical scroll using keyframes, the background image itself runs out, or it glitches out completely and starts the scroll effect over. That is not what I need. I need a seamless VERTICAL scrolling background that takes up the full width of the screen. There will be a container with the overflow hidden and it's background needs to scroll slowly upwards with a series of images that never glitches out, runs out etc. It needs to look like the one million examples of horizontal scrolling but vertically.
In the CSS is the actual dimensions of the image I am using. I am using a placeholder to start this conversation. Notice, even with the placeholder, the image just eventually stops.
Why does it do this with vertical scrolling, but typically not with horizontal? It doesn't make sense to me and there aren't many resources out there about vertical infinite scrolls of a background image, believe it or not.
If anyone has any recommendations, I will take it. JS or CSS whatever it is I am willing to listen and learn and understand why the f*** I can't figure this out. Thanks.
<div class="container">
<div class="sliding-background"></div>
</div>
.container {
overflow: hidden;
height: 600px;
}
.sliding-background {
background: url("https://images.fineartamerica.com/images/artworkimages/mediumlarge/2/a-dramatic-image-of-a-tall-tree-sitting-against-moody-skies-in-the-background-with-blue-and-yellow-tones-chris-cook.jpg") repeat-y;
height: 4980px;
width: 1440px;
animation: slide 30s linear infinite;
}
#keyframes slide{
0% {
transform: translate3d(0, 0, 0);
}
100% {
transform: translate3d(0, -100%, 0);
}
}
<div class="container">
<div class="sliding-background"></div>
</div>
If you know the exact height of the image, this solution should work:
body {
margin: 0;
}
.container {
overflow: hidden;
height: 600px;
}
.sliding-background {
--imageHeight: 900px;
background: url("https://images.fineartamerica.com/images/artworkimages/mediumlarge/2/a-dramatic-image-of-a-tall-tree-sitting-against-moody-skies-in-the-background-with-blue-and-yellow-tones-chris-cook.jpg") repeat-y;
height: calc(var(--imageHeight) * 2);
animation: slide 4s linear infinite;
}
#keyframes slide {
from {
transform: translateY(0px);
}
to {
transform: translateY(calc(var(--imageHeight) * -1));
}
}
<div class="container">
<div class="sliding-background"></div>
</div>
If there is any confusion about the image height:
body {
margin: 0;
}
.container {
overflow: hidden;
height: 600px;
}
.sliding-background {
background: url("https://images.fineartamerica.com/images/artworkimages/mediumlarge/2/a-dramatic-image-of-a-tall-tree-sitting-against-moody-skies-in-the-background-with-blue-and-yellow-tones-chris-cook.jpg") repeat-y;
-webkit-animation: bgScroll 600s linear infinite;
animation: bgScroll 600s linear infinite;
height: 100%;
background-size: cover;
position: relative;
}
#keyframes bgScroll{
0% {
background-position: 0 0;
}
100% {
background-position: 0 10000%;
}
}
<div class="container">
<div class="sliding-background"></div>
</div>

How can I make an image cycle between multiple frames on hover?

I want to make an image do the following:
Start as a static image
Cycle through multiple frames when hovering
Return to the static image when no longer hovering
Image frames I was working with:
https://i.imgur.com/6z28Xcz.png
https://i.imgur.com/A0d4DL0.png
https://i.imgur.com/1QOJG9w.png
https://i.imgur.com/zwjr693.png
I tried this but could not get it to work (it just displayed nothing, even when copying and pasting the jsfiddle example linked to on that page).
Also is there a way of putting this in an img tag rather than a div one?
Pure CSS solution
#keyframes zigzag{
0%{
background-image: url('https://i.imgur.com/6z28Xcz.png');
}
25%{
background-image: url('https://i.imgur.com/A0d4DL0.png');
}
50%{
background-image: url('https://i.imgur.com/1QOJG9w.png');
}
100%{
background-image: url('https://i.imgur.com/zwjr693.png');
}
}
#logo{
width: 400px;
height: 170px;
border: 5px solid;
border-radius: 20%;
background-image: url('https://i.imgur.com/6z28Xcz.png');
background-repeat: no-repeat;
background-size: cover;
}
#logo:hover{
animation: zigzag 2000ms ease-in infinite;
}
<div id="logo"></div>

Make CSS sprite animation work

Im new to css animation, so I got this sequence movements picture online and want to make it walks. I follow a tutorial but it doesn't work in this case. I'm trying to make it moves. I don't know how to properly do that so I start with the first row of image. Its dimensions are 832x228.
and this is CSS code:
.sprite {
width: 130px;
height: 130px;
display: block;
background: transparent url(http://i.stack.imgur.com/UOPXb.png) 0 0 no-repeat;
animation: walker 1s steps(8) infinite;
}
#keyframes walker {
0% {
background-position: 0 0;
}
100% {
background-position: 832px 0px;
}
}
<div class="sprite"></div>
You are on the right path but the background-position is wrong within the keyframes. Sprite images should move from the right to the left in order to produce a moving animation and so the background position should go from 0 0 to -832px 0.
.sprite {
width: 114px;
height: 114px;
display: block;
background: transparent url(http://i.stack.imgur.com/UOPXb.png) 0 0 no-repeat;
animation: walker 1s steps(8) infinite;
/* image size is 832x228, so height is set as half of it */
}
#keyframes walker {
0% {
background-position: 0 0;
}
100% {
background-position: -832px 0px;
}
}
<div class='sprite'></div>
As mentioned in Robert C's answer, this will still not get the second row of images to show up. This is because the Y part of background-position doesn't change within the keyframes. The below snippet kindly contributed by Mishko Vladimir is one way to get them to display but problem is that if the no. of steps is increased to 16 (so as to show all sprites) then the animation doesn't work properly anymore.
Also, there will be a blink at the point where Y position changes. So, my recommendation would be to put all 16 sprites in the same row instead of two.
.sprite {
width: 114px;
height: 114px;
display: block;
background: transparent url(http://i.stack.imgur.com/UOPXb.png) 0 0 no-repeat;
animation: walker 1s steps(8) infinite;
/*832x228*/
}
#keyframes walker {
0% {
background-position: 0 0;
}
50% {
background-position: -832px 0px;
}
51% {
background-position: 0 -114px;
}
100% {
background-position: -832px -114px;
}
}
<div class='sprite'></div>
Looks like you have the wrong background-position, it should be -832px rather than 832px. Note that with the above image you're also only going to get the top 8 frames, you'll need to edit the file to get the bottom 8 for a longer transition.
You may also want to adjust the time in your animation down to a fraction (I had a smoother walk with 0.9), and you'll want to shrink your width and height down to around 115px to avoid seeing some of the other frames.

CSS3 background-position in percentage not working at all

So I'm coding a parallax effect in CSS3 with 3 layers for a page header. My style sheet is the following:
#graphic-layer { /* overall properties for graphic layers */
position: absolute;
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
}
#graphic-layer.header { /* header-class */
width: 100%;
height: 150px;
background-repeat: repeat-x;
-webkit-animation-name: header;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
#graphic-layer.header:nth-of-type(1) { /* parallax layer 1 */
background-image: url('images/header-background.jpg');
-webkit-animation-duration: 100s;
}
#graphic-layer.header:nth-of-type(2) { /* parallax layer 2 */
background-image: url('images/header-middle.png');
-webkit-animation-duration: 80s;
}
#graphic-layer.header:nth-of-type(3) { /* parallax layer 3 */
background-image: url('images/header-foreground.png');
-webkit-animation-duration: 60s;
}
#-webkit-keyframes header { /* keyframes */
0% {
background-position: 0 0;
}
100% {
background-position: 100% 0; /* <- PROBLEM HERE */
}
}
EDIT: HTML, simply three instances of graphic-layer with class header:
<div id="graphic-layer" class="header"></div>
<div id="graphic-layer" class="header"></div>
<div id="graphic-layer" class="header"></div>
So far, so good. Note, my header is 100% width of the screen. This works perfectly fine if I set the background position at keyframe 100% to background-position: 1920px 0; (my screen/window width) but as soon as the resolution of the window changes, this obviously won't work anymore. If I set the value lower, to 500px, for example, the picture moves 500 pixels and jumps back to the start but I want it to continously move without "jumping".
So I need a solution to make the image move exactly 100% of the width of the header and then restart the animation. But when I set the background position at keyframe 100% to background-position: 100% 0; it doesn't move at all.
What is the problem here? Why are the percentage values not working?
EDIT:
Found the answer myself!
It was just a stupid error in reasoning. #graphic-layer.header doesn't have to be 100% of the header but 100% of the image, which is a static value (in this case 1920px). So if I set the width to 3480px (1920x2) and then change the keyframes to the following:
#-webkit-keyframes header { /* keyframes */
0% {
left: 0;
}
100% {
left: -1920px; /* <- Image size */
}
}
...then the header class moves 1920px to the left and starts over again and because of the doubled width of the class it seems like it is an endless image. No need for relative percentage values!

Resources