I have an element with multiple (two) backgrounds
div
{
background: url("bg1.png"), url("bg2.png");
transition: background 1s;
}
div:hover
{
background-position: 0 -20px, 0 -200px;
}
Here, both backgrounds will move in the same time.
How can I have different transition time on them ?
I guess one solution would be to use #keyframes to delay one of the backgrounds animation but I wondered if there was any other way.
Here's a little FIDDLE that might help you.
Relevant CSS:
.testdiv {
width: 200px;
height: 300px;
background-color: red;
background: url("http://upload.wikimedia.org/wikipedia/commons/9/95/Tux-small.png"),
url("http://www.twitip.com/wp-content/uploads/2008/11/twitter-button-small.png");
background-repeat: repeat-x, repeat;
}
.testdiv:hover {
background-position: 0 -20px, 0 -200px;
}
Related
This question already has answers here:
Using percentage values with background-position on a linear-gradient
(2 answers)
How to animate background-position using percentages when background-size is 100%?
(1 answer)
Closed 4 months ago.
I'm trying to have an animated linear-gradient work vertically, but for some reason it only works when I use a value in px instead of % for the background-position in the keyframes. A percentage would be way better since the width/height of the element is going to change, therefore the background-position should follow.
If the gradient is oriented 90deg, it works but obviously it renders horizontally instead of vertically.
Here is the code :
div {
width: 50px;
height: 150px;
background: linear-gradient(0deg, yellow, orange, red, violet, purple, blue, yellow);
animation: color 5s linear infinite;
margin: 50px auto;
}
#keyframes color {
0% {
background-position: 0%;
}
100% {
background-position: 200%; /* doesn't work */
/*background-position: 0 -150px; -> works fine but not ideal */
}
}
<div></div>
I tried negative value and other background-position variations, without success.
Here is a pen with the code : https://codepen.io/petruhaand1/pen/jOKMrWB
Using aspects from this answer to a similar question, got it working somewhat:
div {
width: 50px;
height: 150px;
margin: 50px auto;
overflow: hidden;
position: relative;
z-index: 0;
}
div:before {
content: "";
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
background: linear-gradient( 0deg, yellow, orange, red, violet, purple, blue, yellow) top/100% 50%;
bottom: 0;
animation: color 5s linear infinite;
}
#keyframes color {
0% {
background-position: top;
}
100% {
background-position: bottom;
}
}
<div></div>
in this code:
#p1 {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-color: #05080d;
background-position: left top, left bottom;
background-size: 100% 35%, 100% 65%;
}
I want when the page shows up, first show backimgs/first/1.jpg then after 1 sec show backimgs/first/2.jpg. how can I do it?
You can't animate background-images. You can change it, but there won't be any smooth transition:
#p1 {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-color: #05080d;
background-position: left top, left bottom;
background-size: 100% 35%, 100% 65%;
animation: change-bg;
animation-duration: 1s;
}
#keyframes change-bg {
0% {
background-image: url(backimgs/first/1.jpg), url(backimgs/first/2.jpg);
background-size: 100% 35%, 100% 65%;
}
100% {
background-image: url(backimgs/first/2.jpg), url(backimgs/first/1.jpg);
background-size: 100% 65%, 100% 35%;
}
}
If you want a smooth transition - you can use ::before and ::after with a background and animate the opacity of them. Let me know with a comment if you need more info on this aproach, I'll edit the post and show, how it's done.
You mention 'transition' in the title so you will need to control the two parts of the background separately.
To enable this, this snippet removes the backgrounds from the element itself, instead putting them onto two pseudo elements. The before pseudo element having the first image as background and the after pseudo element having the second one.
Separating the components in this way means we can animate the opacities, the first pseudo element going from opacity 0 to opacity 1 in the first second.
Note however that a little hack has been added to ths snippet. As the animation on the before pseudo element is to happen on load then there needs to be some method of waiting for the background image to load before the animation starts else there is a danger it will be part way through, or even finished, before the image is actually available.
I do not know the wider context of how you are testing for load being complete so have just put a delay in here for demo purposes. You'll need to decide what to do to avoid this inital load situation.
* {
margin: 0;
padding: 0;
}
#p1 {
/* added for this demo */
display: inline-block;
width: 100vw;
height: 100vh;
position: relative;
}
#p1::before,
#p1::after {
content: '';
position: absolute;
z-index: -1;
width: 100%;
left: 0;
display: inline-block;
background-color: #05080d;
background-size: cover;
background-repeat: no-repeat no-repeat;
background-position: center center;
animation: fadein 1s linear;
animation-fill-mode: forwards;
opacity: 0;
}
#p1::before {
top: 0;
height: 35%;
background-image: url(https://picsum.photos/id/1018/1024/768);
animation-delay: 1s;
/* a hack to ensure it is loaded before start the animation */
}
#p1::after {
bottom: 0;
height: 65%;
background-image: url(https://picsum.photos/id/1015/1024/768);
animation-delay: 2s;
}
#keyframes fadein {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div id="p1"></div>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I want to create a diagonal background image as seen in the attached image. I can create a diagonal line using linear-gradient however as I have two different angles this didn't work.
Using Linear Gradients:
This can be done using multiple background images and positioning them accordingly. In the snippet below I've used 3 different layers - one for the top angle (a triangle which is transparent for 50% and is colored for the rest), one for the middle which is essentially nothing but a solid colored rectangle, this is created using linear gradients as it is easier to control the dimensions of an image and finally one for the bottom angle (same approach as the top one but this has a different height and so different angle.)
The output is also responsive as you can see by hovering the element in the below snippet. In the 2nd div, I've set different colors for each image so that you can see how it is formed.
div {
height: 300px;
width: 100%;
background: linear-gradient(to bottom right, transparent 50%, lightblue 51%), linear-gradient(lightblue, lightblue), linear-gradient(to top right, transparent 50%, lightblue 51%);
background-size: 100% 30px, 100% calc(100% - 130px), 100% 100px;
background-position: top left, left 30px, bottom left;
background-repeat: no-repeat;
transition: all 1s ease; /* just for demo */
}
/* just for demo */
div {
margin-bottom: 10px;
}
div:hover {
height: 400px;
}
div:nth-of-type(2) {
background: linear-gradient(to bottom right, transparent 50%, lightblue 51%), linear-gradient(lightpink, lightpink), linear-gradient(to top right, transparent 50%, lightgreen 51%);
background-size: 100% 30px, 100% calc(100% - 130px), 100% 100px;
background-position: top left, left 30px, bottom left;
background-repeat: no-repeat;
}
<div></div>
<div></div>
Using SVG: recommended
This is the approach that I generally recommend and is the best. It involves creating the shape using SVG and then placing it absolutely behind the div element.
div {
position: relative;
height: 300px;
width: 100%;
}
svg {
position: absolute;
height: 100%;
width: 100%;
}
polygon {
fill: lightblue;
}
<div>
<svg viewBox='0 0 300 100' preserveAspectRatio='none'>
<polygon points='0,10 300,0 300,100 0,75z' />
</svg>
</div>
Using Clip-path:
Another approach that can be used is to position a pseudo-element behind the main div and then set a clip-path in the required shape to this pseudo-element.
Note: This snippet will currently work only in WebKit powered browsers. Firefox would need the clip-path to be created via SVG element whereas IE doesn't support it all.
div {
position: relative;
height: 300px;
width: 100%;
}
div:before {
position: absolute;
content: '';
height: 100%;
width: 100%;
background: lightblue;
-webkit-clip-path: polygon(0% 5%, 100% 0%, 100% 100%, 0% 75%);
clip-path: polygon(0% 5%, 100% 0%, 100% 100%, 0% 75%);
}
<div></div>
CSS Perspective
You can use a CSS Perspective Transform to create the shape you want.
div {
margin-top: 25px;
width: 500px;
height: 150px;
transform: perspective( 800px ) rotateY( -25deg );
background: blue;
}
<div></div>
CSS Tricks Docs
Perspective - CSS | MDN
You can apply perspective to the parent container of the rotated div to give it 3-dimensional depth from the front of the viewport.
N.B. For the difference between transform: perspective(value) and perspective: value, see the CSS Tricks Almanac entry on perspective:
Important: Please note the perspective property doesn't affect how the element is rendered; it simply enables a 3D-space for children
elements. This is the main difference between the transform: perspective() function and the perspective property. The first
gives element depth while the latter creates a 3D-space shared by all
its transformed children.
After applying a 3-dimensional depth to the parent container using perspective, you can then apply rotateY to the div you want to rotate.
Working Example:
section {
position: relative;
width: 600px;
perspective: 800px;
transform: translateX(-60px);
}
div:nth-of-type(1) {
position: absolute;
top:30px;
left: 0;
width: 100%;
height: 100px;
background-color: rgb(235,250,255);
transform: rotateY(320deg);
}
div:nth-of-type(2) {
position: absolute;
top: 0;
left: 220px;
width: 120px;
height: 140px;
background-color: rgb(103,201,236);
box-shadow: 6px 6px 6px rgba(127,127,127,0.5);
}
div:nth-of-type(3) {
position: absolute;
top: 24px;
left: 340px;
width: 120px;
height: 140px;
background-color: rgb(255,255,255);
box-shadow: 6px 6px 6px rgba(127,127,127,0.5);
}
<section>
<div></div>
<div></div>
<div></div>
</section>
I would like to bring some more interactive elements into my webpage.
What i've seen before on some website's, is that the background image zoom's in slowly and back out. So that it looks more like a living thing.
I've been searching on the internets and here. But i dont know how this technique is done exactly and i dont know the name for this kind of effect.
I also think this should be fairly easy to achiev this with some CSS3 and HTML5.
The questions are:
Is there a name for this effect and what is it called?
Can it be done with pure CSS?
Is there a sample online availble for the basics?
Here is the html i had in mind:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test page</title>
<style>
body {
background-image: url("http://wallpapercave.com/wp/LXR5gFx.png");
background-size: 100% auto;
}
</style>
</head>
<body>
</body>
</html>
The goal is to let the background image zooming in slowly and back out. Like it is breathing.
There is mainly 2 different ways, using either animation or transition.
animation is normally better when one want something running all the time, and transition is more efficient for e.g. hover effects.
Here is a start using animation.
Stack snippet
html, body {
height: 100%;
margin: 0
}
#keyframes breath {
0% { background-size: 100% auto; }
50% { background-size: 140% auto; }
100% { background-size: 100% auto; }
}
#bkg{
width: 100%;
height: 100%;
animation: breath 4s linear infinite;
background: url("http://wallpapercave.com/wp/LXR5gFx.png") center center no-repeat;
}
<div id="bkg"></div>
And here is another using transition and :hover.
Stack snippet
html, body {
height: 100%;
margin: 0
}
#bkg {
width: 180px;
height: 180px;
position: relative;
overflow: hidden;
}
#bkg::before {
content: '';
position: absolute;
left: 0; top: 0;
width: 100%;
height: 100%;
background-size: cover;
background-image: url("http://wallpapercave.com/wp/LXR5gFx.png");
background-position: center;
background-repeat: no-repeat;
transition: transform .5s linear;
}
#bkg:hover::before{
transform: scale(1.3);
}
<div id="bkg"></div>
What you are looking for is called keyframes.
This is the code in the following example.
#keyframes zoom {
0% { transform:scale(1,1); }
50% { transform:scale(1.2,1.2); }
100% {
transform:scale(1,1);
}
}
Css transform has properties which can br run "frame by frame", in the above, we want the picture to be zoomed by the factor 1.2 on the x and y axis by the time 50% of the animation have passed.
We start at no zoom, zoom it by 20% and then we go back tot he original state.
And here is how we add this to the class:
animation: zoom 30s infinite;
just add that to your class and it will run. There are more parameters, but this gets complicated for someone who is unfamiliar with, thus, an easy example.
Here the link to the codepen in action
http://codepen.io/damianocel/pen/QyqRgw
You want to use a separate element with transform(), for three reasons:
It will use the GPU to render the element
It will be more performant in terms of FPS more on that
Animating the body background will cause the entire page to repaint on every frame
Also, animating the background-position will create a juggle effect, as the browser will try to round the position to the nearest pixel.
With a transform: scale() on the other hand, the browser will position the element with subpixel rendering, resulting in a way smoother movement.
#keyframes breath {
from {
transform: scale(1);
}
to {
transform: scale(1.05)
}
}
div{
width: 100vw;
height: 100vh;
animation: breath 2s ease-in-out alternate infinite;
background: url("https://www.placecage.com/800/600");
background-size: cover;
}
body {
margin: 0;
}
<div></div>
I am trying to use a CSS3 Step Animation to change from one image to another using a simple 2 image sprite sheet. I can't seem to get the second image to load in place of the first image. I have looked at other examples and I really can't see where I am going wrong. So if anyone could help it would be much appreciated. Thanks.
CODEPEN DEMO
<div class="character">
<div class="beak"></div>
</div>
#keyframes newquestion-beak {
from { background-position: 0px 0; }
to { background-position: -100px 0; }
}
.character > div {
background-repeat: no-repeat;
height: 100px;
width: 100px;
position: absolute;
top: 0;
left: 0;
}
.character .beak {
background-image: url(http://s22.postimg.org/6mb37v5sh/compiled_beaks.png);
animation: newquestion-beak .8s steps(2) infinite;
}
Your background positioning wasn't right. Try:
#keyframes newquestion-beak {
from { background-position: -100px 0; }
to { background-position: 100px 0; }
}
Running demo on CodePen
Using "steps(2)" in the animation seems to only move the image halfway. Doubling the 'to' background-position works for me, using Chrome.
Demo with change.