https://jsfiddle.net/vaf6nv36/1/
Can the balloons image slowly transition over the apple image?
I think that I need more transition parameters, or I should use opacity?
Can someone help me?
HTML:
<div class="img1">
</div>
<div class="img2">
</div>
CSS:
.img1, .img2{
border: 1px solid black;
transition: 1s;
position: absolute;
}
.img1{
left: 25%;
height: 500px;
width: 500px;
z-index: 1;
background-image: url(http://cdn.pcwallart.com/images/balloons-photography-vintage-wallpaper-1.jpg);
}
.img2{
right: 25%;
width: 500px;
height: 500px;
bottom: 0;
z-index: 2;
background-image: url(https://i.pinimg.com/736x/c1/7b/15/c17b150e93c4e9c50d963b076484bee7--apple-wallpaper-iphone-wallpaper.jpg);
}
.img1:hover{
z-index: 999;
}
Although theoretically you can transition z-index, it wouldn't make much sense, i.e. would not result in the crossfade effect which you obviously are looking for: z-index values are integers, which - when you change them in the smallest possible steps (integers, no commas) - results in states either before the other one OR behind the other one - no transitional "half states" in between. If you want to do a kind of continuous crossfade between two elements, you should use a transition on opacity.
In your particular case, since your DIVs are not directly above each other, but only overlap each other, you can solve that by having a second DIV identical to img2 (I called its class .img3), but with z-index: 0 and this CSS rule:
.img1:hover + .img2 {
opacity: 0;
}
This will fade out img2, but still show img3, which however is behind img1, creating the impression of a transition between img1 and img2.
https://jsfiddle.net/2a2epLfv/1/
.img1,
.img2,
.img3 {
border: 1px solid black;
transition: 1s;
position: absolute;
}
.img1 {
left: 20%;
height: 300px;
width: 300px;
z-index: 1;
background-image: url(http://cdn.pcwallart.com/images/balloons-photography-vintage-wallpaper-1.jpg);
}
.img2,
.img3 {
right: 20%;
width: 300px;
height: 300px;
top: 100px;
background-image: url(https://i.pinimg.com/736x/c1/7b/15/c17b150e93c4e9c50d963b076484bee7--apple-wallpaper-iphone-wallpaper.jpg);
}
.img2 {
z-index: 2;
}
.img3 {
z-index: 0;
}
.img1:hover+.img2 {
opacity: 0;
}
<div class="img1"></div>
<div class="img2"></div>
<div class="img3"></div>
I fear z-index transition only makes the element pass step by step through every layer. To make a nice effect you need to combine it with opacity transition and scale / position transition. The fiddle to show you the idea:
.img1, .img2{
border: 1px solid black;
transition: 1s;
position: absolute;
}
.img1{
left: 25%;
height: 500px;
width: 500px;
z-index: 1;
transform: scale(0.9);
opacity: 0.5;
background-image: url(http://cdn.pcwallart.com/images/balloons-photography-vintage-wallpaper-1.jpg);
}
.img2{
right: 25%;
width: 500px;
height: 500px;
bottom: 0;
z-index: 2;
background-image: url(https://i.pinimg.com/736x/c1/7b/15/c17b150e93c4e9c50d963b076484bee7--apple-wallpaper-iphone-wallpaper.jpg);
}
.img1:hover{
animation: fronte 1s linear forwards;
}
#keyframes fronte {
from { z-index: 0; transform: scale(0.9); opacity: 0.5; }
to { z-index: 4; transform: scale(1.1); opacity: 1; }
}
<div class="img1">
</div>
<div class="img2">
</div>
This is the trick I used.
.minus{animation:move 2s;animation-fill-mode:forwards;animation-delay:2s;}
#-webkit-keyframes move {
0 {z-index:1;opacity:1}
50% {opacity:0}
100% { z-index:-1;opacity:1}
}
#keyframes move {
0 {z-index:1;opacity:1}
50% {opacity:0}
100% {z-index:-1;opacity:1}
}
#main{background:red;width:100vw;height:100vh;position:fixed;top:0;left:0;opacity:.9}
.minus{position:fixed;top:10px;left:10px;z-index:1;color:#000}
<div id="main"></div>
<div class="minus">FADE</div>
Related
I am working a project on my favorite science stories animated using HTML. While I was working on it By just changing the position to fixed or nothing position of all my objects was changing. If you remove the position property from #Guy, you will notice that the image of Galileo will shift drastically. I just want to know why this happens.
:root {
--initX: 280px;
--initY: 70px;
--finalY: 600px;
}
body {
background-color: aqua;
padding: 0px;
margin: 0px;
}
#Guy {
z-index: 4;
height: 200px;
position: fixed;
width: auto;
transform: translate(800px, 450px);
}
#Galilo {
height: 50px;
width: auto;
z-index: -1;
transform: translate(290px, 5px) rotateZ(4deg);
}
#tower {
height: 650px;
width: 150px;
z-index: 0;
transform: translate(250px, 50px) rotateZ(4deg);
position: absolute;
background-color: grey;
}
#Lball {
height: 40px;
width: 40px;
z-index: 2;
border-radius: 50%;
transform: translate(var( --initX), var(--initY));
background-color: blue;
position: absolute;
animation: lite 2s linear 1s infinite forwards;
}
#Hball {
height: 50px;
width: 50px;
z-index: 3;
transform: translate(calc(var( --initX) + 75px), var(--initY));
border-radius: 50%;
background-color: red;
position: absolute;
animation: heavy 2s linear 1s infinite forwards;
}
#floor {
height: 25%;
width: 100%;
background-color: green;
position: absolute;
z-index: -1;
transform: translate(0px, 565px);
}
#hide {
height: 12%;
width: 100%;
background-color: green;
position: absolute;
z-index: 1;
transform: translate(0px, 650px);
}
#keyframes lite {
0% {
transform: translate(var( --initX), var(--initY))
}
90% {
transform: translate(var(--initX), calc(var(--finalY) + 12.5px))
}
100% {
transform: translate(var(--initX), calc(var(--finalY) + 12.5px))
}
}
#keyframes heavy {
0% {
transform: translate(calc(var( --initX) + 75px), var(--initY))
}
90% {
transform: translate(calc(var( --initX) + 75px), var(--finalY))
}
100% {
transform: translate(calc(var( --initX) + 75px), var(--finalY))
}
}
<div id="tower"></div>
<div id="Hball"></div>
<div id="Lball"></div>
<div id="floor"></div>
<div id="hide"></div>
<img src="stick fidure.png" alt="Dude thinking" id="Guy">
<img src="galileo-galilei.png" alt="gallilo" id="Galilo">
P.S.
The link for the image of Galileo is https://cdn.images.express.co.uk/img/dynamic/109/590x/galileo-galilei-819977.jpg and the stick figure was made in Paint 3D
position: fixed takes the element out of the document flow and places it in relation to the viewport/window. Usually that also causes this element to overlap other elements. The other elements however will be rearranged in a way like the fixed element wouldn't be there (it's not in the document flow). So adding/removing position: fixed to/from an element will have all these effects on the overall document.
I want to achive a simple animation on hover in css, but while hovering off, the animation jumps and makes it look silly. Is there a way to avoid that?
My wish would be that it is colapsing the same way it originaly transformed.
Codepen: https://codepen.io/misah/pen/abzRXvL
.item {
width: 20%;
height: 0;
padding-top: 20%;
background-color: blue;
position: relative;
transition: 800ms;
}
.item::after {
position: absolute;
bottom: 0;
height: 30%;
width: 100%;
content: "";
background-color: grey;
transition: transform 800ms ease-in-out;
}
.item:hover::after {
transform: scaleY(2);
transform-origin: bottom;
}
<div class="item">
</div>
This happens because the transform-origin: bottom; is only applied when the item is hovered. When not hovered it falls back to the default - center. Move the rule to the declaration of the ::after.
.item {
width: 20%;
height: 0;
padding-top: 20%;
background-color: blue;
position: relative;
transition: 800ms;
}
.item::after {
position: absolute;
bottom: 0;
height: 30%;
width: 100%;
content: "";
background-color: grey;
transition: transform 800ms ease-in-out;
transform-origin: bottom;
}
.item:hover::after {
transform: scaleY(2);
}
<div class="item"></div>
I'm trying to make a 'dot' orbit around another object (circle) but due to the z-index the dot always appears above the circle it is meant orbiting around.
CodePen link: https://codepen.io/moy/pen/ROVZXd?editors=1100
Ideally the 2nd half of the animation would take place behind the object so it's not seen until it comes out the other side - is that possible?
I thought about fading out the object that is moving around but I don't think that would give a smooth/masked effect?
A bit stuck as to how I'd mask this area as I can't see a way the CSS would know it's meant to be hidden. I thought maybe I could change the z-index 50% though the animation it and reset it at 0%/100% but that doesn't appear to do anything.
Any ideas? Thanks in advance!
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 30px auto;
position: relative;
width: 100px;
z-index: 20;
}
.orbit {
border: 2px #eee transparent;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
z-index: 10;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
z-index: 10;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg); z-index: 20;
}
50% {
z-index: -20;
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg); z-index: 20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
I seem to have solved this by adding a negative z-index to an animation applied to the parent .orbit
Link: https://codepen.io/moy/pen/wZdpRw?editors=1100
I initially applied this at 50% through the animation as that should be the furthest away the dot is before it comes back behind the larger circle. However this didn't work, setting it on 100% did work. Not entirely sure why but it seems to work!
The initial issue was due to the fact that you are applying z-index to the parent element and doing so it will impossible to make the child to move behind it (Why elements with any z-index value can never cover its child?) thus changin z-index is useless
Even if you remove the z-index from the parent you still have the transform that is also creating a stacking context making impossible to the child element to move behind so you cannot make the .moon to move behind the .earth.
The only way to do it (like you already noticed) is to remove z-index from the .earth to avoid the earth creating a stacking context and animate z-index of orbit to make the orbit AND the moon moving behind the earth (not only the moon).
Add some coloration to better see this:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 60px auto;
position: relative;
width: 100px;
}
.orbit {
animation: hide ease-in-out infinite;
animation-duration: 2s;
background:red;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg);
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg);
}
}
#keyframes hide {
0% {
z-index: 20;
}
100% {
z-index: -20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
Now if you add back z-index to earth it will stop working because of the stacking context:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 60px auto;
position: relative;
width: 100px;
z-index:2;
}
.orbit {
animation: hide ease-in-out infinite;
animation-duration: 2s;
background:red;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg);
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg);
}
}
#keyframes hide {
0% {
z-index: 20;
}
100% {
z-index: -20;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
You can try key-framing the opacity:
.earth {
background: white;
border: 1px solid black;
border-radius: 50%;
display: block;
height: 100px;
margin: 30px auto;
position: relative;
width: 100px;
z-index: 20;
}
.orbit {
border: 2px #eee transparent;
border-radius: 50%;
height: 140px;
margin: auto;
position: absolute;
top: -20px;
left: -20px;
transform: rotateZ(60deg) rotateY(60deg);
transform-style: preserve-3d;
width: 140px;
z-index: 10;
}
.orbit .moon {
animation: move ease-in-out infinite;
animation-duration: 2s;
background: black;
border-radius: 50%;
height: 15px;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 15px;
z-index: 10;
}
#keyframes move {
0% {
transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg); opacity: 1;
}
56% {
opacity: 1;
}
58% {
opacity: 0;
}
77% {
opacity: 0;
}
78% {
opacity: 1;
}
100% {
transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg); opacity: 1;
}
}
<div class="earth">
<div class="orbit">
<div class="moon"></div>
</div>
</div>
For a web application meant for mobile browsers, I want to integrate this simple yet elegant preloader. It's going to reside on top of a translucent overlay. It's also going to have some words on top of it (e.g. "Please wait...", or "Hold on a minute..." etc).
I tried integrating all that. The result is below (run the snippet). It has 3 distinct problems (can you help me solve them all):
1) I haven't been able to position the preloader + it's text on top of the translucent overlay (although I've used a high z-index).
2) Moreover, the preloader graphic is getting skewed in accordance with the length of the sentence on top of it. I want it to be independent of that.
3) Lastly, they're not positioned in the exact middle (vertically speaking).
body{background:#ECF0F1}
.parent{
position:fixed;
z-index:1;
top:50%;
left:50%;
transform:translate(-50%, -50%);
}
.caption{
margin-bottom:1em;
color:gray;
position:relative;
z-index:10;
}
.load{
width:50px;
height:50px;
position:relative;
z-index:10;
}
.load hr{border:0;margin:0;width:40%;height:40%;position:fixed;border-radius:50%;animation:spin 2s ease infinite}
.load :first-child{background:#19A68C;animation-delay:-1.5s}
.load :nth-child(2){background:#F63D3A;animation-delay:-1s}
.load :nth-child(3){background:#FDA543;animation-delay:-0.5s}
.load :last-child{background:#193B48}
#keyframes spin{
0%,100%{transform:translate(0)}
25%{transform:translate(160%)}
50%{transform:translate(160%, 160%)}
75%{transform:translate(0, 160%)}
}
.overlay{
position:fixed;
width:100%;
height:100%;
top:0;
left:0;
opacity:0.6;
z-index:100;
background-color:#FFFFFF;
}
body {
background: #E8F5E9;
background: repeating-linear-gradient(
to right,
#FAFAFA,
#FAFAFA 50px,
#E8F5E9 50px,
#E8F5E9 100px
);
}
<body>
<div class="overlay">
<div class="parent">
<div class="caption">Lorem ipsum dolor sit amet ...</div>
<div class="load">
<hr><hr><hr><hr>
</div>
</div>
</div>
<body>
Note: I'm hoping for pure CSS solutions, no JS involvement. I'd also want to avoid flex-box, and go for something universal (in a backward compatibility sense). E.g. flex-box support dwindles in older versions of Android browser (according to caniuse.com). I want to respect those versions too, hence it's best to stick to well-supported CSS 2.1 properties.
The issue is with the hr element they are placed fixed and they should be absolute to keep their relation with parent container. And then simply add margin:auto to load to center them.
And since parent and overlay elements are both fixed position you can separate them to be able to correctly use z-index and avoid the opacity being applied of overlay:
body {
background: #ECF0F1
}
.parent {
position: fixed;
z-index: 1000;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.caption {
margin-bottom: 1em;
color: gray;
position: relative;
z-index: 10;
}
.load {
width: 50px;
height: 50px;
position: relative;
z-index: 10;
margin: auto;
}
.load hr {
border: 0;
margin: 0;
width: 40%;
height: 40%;
position: absolute;
border-radius: 50%;
animation: spin 2s ease infinite
}
.load :first-child {
background: #19A68C;
animation-delay: -1.5s
}
.load :nth-child(2) {
background: #F63D3A;
animation-delay: -1s
}
.load :nth-child(3) {
background: #FDA543;
animation-delay: -0.5s
}
.load :last-child {
background: #193B48
}
#keyframes spin {
0%,
100% {
transform: translate(0)
}
25% {
transform: translate(160%)
}
50% {
transform: translate(160%, 160%)
}
75% {
transform: translate(0, 160%)
}
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
opacity: 0.6;
z-index: 100;
background-color: #FFFFFF;
}
body {
background: #E8F5E9;
background: repeating-linear-gradient( to right, #FAFAFA, #FAFAFA 50px, #E8F5E9 50px, #E8F5E9 100px);
}
<div class="overlay">
</div>
<div class="parent">
<div class="caption">Lorem ipsum dolor sit amet ...</div>
<div class="load">
<hr>
<hr>
<hr>
<hr>
</div>
</div>
The preloader is a child of the overlay, therefore it will have the parent opacity, no way to avoid that but setting it outside the overlay, maybe as a sibling, and adjust the overlay with a negative z-index
As for the sizing, the he are ignoring the parent size as they are set to position:fixed, should be absolute
body {
background: #ECF0F1
}
.parent {
position: fixed;
z-index: 1;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.caption {
margin-bottom: 1em;
color: gray;
position: relative;
z-index: 10;
}
.load {
width: 50px;
height: 50px;
position: relative;
z-index: 10;
margin: auto;
}
.load hr {
border: 0;
margin: 0;
width: 40%;
height: 40%;
position: absolute;
border-radius: 50%;
animation: spin 2s ease infinite
}
.load :first-child {
background: #19A68C;
animation-delay: -1.5s
}
.load :nth-child(2) {
background: #F63D3A;
animation-delay: -1s
}
.load :nth-child(3) {
background: #FDA543;
animation-delay: -0.5s
}
.load :last-child {
background: #193B48
}
#keyframes spin {
0%,
100% {
transform: translate(0)
}
25% {
transform: translate(160%)
}
50% {
transform: translate(160%, 160%)
}
75% {
transform: translate(0, 160%)
}
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
opacity: 0.6;
z-index: -10;
background-color: #FFFFFF;
}
body {
background: #E8F5E9;
background: repeating-linear-gradient( to right, #FAFAFA, #FAFAFA 50px, #E8F5E9 50px, #E8F5E9 100px);
}
<div class="overlay">
</div>
<div class="parent">
<div class="caption">Lorem ipsum dolor sit amet ...</div>
<div class="load">
<hr>
<hr>
<hr>
<hr>
</div>
</div>
I need to do a task where I have an image, this image is being covered in some color fade, and when I hover on image - fade dissapears (the example is https://html5up.net/uploads/demos/forty/ ). I did it, but I also have to do a transition so that disappearing of fade will be slower for 2 seconds. I tried to put transition property everywhere and I failed. Any help, please?
.photo-text.one {
background-size: cover;
background: url("https://i2.wp.com/www.thehopelesshousewife.com/wp-content/uploads/2013/12/Christmas-No-Bake-Nachos-576x409.jpg") no-repeat center top;
height: 409px;
position: relative;
width: 576px;
}
.img-overlay {
width: 100%;
height: 100%;
background: #6fc3df;
opacity: 0.75;
}
.photo-text.one:hover:after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: url("https://i2.wp.com/www.thehopelesshousewife.com/wp-content/uploads/2013/12/Christmas-No-Bake-Nachos-576x409.jpg") no-repeat center top;
}
.text {
position: absolute;
top: 100px;
left: 150px;
color: red;
z-index: 1;
}
<div class="photo-text one">
<div class="img-overlay"></div>
<h2 class="text">fffff</h2>
</div>
Instead of this block of code :
.photo-text.one:hover:after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: url("https://i2.wp.com/www.thehopelesshousewife.com/wp-content/uploads/2013/12/Christmas-No-Bake-Nachos-576x409.jpg") no-repeat center top;
}
You can simplify by simply hiding the overlay by modifying its opacity to 0 with the transition of opacity and the duration you need:
.photo-text.one:hover > .img-overlay{
transition: opacity 1.5s ease-in-out;
opacity: 0;
}
.photo-text.one {
background-size: cover;
background: url("https://i2.wp.com/www.thehopelesshousewife.com/wp-content/uploads/2013/12/Christmas-No-Bake-Nachos-576x409.jpg") no-repeat center top;
height: 409px;
position: relative;
width: 576px;
}
.img-overlay {
width: 100%;
height: 100%;
background: #6fc3df;
opacity: 0.75;
transition: opacity 1s ease-in-out;
}
.photo-text.one:hover > .img-overlay{
transition: opacity 1.5s ease-in-out;
opacity: 0;
}
.text {
position: absolute;
top: 100px;
left: 150px;
color: red;
z-index: 1;
}
<div class="photo-text one">
<div class="img-overlay"></div>
<h2 class="text">fffff</h2>
</div>
You could just hover over the .img-overlay, but since you also want to have the same effect when hovering over the text, leave it as it is and just replace the :after pseudo-element (don't need it) with the > .img-overlay, set its opacity to 0 and apply the transition property as desired:
.photo-text.one {
background-size: cover;
background: url("https://i2.wp.com/www.thehopelesshousewife.com/wp-content/uploads/2013/12/Christmas-No-Bake-Nachos-576x409.jpg") no-repeat center top;
height: 409px;
position: relative;
width: 576px;
max-width: 100%; /* responsiveness */
}
.img-overlay {
position: absolute; /* needs to be on the child since the relative position is on the parent */
width: 100%;
height: 100%;
background: #6fc3df;
opacity: 0.75;
transition: opacity 2s linear; /* optional / when "unhovering" */
}
/* added */
.photo-text.one:hover > .img-overlay {
opacity: 0;
transition: opacity 2s linear; /* can also try other values such as "ease", "ease-out" etc. */
}
.text {
position: absolute;
top: 100px;
left: 150px;
color: red;
z-index: 1;
}
<div class="photo-text one">
<div class="img-overlay"></div>
<h2 class="text">fffff</h2>
</div>