I have to make a site which presents a menu of desserts for a restaurant. I used JS to make a flip-book animation. My site should mainly be adapted for phones. The problem is that on the phone when I "open" the card, the left part of menu is off the screen and I cannot scroll to get it.
Can anyone help me?
var currentPage = 0;
$(".book").on("click", ".active", nextPage).on("click", ".flipped", prevPage);
$(".book").hammer().on("swipeleft", nextPage);
$(".book").hammer().on("swiperight", prevPage);
function prevPage() {
$(".flipped")
.last()
.removeClass("flipped")
.addClass("active")
.siblings(".page")
.removeClass("active");
}
function nextPage() {
$(".active")
.removeClass("active")
.addClass("flipped")
.next(".page")
.addClass("active")
.siblings();
}
html {
height: 100%;
}
body {
background-color: black;
margin: 0;
width: 100%;
height: 100%;
overflow: scroll;
}
.scene {
width: 560px;
height: 793px;
margin: 80px auto;
-webkit-perspective: 2000px;
perspective: 2000px;
}
.book {
position: relative;
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.page {
cursor: pointer;
position: absolute;
color: black;
width: 100%;
height: 100%;
-webkit-transition: 1.5s -webkit-transform;
transition: 1.5s transform;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: left center;
-ms-transform-origin: left center;
transform-origin: left center;
}
.front,
.back {
position: absolute;
width: 100%;
height: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
background: -webkit-gradient(
linear,
0% 0%,
100% 100%,
from(#ffffff),
to(#cccccc)
);
background: -webkit-gradient(
linear,
left top,
right bottom,
from(#fff),
to(#ccc)
);
background: -webkit-linear-gradient(top left, #fff, #ccc);
background: linear-gradient(to bottom right, #fff, #ccc);
}
.back {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
}
.page.active {
z-index: 1;
}
.page.flipped {
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}
.page.flipped:last-of-type {
z-index: 1;
}
p {
margin: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
</head>
<body>
<div class="scene">
<article class="book">
<section class="page active">
<div class="front">
<p><img src="https://via.placeholder.com/559x751.jpg?text=Page%20A"></p>
</div>
<div class="back">
<p><img src="https://via.placeholder.com/559x751.jpg?text=Page%20A%20Back"></p>
</div>
</section>
<section class="page">
<div class="front">
<p><img src="https://via.placeholder.com/559x751.jpg?text=Page%20B"></p>
</div>
<div class="back">
<p><img src="https://via.placeholder.com/559x751.jpg?text=Page%20B%20Back"></p>
</div>
</section>
</article>
</div>
</body>
</html>
Thank you in advance.
Related
I took this Pen: https://codepen.io/golle404/pen/BoqrEN and wanted to make it move every few seconds.
I tried this:
setTimeout(function() {
document.getElementById("move").style.transform = "rotateY(203deg)";
}, 2000);
but this moves the object once and I want to make the cube spin infinite with 3 stops.
So like the cube rotates to 203deg and should stay there for 2 seconds and move to 180deg for example - in a infinite loop.
Is there a way to do it ? Or is it not possible.
You can use a keyframe animation for this.
For example:
#keyframes rotation {
0%, 100% {
transform: rotateX(90deg) translateZ(-150px);
}
33.333% {
transform: translateZ(150px);
}
66.666% {
transform: rotateY(90deg) translateZ(150px);
}
}
And then you use it like this
.my-element {
animation: rotation 5s infinite;
}
Here it is in combination with your code from the codepen:
.container {
margin-top: 150px;
}
.news-grid {
width: 300px;
margin: auto;
}
.news-card {
width: 300px;
height: 300px;
perspective: 800px;
perspective-origin: 50% 50%;
outline: 1px solid blue;
}
.face>img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#experiment {
-webkit-perspective: 800px;
-webkit-perspective-origin: 50% 200px;
-moz-perspective: 800px;
-moz-perspective-origin: 50% 200px;
perspective: 800px;
perspective-origin: 50% 200px;
}
.cube {
position: relative;
margin: auto;
height: 300px;
width: 300px;
-webkit-transition: -webkit-transform 2s linear;
-webkit-transform-style: preserve-3d;
-moz-transition: -moz-transform 2s linear;
-moz-transform-style: preserve-3d;
transition: transform 2s linear;
transform-style: preserve-3d;
transform: rotateY(245deg);
animation: rotation 5s infinite;
}
.face {
position: absolute;
height: 260px;
width: 260px;
padding: 20px;
background-color: rgba(50, 50, 50, 0.7);
font-size: 27px;
line-height: 1em;
color: #fff;
border: 1px solid #555;
border-radius: 3px;
}
#keyframes rotation {
0%,
100% {
transform: rotateX(90deg) translateZ(-150px);
}
33.333% {
transform: translateZ(150px);
}
66.666% {
transform: rotateY(90deg) translateZ(150px);
}
}
<div class="container">
<div class="news-grid">
<div class="news-card">
<div class="cube">
<div class="face one"></div>
<div class="face two">
<img src="http://images.sixrevisions.com/2010/10/13-01_information_architecture_101_ld_img.jpg" alt="" /></div>
<div class="face three">
Information Architecture 101: Techniques and Best Practices
</div>
</div>
</div>
</div>
</div>
You need to use setInterval, not setTimeout
I made a HTML cube and animated its rotation after clicking on it. The cube rotates 90 degrees each time you click on it. I have an animation that makes 360 degrees.It pauses after 1/4 of animation total duration and runs again after click. That way we can see each of side faces in turn - 1,2,3,4.
But after about 10 clicks it is clear that angle is more than 90 but and view is not isometric anymore.
How to make this cube turn exactly 90 degrees and look right?
Probably it is not good to rely on duration. It could be easier if browser could watch angle and pause animation-play-state on 90, 180, 270, 360 degrees
var spinner = document.getElementById('spinner');
// get animation duration in ms
var animationDuration = parseFloat(window.getComputedStyle(spinner)['animation-duration'])*1000;
spinner.addEventListener('click', function () {
// run animation
spinner.style['animation-play-state'] = 'running';
// pause animation after animationDuration / 4
setTimeout(function () {
spinner.style['animation-play-state'] = 'paused';
}, animationDuration / 4);
});
body {
-webkit-font-smoothing: antialiased;
margin: 0;
}
* {
box-sizing: border-box;
}
.container {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 100px;
color: black;
}
.scene {
position: relative;
width: 120px;
height: 120px;
transform-style: preserve-3d;
transform: rotatex(-33.5deg) rotatey(45deg);
}
.face {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 100px;
background: rgba(141, 148, 249, 0.5);
line-height: 100px;
border: 2px solid white;
}
.face-front {
transform: rotateY(360deg) translateZ(60px);
}
.face-right {
transform: rotateY(90deg) translatez(60px);
}
.face-back {
transform: rotateY(180deg) translatez(60px);
}
.face-left {
transform: rotateY(270deg) translateZ(60px);
}
.face-top {
transform: rotatex(90deg) translatez(60px);
}
.face-bottom {
transform: rotatex(-90deg) translatez(60px);
}
#spinner {
position: absolute;
display: inline-block;
width: 120px;
height: 120px;
left: 0;
top: 0;
transform-style: preserve-3d;
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 4s;
animation-play-state: paused;
transform-style: preserve-3d;
}
#keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
<!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" />
<title>Document</title>
</head>
<body>
<div class="container">
<div class="scene">
<div id="spinner">
<div class="face face-left">1</div>
<div class="face face-front">2</div>
<div class="face face-right">3</div>
<div class="face face-back">4</div>
<div class="face face-top">5</div>
<div class="face face-bottom">6</div>
</div>
</div>
</div>
</body>
</html>
Using the duration isn't recommended as you stated.
One other way is to use the transform css style, and add 90 degrees to it on each click:
Then we only need one more CSS rule to add some 'animation' to the transform:
transition: transform 1s ease;
var spinner = document.getElementById('spinner');
var scene = document.getElementsByClassName('scene')[0];
let currentRotation = 45;
spinner.addEventListener('click', function () {
currentRotation += 90; // Or change to -= to go clockwise
scene.style['transform'] = `rotatex(-33.5deg) rotatey(${currentRotation}deg)`;
});
body {
-webkit-font-smoothing: antialiased;
margin: 0;
}
* {
box-sizing: border-box;
}
.container {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 100px;
color: black;
}
.scene {
position: relative;
width: 120px;
height: 120px;
transform-style: preserve-3d;
transform: rotatex(-33.5deg) rotatey(45deg);
transition: transform 1s ease;
}
.face {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 100px;
background: rgba(141, 148, 249, 0.5);
line-height: 100px;
border: 2px solid white;
}
.face-front {
transform: rotateY(360deg) translateZ(60px);
}
.face-right {
transform: rotateY(90deg) translatez(60px);
}
.face-back {
transform: rotateY(180deg) translatez(60px);
}
.face-left {
transform: rotateY(270deg) translateZ(60px);
}
.face-top {
transform: rotatex(90deg) translatez(60px);
}
.face-bottom {
transform: rotatex(-90deg) translatez(60px);
}
#spinner {
position: absolute;
display: inline-block;
width: 120px;
height: 120px;
left: 0;
top: 0;
transform-style: preserve-3d;
animation-name: spinner;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 4s;
animation-play-state: paused;
transform-style: preserve-3d;
}
#keyframes spinner {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(-360deg);
}
}
<div class="container">
<div class="scene">
<div id="spinner">
<div class="face face-left">1</div>
<div class="face face-front">2</div>
<div class="face face-right">3</div>
<div class="face face-back">4</div>
<div class="face face-top">5</div>
<div class="face face-bottom">6</div>
</div>
</div>
</div>
I found this flip animation on the internet and I was wondering: How can I change the javascript that instead of hovering over the image will cause the flip, a set time wil? So for instance after 3 seconds, the animation will start.
I am not so good with javascript yet and I am hoping someone can help me out
Thank you very much If you know the solution!
$(document).ready(function() {
$(".container").hover(function() {
$(".card").toggleClass('flipped')
}, function() {
$(".card").toggleClass('flipped')
});
})
h1 {
text-align: center;
}
.container {
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
-webkit-perspective: 800px;
-moz-perspective: 800px;
-o-perspective: 800px;
perspective: 800px;
display: inline-block;
}
#main {
border: 1px solid black;
}
button {
width: 30%;
height: 10%;
margin-top: 100px;
cursor: default;
}
.card {
width: 100%;
height: 100%;
position: absolute;
-webkit-transition: -webkit-transform 1s;
-moz-transition: -moz-transform 1s;
-o-transition: -o-transform 1s;
transition: transform 1s;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: right center;
-moz-transform-origin: right center;
-o-transform-origin: right center;
transform-origin: right center;
}
.card.flipped {
-webkit-transform: translateX( -100%) rotateY( -180deg);
-moz-transform: translateX( -100%) rotateY( -180deg);
-o-transform: translateX( -100%) rotateY( -180deg);
transform: translateX( -100%) rotateY( -180deg);
}
.card div {
height: 100%;
width: 100%;
color: white;
text-align: center;
font-weight: bold;
position: absolute;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
cursor: pointer;
}
.card .front {
background: red;
display: flex;
justify-content: center;
align-items: center;
}
/*
.card .front p {
margin-top: 100px;
}
*/
.card .back p {
margin: auto;
}
.card .back {
background: blue;
-webkit-transform: rotateY( 180deg);
-moz-transform: rotateY( 180deg);
-o-transform: rotateY( 180deg);
transform: rotateY( 180deg);
display: flex;
justify-content: center;
align-items: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
<div id="main"><br>
<section class="container">
<div class="card">
<div class="front">
<p>Test</p>
</div>
<div class="back">
<p>MyBack</p>
</div>
</div>
</section>
</div>
</div>
Why not do it with CSS?
On hover pseudo class with a transition:
h1 {
text-align: center;
}
.container {
--card-transition-duration: 1s;
--card-transition-delay: 4s;
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
perspective: 800px;
display: inline-block;
}
#main {
border: 1px solid black;
}
button {
width: 30%;
height: 10%;
margin-top: 100px;
cursor: default;
}
.card {
width: 100%;
height: 100%;
position: absolute;
transition: transform var(--card-transition-duration) ease var(--card-transition-delay);
transform-style: preserve-3d;
transform-origin: right center;
}
.container:hover .card {
transform: translateX( -100%) rotateY( -180deg);
}
.card div {
height: 100%;
width: 100%;
color: white;
text-align: center;
font-weight: bold;
position: absolute;
backface-visibility: hidden;
cursor: pointer;
}
.card .front {
background: red;
display: flex;
justify-content: center;
align-items: center;
}
.card .back p {
margin: auto;
}
.card .back {
background: blue;
transform: rotateY( 180deg);
display: flex;
justify-content: center;
align-items: center;
}
<div class="container-fluid">
<div id="main"><br>
<section class="container">
<div class="card">
<div class="front">
<p>Test</p>
</div>
<div class="back">
<p>MyBack</p>
</div>
</div>
</section>
</div>
</div>
Or by itself with #keyframes animation:
h1 {
text-align: center;
}
.container {
--card-transition-duration: 1s;
--card-transition-delay: 4s;
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
perspective: 800px;
display: inline-block;
}
#main {
border: 1px solid black;
}
button {
width: 30%;
height: 10%;
margin-top: 100px;
cursor: default;
}
.card {
width: 100%;
height: 100%;
position: absolute;
transition: transform var(--card-transition-duration) ease var(--card-transition-delay);
transform-style: preserve-3d;
transform-origin: right center;
animation-name: flip;
animation-duration: 5s;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.card div {
height: 100%;
width: 100%;
color: white;
text-align: center;
font-weight: bold;
position: absolute;
backface-visibility: hidden;
cursor: pointer;
}
.card .front {
background: red;
display: flex;
justify-content: center;
align-items: center;
}
.card .back p {
margin: auto;
}
.card .back {
background: blue;
transform: rotateY( 180deg);
display: flex;
justify-content: center;
align-items: center;
}
#keyframes flip {
0% {
transform: translateX( 0%) rotateY( 0deg);
}
35% {
transform: translateX( 0%) rotateY( 0deg);
}
65% {
transform: translateX( -100%) rotateY( -180deg);
}
100% {
transform: translateX( -100%) rotateY( -180deg);
}
}
<div class="container-fluid">
<div id="main"><br>
<section class="container">
<div class="card">
<div class="front">
<p>Test</p>
</div>
<div class="back">
<p>MyBack</p>
</div>
</div>
</section>
</div>
</div>
First, that's not justjavascript, it's jQuery. If you want the animation to start with a delay using the jquery code, you can add a setTimeout.
And if you use the callback function of the hover method, use add/remove class not toggle.
You could do it in multiple ways, even with just CSS and animations.
$(document).ready(function() {
$(".container").hover(function() {
setTimeout(() => { $(".card").addClass('flipped')},3000)
}, function() {
$(".card").removeClass('flipped')
});
})
h1 {
text-align: center;
}
.container {
width: 200px;
height: 260px;
position: relative;
margin: 0 auto 40px;
-webkit-perspective: 800px;
-moz-perspective: 800px;
-o-perspective: 800px;
perspective: 800px;
display: inline-block;
}
#main {
border: 1px solid black;
}
button {
width: 30%;
height: 10%;
margin-top: 100px;
cursor: default;
}
.card {
width: 100%;
height: 100%;
position: absolute;
-webkit-transition: -webkit-transform 1s;
-moz-transition: -moz-transform 1s;
-o-transition: -o-transform 1s;
transition: transform 1s;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: right center;
-moz-transform-origin: right center;
-o-transform-origin: right center;
transform-origin: right center;
}
.card.flipped {
-webkit-transform: translateX( -100%) rotateY( -180deg);
-moz-transform: translateX( -100%) rotateY( -180deg);
-o-transform: translateX( -100%) rotateY( -180deg);
transform: translateX( -100%) rotateY( -180deg);
}
.card div {
height: 100%;
width: 100%;
color: white;
text-align: center;
font-weight: bold;
position: absolute;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
cursor: pointer;
}
.card .front {
background: red;
display: flex;
justify-content: center;
align-items: center;
}
/*
.card .front p {
margin-top: 100px;
}
*/
.card .back p {
margin: auto;
}
.card .back {
background: blue;
-webkit-transform: rotateY( 180deg);
-moz-transform: rotateY( 180deg);
-o-transform: rotateY( 180deg);
transform: rotateY( 180deg);
display: flex;
justify-content: center;
align-items: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
<div id="main"><br>
<section class="container">
<div class="card">
<div class="front">
<p>Test</p>
</div>
<div class="back">
<p>MyBack</p>
</div>
</div>
</section>
</div>
</div>
Change the ready function to the one below.
$(document).ready(function () {
window.setInterval(function () {
$(".card").toggleClass("flipped");
}, 3000);
});
I have a page flipper animation for a notebook styled divs:
http://jsfiddle.net/jdell64/c1ytu8mo/2/
$('#next').click(function () {
$('#card').toggleClass('flipped');
})
.container {
background: lightgray;
width: 500px;
height:500px;
margin: 0 auto;
perspective: 800px;
}
#card {
width: 50%;
height: 100%;
margin: 0 auto;
transform-style: preserve-3d;
}
#card > div {
position:absolute;
width:100%;
height: 50%;
background: rgba(255, 255, 255, 0.7);
top: 125px;
/* backface-visibility: hidden; */
transition: transform 1s, visibility 0.9s;
transform-origin: 50% 0%;
}
#card.flipped .front {
transform: rotateX(360deg);
transform-origin: 50% 0%;
visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container">
<div id="card">
<div class="back">Back</div>
<div id="mid" class="mid">Middle</div>
<div id="front" class="front">Front</div>
</div>
</section>
<br/>
<br/>
<br/>
<br/>
<a id="back" href="#">back</a>
<a id="next" href="#">next</a>
The 'next' button seems to work, but it toggles the page back and forth. How would I get it to go 'next' in an endless loop, and have the previous page do the same?
Also, as an aside... I am not sure why my 'front' content has to be at the bottom.
More info
Based off of this article, I can do this:
$('#next').click(function () {
myBox = $('#card')
myBox.toggleClass('flipped');
myBox.one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',
function (e) {
console.log('done!');
console.log(e);
// code to execute after transition ends
});
})
but it fires twice for some reason.
Update I got the 'next' button to work, but I can't figure out the back button:
http://jsfiddle.net/jdell64/u3aebu1L/5/
You simply toggle the flipped class, adding / removing would create a forth and back notion, but if you want to flip more elements, then the flipped class should stay on the card, but instead should go to the sub elements.
To answer your aside: z-index will solve reordering issues... otherwise the sub elements will simply be put over each other, thus the last one being on top.
$('#next').click(function () {
$('#card').addClass('flipped');
});
$('#back').click(function () {
$('#card').removeClass('flipped');
});
.container {
background: lightgray;
width: 500px;
height:500px;
margin: 0 auto;
perspective: 800px;
}
#card {
width: 50%;
height: 100%;
margin: 0 auto;
transform-style: preserve-3d;
}
#card > div {
position:absolute;
width:100%;
height: 50%;
background: rgba(255, 255, 255, 0.7);
top: 125px;
/* backface-visibility: hidden; */
transition: transform 1s, visibility 0.9s;
transform-origin: 50% 0%;
}
#card.flipped .front {
transform: rotateX(360deg);
transform-origin: 50% 0%;
visibility: hidden;
}
#card .front {
z-index: 2;
}
#card .mid {
z-index: 1;
}
#card div {
z-index: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container">
<div id="card">
<div id="front" class="front">Front</div>
<div id="mid" class="mid">Middle</div>
<div class="back">Back</div>
</div>
</section>
<br/>
<br/>
<br/>
<br/>
<a id="back" href="#">back</a>
<a id="next" href="#">next</a>
You should also switch the front class to the next page so the animation will always be the same because off that 'front' class
This is future you... I found a hacky solution:
http://jsfiddle.net/jdell64/u3aebu1L/
Basically, I added a .middle class to be for the other direction animation. I also added a noAnimate class to ignore animations.
.container {
background: lightgray;
width: 500px;
height:500px;
margin: 0 auto;
perspective: 800px;
}
#card {
width: 50%;
height: 100%;
margin: 0 auto;
transform-style: preserve-3d;
}
#card > div {
position:absolute;
width:100%;
height: 50%;
//background: rgba(255, 255, 255, 0.6);
top: 125px;
transform-origin: 50% 0%;
}
#card .front {
transition: transform 1s, visibility 0.9s;
}
#card .middle {
transition: visibility 0.1s, transform 1s;
}
#card.flipped .front {
transform: rotateX(360deg);
transform-origin: 50% 0%;
visibility: hidden;
}
#card.flopped .middle {
transform: rotateX(-360deg);
transform-origin: 50% 0%;
}
.noAnimate {
-moz-transition-property: none !important;
-webkit-transition-property: none !important;
-o-transition-property: none !important;
transition-property: none !important;
}
.front {
background: lightgreen;
}
.middle {
background: lightblue;
}
.back {
background: goldenrod;
}
I have a div which has two child div's, one div on the screen plan and other vertically perpendicular to the screen.
I try to rotate the div along Y axis for about 30 degrees. keeping its transform-style 3d preserved.
When doing it, in Firefox the border isn't a straight line anymore. It looks like this
For closer view
I happen to use the following code
.holder {
position: relative;
top: 0;
left: 0;
width: 200px;
height: 226px;
perspective: 2000px;
-moz-perspective: 2000px;
}
.box {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 226px;
background-color: transparent;
transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform: translateZ( -100px ) rotateY(30deg);
-moz-transform: translateZ( -100px ) rotateY(30deg);
transition: transform 0.5s;
-moz-transition: transform 0.5s;
}
.box div {
position: absolute;
margin: 0;
display: block;
}
.box .front {
left: 0;
right: 0;
top: 0;
bottom: 0;
transform: rotateX(0deg) translateZ(10px);
-moz-transform: rotateX(0deg) translateZ(10px);
background-color: grey;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.box .left {
left: 0;
top: 0;
bottom: 0;
width: 20px;
transform: rotateY(-90deg) translateZ(10px);
-moz-transform: rotateY(-90deg) translateZ(10px);
background-color: black;
background-size: cover;
background-position: left;
background-repeat: no-repeat;
}
<div class="holder">
<div class="box">
<div class="front"></div>
<div class="left"></div>
</div>
</div>
Please let me know if I'm missing anything.
Picture of the link provided in one of the answers :
It's a Firefox aliasing problem, you can add
outline: 1px solid transparent;
as a workaround to .box .front.
I got a work around for your issue reference.
Try filter for the div having class="box".
Basically this is used for svg elements but it is working for your case as well.
filter: url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter id="gaussian_blur"><feGaussianBlur in="SourceGraphic" stdDeviation="0" /></filter></defs></svg>#gaussian_blur');
Tested in latest version of Opera, FF and Chrome for both mac and windows.
Working Demo here
I'm not sure why using translateZ inside a transformed element is not works properly on FF.
Adding outline: 1px solid transparent; is not working, but adding border: 1px solid transparent; to the .box will working, with removing transform: rotateX(0deg) translateZ(10px); from the .box .front.
Example:
.holder {
position: relative;
top: 0;
left: 0;
width: 200px;
height: 226px;
perspective: 2000px;
-moz-perspective: 2000px;
}
.box {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 226px;
background-color: transparent;
border: 1px solid transparent;
transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform: translateZ( -100px ) rotateY(30deg);
-moz-transform: translateZ( -100px ) rotateY(30deg);
transition: transform 0.5s;
-moz-transition: transform 0.5s;
}
.box div {
position: absolute;
margin: 0;
display: block;
}
.box .front {
left: 0;
right: -4px;
top: 0;
bottom: 0;
/* transform: rotateX(0deg) translateZ(10px); */
/* -moz-transform: rotateX(0deg) translateZ(10px); */
background-color: grey;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.box .left {
left: 0;
top: 0;
bottom: 0;
width: 20px;
transform: rotateY(-90deg) translateZ(10px);
-moz-transform: rotateY(-90deg) translateZ(10px);
background-color: black;
background-size: cover;
background-position: left;
background-repeat: no-repeat;
}
<div class="holder">
<div class="box">
<div class="front"></div>
<div class="left"></div>
</div>
</div>