Hover on 3D carousel element in CSS only - css

I'm trying to figure out how to make the carousel element stand still when hovered (keep it in the same position where the cursor is) but it keeps changing the position to the center of the whole thing like in this picture:
The idea is to build a 3D carousel that rotates till the user hovers over it, then it stops, the hovered element grows (inviting to click on it), and if unhover animation continues, but for some reason element keeps changing position :c
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- <link rel="stylesheet" href="../css/test.css"> -->
<title>Document</title>
</head>
<style>
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.slider {
position: relative;
width: 200px;
height: 200px;
transform-style: preserve-3d;
animation: rotate 30s linear infinite;
}
#keyframes rotate {
0% {
transform: perspective(1000px) rotateY(0deg);
}
100% {
transform: perspective(1000px) rotateY(360deg);
}
}
.slider div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-origin: center;
transform-style: preserve-3d;
transform: rotateY(calc(var(--i)*40deg)) translateZ(350px);
background-color: black;
}
.slider img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
transition: 2s;
}
.slider div:hover {
transform: translateY(-50px) scale(1.2);
}
.slider:hover {
animation-play-state: paused;
}
</style>
<body>
<div class="slider">
<div style="--i:1"><img src=""></div>
<div style="--i:2"><img src=""></div>
<div style="--i:3"><img src=""></div>
<div style="--i:4"><img src=""></div>
<div style="--i:5"><img src=""></div>
<div style="--i:6"><img src=""></div>
<div style="--i:7"><img src=""></div>
<div style="--i:8"><img src=""></div>
<div style="--i:9"><img src=""></div>
</div>
</body>
</html>
Do you guys know any solutions?

Apply the transformation to the image on hover instead of the div. I also updated the code a little to optimize it using CSS grid instead of absolute position:
body {
height: 100vh;
margin: 0;
display: grid;
place-content: center;
}
.slider {
display: grid;
width: 150px;
height: 150px;
transform-style: preserve-3d;
animation: rotate 30s linear infinite;
}
#keyframes rotate {
0% {
transform: perspective(1000px) rotateY(0deg);
}
100% {
transform: perspective(1000px) rotateY(360deg);
}
}
.slider div {
grid-area: 1/1;
transform-style: preserve-3d;
transform: rotateY(calc(var(--i)*40deg)) translateZ(250px);
}
.slider img {
width: 100%;
height: 100%;
object-fit: cover;
transition: 1s;
}
.slider div:hover img{
transform: translateY(-50px) scale(1.2);
}
.slider:hover {
animation-play-state: paused;
}
<div class="slider">
<div style="--i:1"><img src="https://picsum.photos/id/1051/200/200"></div>
<div style="--i:2"><img src="https://picsum.photos/id/1051/200/200"></div>
<div style="--i:3"><img src="https://picsum.photos/id/1051/200/200"></div>
<div style="--i:4"><img src="https://picsum.photos/id/1051/200/200"></div>
<div style="--i:5"><img src="https://picsum.photos/id/1051/200/200"></div>
<div style="--i:6"><img src="https://picsum.photos/id/1051/200/200"></div>
<div style="--i:7"><img src="https://picsum.photos/id/1051/200/200"></div>
<div style="--i:8"><img src="https://picsum.photos/id/1051/200/200"></div>
<div style="--i:9"><img src="https://picsum.photos/id/1051/200/200"></div>
</div>

Related

Must perspective be set on the parent element of `transform style: preserve-3d` element?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<style>
.scene {
width: 200px;
height: 200px;
margin: 0 auto;
perspective: 600px;
}
.cube {
width: 100%;
height: 100%;
transition: all 3s;
position: relative;
transform-style: preserve-3d;
transform-origin: center center -100px;
}
.cube:hover {
transform: rotateY(360deg);
}
.cube__face {
position: absolute;
width: 100%;
height: 100%;
line-height: 200px;
text-align: center;
background-color: aquamarine;
}
.cube__face_front {
z-index: 1;
}
.cube__face_right {
transform-origin: left;
transform: rotateY(90deg);
right: -200px;
}
.cube__face_back {
transform: translateZ(-200px) rotateY(180deg);
}
.cube__face_left {
transform-origin: right;
transform: rotateY(-90deg);
left: -200px;
}
.cube__face_top {
transform-origin: bottom;
transform: rotateX(90deg);
top: -200px;
}
.cube__face_bottom {
transform-origin: top;
transform: rotateX(-90deg);
bottom: -200px;
}
</style>
</head>
<body>
<div class="scene">
<div class="cube">
<div class="cube__face cube__face_front">front</div>
<div class="cube__face cube__face_back">back</div>
<div class="cube__face cube__face_right">right</div>
<div class="cube__face cube__face_left">left</div>
<div class="cube__face cube__face_top">top</div>
<div class="cube__face cube__face_bottom">bottom</div>
</div>
</div>
</body>
</html>
If the perspective is set on the. scene element, everything is ok, but I set the perspective on the .cube, as shown below. What's the difference?
.scene {
width: 200px;
height: 200px;
margin: 0 auto;
}
.cube {
width: 100%;
height: 100%;
transition: all 3s;
position: relative;
transform-style: preserve-3d;
transform-origin: center center -100px;
perspective: 600px; //Move perspective from .scene to here
}

scale and transform img on hover

So what I'm trying to make is a banner that has scale and transform like in this webpage: https://www.johannesfog.dk/
So the two landscape images overlap each other on hover.
This is how far I got:
<div class="container">
<div class="image1">
<a href="#">
<img src="">
</a>
</div>
<div class="image2">
<a href="#">
<img src="">
</a>
</div>
</div>
<script src=""></script>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
display: flex;
flex-wrap: wrap;
overflow: hidden;
}
.container .image1 {
width: 50%;
overflow: hidden;
}
.container .image2 {
width: 50%;
overflow: hidden;
}
.container img {
width: calc(100% - (0px * 2));
}
.container .image1:hover {
transform: scale(1.5);
transform: translate(50%, 0%);
overflow: hidden;
transition: ease-in-out, transform .3s ease-in-out;
}
.container .image2:hover {
transform: scale(1.5);
transform: translate(-50%, 0%);
overflow: hidden;
transition: ease-in-out, transform .3s ease-in-out;
}
Right now the img only transform.

how to flip div on hover using css [duplicate]

This question already has answers here:
how to flip the div using css?
(3 answers)
Closed 2 years ago.
i am trying to show backside of card on hover using css. i tried below code but its just roates front div and doesn't display back div. also i want to hide front div on hover. Can anyone fix this problem?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.content {
position: relative;
}
.front {
background: darkred;
width: 200px;
height: 200px;
transition: 0.5s;
position: absolute;
z-index: 1;
}
.back {
background: darkblue;
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.content:hover .front {
transform: rotateY(180deg);
}
</style>
</head>
<body>
<div class="content">
<div class="front">Hello</div>
<div class="back">Bye</div>
</div>
</body>
</html>
i try to solve you question and this is my answer....
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.content {
position: relative;
}
.front {
background: darkred;
width: 200px;
height: 200px;
transition: 0.5s;
position: absolute;
z-index: 1;
}
.back {
background: darkblue;
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.content:hover .front {
transform: rotateY(180deg);
opacity: 0;
}
</style>
</head>
<body>
<div class="content">
<div class="front">Hello</div>
<div class="back">Bye</div>
</div>
</body>
</html>
Just change
.content:hover .front {
transform: rotateY(180deg);
}
to
.content:hover .front {
display: none
}
Check out this
https://jsfiddle.net/1dsv7e6b/1/
Please add opacity:0;
.content:hover .front {
transform: rotateY(180deg);
opacity:0;
}
You could use CSS animations here to give the effect of the card flipping but then also being hidden.
The #keyframes defines the animation. Here it starts at 0% with no rotation and opacity of 1 (i.e. visible).
Then at 100% the animation is complete at the rotation is 180 degrees and opacity set to 0 so that it is hidden.
#keyframes flip-card {
0% {
transform: rotateY(0deg);
opacity: 1;
}
100% {
transform: rotateY(180deg);
opacity: 0;
}
}
You can then apply this on hover like so:
.content:hover .front {
animation: flip-card 1s;
animation-fill-mode: forwards;
}
You use the animation property to call the animation and also add how long it should take.
An example can be seen here:
https://jsfiddle.net/368jr1ts/
.content {
position: relative;
}
.front {
background: darkred;
width: 200px;
height: 200px;
transition: 0.5s;
position: absolute;
z-index: 1;
}
.back {
background: darkblue;
width: 200px;
height: 200px;
position: absolute;
top: 0;
left: 0;
}
.content:hover .front {
transform: rotateY(180deg);
opacity: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="content">
<div class="front">Hello</div>
<div class="back">Bye</div>
</div>
</body>
</html>

In CSS flip,TransformZ elements not on top

I have the following snippet to illustrate this issue.
According to everything I have read, elements positioned using transformZ should be on top as they are 'closer.' I can't position the active/flipped card 'on top' using z-index because flickering occurs during the transition. Yet the elements are positioned in the default order of the browser, which means the later elements are on top. Transform-style and perspective are both applied to the parents.
Why aren't the closer elements on top?
.card {
position: relative;
width: 33.333%; height: 12rem;
float: left;
transform-style: preserve-3d;
perspective: 30rem;
}
.front, .back {
position: absolute;
width: 100%; height: 100%;
transition: transform 1s;
backface-visibility:hidden;
}
.front {
background-color: #66ccff;
}
.back {
background-color: #dd8800;
transform: rotateY(180deg);
}
.card:hover .front{ transform: rotateY(180deg);}
.card:hover .back { transform: rotateY(360deg) translateZ(5em);}
.card2 {
position: relative;
width: 33.333%; height: 12rem;
perspective: 30rem;
float: left;
}
.front2, .back2 {
position: absolute;
width: 100%; height: 100%;
transition: transform 1s;
backface-visibility:hidden;
}
.front2 {
background-color: #66ccff;
}
.back2 {
background-color: #dd8800;
transform: rotateY(180deg);
z-index: 99;
}
.card2:hover .front2 { transform: rotateY(180deg);}
.card2:hover .back2 { transform: rotateY(360deg) translateZ(5em);}
.card3 {
position: relative;
width: 33.333%; height: 12rem;
perspective: 30rem;
float: left;
}
.front3, .back3 {
position: absolute;
width: 100%; height: 100%;
transition: transform 1s;
backface-visibility:hidden;
}
.front3 {
background-color: #66ccff;
}
.back3 {
background-color: #dd8800;
transform: rotateY(180deg);
z-index: 99;
}
.card3:hover .front3 { transform: rotateY(180deg);}
.card3:hover .back3 { transform: rotateY(360deg) translateZ(5em);}
<div class="card">
<div class="front">
<span>Front</span>
</div>
<div class="back">
<span>Back</span>
</div>
</div>
<div class="card2">
<div class="front2">
<span>Front</span>
</div>
<div class="back2">
<span>Back</span>
</div>
</div>
<div class="card3">
<div class="front3">
<span>Front</span>
</div>
<div class="back3">
<span>Back</span>
</div>
</div>
It's because the use of persepctive create a stacking context
Using this property with a value different than 0 and none creates a new stacking context. Also, in that case, the object will act as a containing block for position: fixed elements that it contains.ref
So what you said is all true but it happens inside the card element then the card elements are positionned considering the tree order.
An easy fix is to adjust z-index of card element considering some delay to avoid the bad effect.
.card {
position: relative;
width: 33.333%; height: 12rem;
float: left;
transform-style: preserve-3d;
perspective: 30rem;
z-index:0;
transition:z-index 0s .5s;
}
.front, .back {
position: absolute;
width: 100%; height: 100%;
transition: transform 1s;
backface-visibility:hidden;
}
.front {
background-color: #66ccff;
}
.back {
background-color: #dd8800;
transform: rotateY(180deg);
}
.card:hover .front{ transform: rotateY(180deg);}
.card:hover .back { transform: rotateY(360deg) translateZ(5em);}
.card:hover {
z-index:1;
}
<div class="card">
<div class="front">
<span>Front</span>
</div>
<div class="back">
<span>Back</span>
</div>
</div>
<div class="card">
<div class="front">
<span>Front</span>
</div>
<div class="back">
<span>Back</span>
</div>
</div>
<div class="card">
<div class="front">
<span>Front</span>
</div>
<div class="back">
<span>Back</span>
</div>
</div

3D Transform (rotateY) in Chrome and Firefox do react differently

I created a CSS 3D Transformation for a logo div within a header of my page. On hover the logo gets rotated. Everything looks fine in Chrome, but Firefox renders it completely different.
I moved the transform origin to the left side of the logo div. When rotating the right side of the div gets "compressed" to get the visual 3D effect. In Firefox the logo div only gets smaller but not "compressed" and you can't see a 3D effect.
The Code:
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<title>test</title>
<style>
#header {
width: 940px;
margin: auto;
background-color: blue;
height: 350px;
position: relative;
-webkit-perspective: 800;
-moz-perspective: 800;
}
#logo {
width: 300px;
height: 80px;
background-color: red;
position: absolute;
top: 50px;
left: 0px;
-webkit-transition-duration: 0.25s;
-webkit-transform-origin: 0% 50%;
-webkit-transform-style: preserve-3d;
-webkit-transform: rotate3d(0,1,0,0deg);
-moz-transition-duration: 0.25s;
-moz-transform-origin: 0% 50%;
-moz-transform-style: preserve-3d;
-moz-transform: rotate3d(0,1,0,0deg);
}
#logo:hover {
-webkit-transition-duration: 0.5s;
-webkit-transform: rotate3d(0,1,0,45deg);
-moz-transition-duration: 0.5s;
-moz-transform: rotate3d(0,1,0,45deg);
}
</style>
</head>
<body>
<div id="header">
<div id="logo"></div>
</div>
</body>
</html>
Please try the following JSFiddle: http://jsfiddle.net/4CN5g/
Any idea what I'm doing wrong?

Resources