I am trying to make an advent calendar for my website similar to THIS example.
I have the basic layout of the calendar created and when I hover over one of the "tiles" on the calendar the animation starts and the tile swings open. The animation swings the tile in the fashion as if you are opening a door towards you and it swings open to 90 degrees. However, when the animation gets to 90 degrees, the tile is reset to its original closed position.
How can I keep the door open while the user hovers over the tile and then swing the tile closed again when the user removes the cursor from the tile?
When the tile is open I also need to have an image behind it that is a clickable link to another page on my site. I have set this in a but all that is displayed is the background color of my .tile div (background-color: #000;) and not the clickable image or even my .back div.
Can anyone please help.
I have attached my current CSS and HTML that shows how the tile is created and animated.
Note: I do not need to handle touch events from mobile devices for this example.
CSS
.tile
{
background-color: #000;
color: #ffffff;
border: 1px solid #220001;
}
/* Flip the tile when hovered */
.tile:hover .flipper, .tile.hover .flipper
{
-webkit-animation: example 2s;
}
#-webkit-keyframes example
{
from
{
-webkit-transform: perspective(500) rotateY(0deg);
-webkit-transform-origin: 0% 0%;
}
to
{
-webkit-transform: perspective(500) rotateY(-90deg);
-webkit-transform-origin: 0% 0%;
}
}
.tile, .front, .back
{
width: 120px;
height: 120px;
}
.flipper
{
position: relative;
}
.front, .back
{
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
/* Front Tile - placed above back */
.front
{
z-index: 2;
transform: rotateY(0deg);
background-color: #760805;
}
/* Back - initially hidden Tile */
.back
{
background-color: #000;
}
HTML
<table>
<tr>
<td>
<div class="tile">
<div class="flipper">
<div class="front">
<!-- front content -->
<p>December 1</p>
</div>
<div class="back">
<!-- back content -->
<a href="http://www.google.com">
<img src="images/myImage1.jpg">
</a>
</div>
</div>
</div>
</td>
</tr>
</table>
Instead of using keyframes use transition
(Note: I've also added backface-visibility: true; and increased the rotation to -95deg to make the effect more similar to your example)
.tile .front {
transition: all 1.5s ease-in-out;
-webkit-transform: perspective(500) rotateY(0deg);
-webkit-transform-origin: 0% 0%;
backface-visibility: visible;
}
.tile:hover .front, .tile.hover .front
{
-webkit-transform: perspective(500) rotateY(-95deg);
-webkit-transform-origin: 0% 0%;
}
Demo
.tile
{
background-color: #000;
color: #ffffff;
border: 1px solid #220001;
}
.tile .front {
transition: all 1.5s ease-in-out;
-webkit-transform: perspective(500) rotateY(0deg);
-webkit-transform-origin: 0% 0%;
backface-visibility: visible;
}
/* Flip the tile when hovered */
.tile:hover .front, .tile.hover .front
{
-webkit-transform: perspective(500) rotateY(-95deg);
-webkit-transform-origin: 0% 0%;
}
.tile, .front, .back
{
width: 120px;
height: 120px;
}
.flipper
{
position: relative;
}
.front, .back
{
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
/* Front Tile - placed above back */
.front
{
z-index: 2;
transform: rotateY(0deg);
background-color: #760805;
}
/* Back - initially hidden Tile */
.back
{
background-color: #000;
}
<table>
<tr>
<td>
<div class="tile">
<div class="flipper">
<div class="front">
<!-- front content -->
<p>December 1</p>
</div>
<div class="back">
<!-- back content -->
<a href="http://www.google.com">
<img src="http://placehold.it/120x120">
</a>
</div>
</div>
</div>
</td>
</tr>
</table>
Related
This is supposed to be a memory game with cards with text on them.
The cards on the front should just be white (the background-image) and at the back there is a word. But since applying the backface-visibility-hidden, it actually just shows the background image and no text.
It supposed to have text only on the back, but out of curiosity I have placed text on one card on the back and on the front, only this one shows text from the front, but after flipping it does not show the back text, but only the mirror image of the front.
I have read the IE might cause problems, but not in this case, as it does not work in any browser.
I have tried playing with preserve-3d, but nothing brings me a solution.
<section class="memory-game">
<div class="memory-card">
<p class="front">un abricot</p>
<p class="back"></p>
</div>
</section>
.memory-game {
perspective: 1000px;
}
.memory-card {
position: relative;
transform: scale(1);
transition: transform 0.4s;
}
.memory-card:active {
transform: scale(0.95);
transition: transform 0.4s;
}
.memory-card.flip {
transform: rotateY(180deg);
}
.front,
.back {
position: absolute;
background-image: url("image.jpg");
backface-visibility: hidden;
}
.front {
transform: rotateY(180deg);
}
back
front
disappearing half
As you say, the solution is to add preserve-3d.
See it working in the snippet
.memory-game {
perspective: 1000px;
}
* {
transform-style: preserve-3d;
}
.memory-card {
position: relative;
transform: scale(1);
transition: transform 0.4s;
border: solid 1px black;
height: 50px;
width: 200px;
}
.memory-card:active {
transform: scale(0.95);
transition: transform 0.4s;
}
body:hover .memory-card {
transform: rotateY(180deg);
}
.front,
.back {
position: absolute;
background-image: url("image.jpg");
backface-visibility: hidden;
}
.front {
transform: rotateY(180deg);
}
<section class="memory-game">
<div class="memory-card">
<p class="front">FRONT</p>
<p class="back">BACK</p>
</div>
</section>
I'm trying to make a card flip effect with CSS keyframes but for some reason the transform: rotateY() doesn't rotate correctly. When it's rotated by the #keyframes, after it passes rotateY(90deg) the front side isn't shown, instead it shows the flipped back side. When flipping the card "manually" (in the inspect element), it works fine.
The card by default is showing the front side. But the animation starts with the back side and then it flips. The animation is keeping its ending state.
As far as I could see, for some reason, the front side is always behind the back side. (If you opacity the back side, the front side can be seen.)
I've tried:
Adding perspective: 1000px; to the parent element
(.cards).
Using positive rotateY() instead of negative.
Adding z-index to .front.
Adding transform: rotateY(0deg); to .front, so it knows that that's the front side.
Adding backface-visibility: hidden; to both, .front and .back.
Adding positon: relative; on one (and both), .front and .back.
But none of these fixed it.
Here you can see a video of the issue:
When #keyframes does it:
https://gyazo.com/7cd4e75c85ed5eba6b1e717a37ce95c2
Manually (When I do it with the Inspect Element):
https://gyazo.com/42e63ff2e4fe0149b917e895a633dd88
Here's the code:
HTML:
<div class="cards">
<div class="card">
<div class="front">
<div class="card-number">5</div>
<img src="https://bounty-assets.fra1.cdn.digitaloceanspaces.com/cards/clubs.png" alt="">
</div>
<div class="back">
<img src="https://bounty-assets.fra1.cdn.digitaloceanspaces.com/cards/back.png" alt="">
</div>
</div>
</div>
CSS:
.cards {
width: fit-content;
display: flex;
position: absolute;
top: 25px;
left: 0;
right: 0;
margin: 0 auto;
perspective: 1000px;
}
.cards .card {
min-width: auto;
width: 208px;
background: transparent;
border: 0;
border-radius: 0;
display: flex;
position: relative;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
margin-left: -30px;
transform: rotateY(0deg);
animation: flipcard 1s linear 0s 1 forwards;
}
.cards .card:first-child {
margin-left: 0;
}
.cards .card .front {
position: absolute;
backface-visibility: hidden;
transform: rotateY(0deg);
}
.cards .card .front .card-number {
position: absolute;
top: 30px;
left: 35px;
font-size: 32px;
font-weight: 600;
}
.cards .card .back {
position: absolute;
transform: rotateY(180deg);
}
#keyframes flipcard {
0% {
opacity: 0;
transform: translate(30vw, 30vh) rotateY(-180deg);
}
30% {
opacity: 1;
transform: translate(0, 0) rotateY(-180deg);
}
50% {
opacity: 1;
transform: translate(0, 0) rotateY(-180deg);
}
60% {
transform: translate(-20px, 0) rotateY(-180deg);
}
80% {
transform: translate(-30px, 0) rotateY(-90deg) scale(1.08);
}
90% {
transform: translate(0, 0) rotateY(0deg) scale(1.08);
}
100% {
transform: translate(0, 0) rotateY(0deg) scale(1);
}
}
I fixed it. Belive it or not, the opacity in the keyframes was causing this issue.
Having CSS transition on two absolutely positioned elements one over another causes them to interfere on iPhone 6 (maybe iOS in general). Taking a close look reveals some flickering during the transition. I've tried various z-index and 3D transform hacks, but without any success so far so I am a bit tilted atm :(
<div class="flip-container c1">
<div class="flipper">
<div class="front"><!-- front content --></div>
<div class="back"><!-- back content --></div>
</div>
</div>
<div class="flip-container c2">
<div class="flipper">
<div class="front"><!-- front content --></div>
<div class="back"><!-- back content --></div>
</div>
</div>
<button onclick="$('.c2').toggleClass('flipped')">btn1</button>
css:
/* entire container, keeps perspective */
.flip-container {
perspective: 1000;
transform-style: preserve-3d;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;
-ms-transform: perspective(1000px);
-moz-transform: perspective(1000px);
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
margin: 50px auto;
position: absolute;
top: 0;
border: 1px solid grey;
}
/* UPDATED! flip the pane when hovered */
.flip-container.flipped .back {
transform: rotateY(0deg);
}
.flip-container.flipped .front {
transform: rotateY(180deg);
}
.flip-container,
.front,
.back {
width: 320px;
height: 380px;
}
/* flip speed goes here */
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
/* hide back of pane during swap */
.front,
.back {
backface-visibility: hidden;
transition: 0.6s;
transform-style: preserve-3d;
position: absolute;
top: 0;
left: 0;
}
/* UPDATED! front pane, placed above back */
.front {
z-index: 2;
transform: rotateY(0deg);
}
/* back, initially hidden pane */
.back {
transform: rotateY(-180deg);
background: lightblue;
}
.c1 .front {
background: lightgrey;
}
.c2 .front {
background: teal;
}
link to an example:
http://codepen.io/AlphaVision/pen/avrVoj
I am trying to flip the div vertically from front side to back side and then restore it .But when I hover instead of flipping it is folded into a thin strip.What is the problem?
[The horizontal flip was working fine.Problem occured when I changed it to vertical flip]
<html>
<head>
<style type="text/css">
/* entire container, keeps perspective */
.flip-container {
perspective: 1000;
}
/* flip the pane when hovered */
.flip-container:hover .flipper, .flip-container.hover .flipper {
transform: rotateX(180deg);
}
.flip-container, .front, .back {
width: 320px;
height: 480px;
}
/* flip speed goes here */
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
/* hide back of pane during swap */
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
/* front pane, placed above back */
.front {
z-index: 2;
background-color:red;
}
/* back, initially hidden pane */
.back {
transform: rotateY(180deg);
background-color:green;
}
.vertical.flip-container {
position: relative;
}
.vertical .back {
transform: rotateX(180deg);
}
.vertical.flip-container .flipper {
transform-origin: 100% 213.5px; /* half of height */
}
.vertical.flip-container:hover .flipper {
transform: rotateX(-180deg);
}
</style>
</head>
<body>
<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
<div class="flipper">
<div class="front">
Front Side
</div>
<div class="back">
Back Side
</div>
</div>
</div>
</body>
</html>
Simply make all the rotateYs be rotateXs and make sure to add the class vertical to the container (since you have it in your CSS but not HTML)
Working demo
Changed HTML
<div class="vertical flip-container" ontouchstart="this.classList.toggle('hover');">
Updated CSS
/* entire container, keeps perspective */
.flip-container {
perspective: 1000px;
}
.flip-container, .front, .back {
width: 320px;
height: 480px;
}
/* flip speed goes here */
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
/* hide back of pane during swap */
.front, .back {
position: absolute;
top: 0;
left: 0;
backface-visibility:hidden;
-webkit-backface-visibility:hidden;
}
/* front pane, placed above back */
.front {
z-index: 1;
background-color:red;
}
/* back, initially hidden pane */
.back {
transform: rotateX(-180deg);
background-color:green;
animation: toFront 0.3s linear normal forwards;
}
.vertical.flip-container {
position: relative;
}
.vertical.flip-container:hover .back {
animation-delay: 0.3s;
animation: toBack 0.3s linear normal forwards;
}
#keyframes toBack {
0% {z-index:0;}
100% {z-index:1;}
}
#keyframes toFront {
0% {z-index:1;}
100% {z-index:0;}
}
.vertical.flip-container .flipper {
transform-origin: 100% 240px; /* half of height */
}
.vertical.flip-container:hover .flipper {
transform: rotateX(-180deg);
}
I added full functionality using CSS3 animations as well
I am trying to implement a feature where I need to have two trees, one next to the other, looking like mirrors. Please, see the image:
The point is I found the way to flip it horizontally but text is also inverted. What I cannot do is invert the tree letting the text as it is.
Here is what I have done: http://jsfiddle.net/lontivero/R24mA/
Basically, the following class is applied to the html body:
.flip-horizontal {
-moz-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
-o-transform: scaleX(-1);
transform: scaleX(-1);
-ms-filter: fliph; /*IE*/
filter: fliph; /*IE*/
}
The HTML code:
<body class="flip-horizontal"></body>
And the JS:
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
height: 200,
width: 400,
// more and more code. SO forces me to paste js code ;(
renderTo: Ext.getBody()
});
Your fiddle already had the start of the answer - to do a second flip on the text. There was an extra , preventing the second rule from being parsed.
I've updated the fiddle to include the heading elements, and set them to inline-block because inline elements can't be transformed.
.flip-horizontal, .x-grid-cell-inner, .x-column-header-text, .x-panel-header-text {
-moz-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
-o-transform: scaleX(-1);
transform: scaleX(-1);
-ms-filter: fliph; /*IE*/
filter: fliph; /*IE*/
}
.x-column-header-text, .x-panel-header-text {
display: inline-block;
}
I tried this, and it works great!
HTML code:
<div class="flip-container" ontouchstart="this.classList.toggle('hover');">
<div class="flipper">
<div class="front">
<!-- Front content -->
</div>
<div class="back">
<!-- Back content -->
</div>
</div>
</div>
The CSS:
/* Flip the pane when hovered */
.flip-container:hover .flipper, .flip-container.hover .flipper {
transform: rotateY(180deg);
}
.flip-container, .front, .back {
width: 320px;
height: 480px;
}
/* Flip speed goes here */
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
/* Hide back of pane during swap */
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
/* Front pane, placed above back */
.front {
z-index: 2;
/* For Firefox 31 */
transform: rotateY(0deg);
}
/* Back, initially hidden pane */
.back {
transform: rotateY(180deg);
}
I use this inside a Bootstrap col-sm-* and works great too:
<div class="col-sm-4 flip-container" ontouchstart="this.classList.toggle('hover');">
<div class="content-box flipper">
<div class="content-box-front">
<span class="glyphicon glyphicon-envelope content-box-icon"></span>
<h4>Share your emotions</h4>
</div>
<div class="content-box-back">
<p>Share emotions with friends, family and teammates.</p>
<button>Read more</button>
</div>
</div>
</div>
the CSS:
.content-box {
position: relative;
text-align: center;
height: 105px;
width: 100%;
}
.content-box-icon {
font-size: 30px;
width: 60px;
height: 60px;
line-height: 60px;
border-radius: 50%;
text-align: center;
display: block;
margin: 5px auto 15px auto;
color: #fff;
float: none;
background:#25acfd
}
.content-box-front
{
z-index: 2;
/* For Firefox 31 */
transform: rotateY(0deg);
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 105px;
}
.content-box-back {
transform: rotateY(180deg);
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 105px;
}
/* Entire container, keeps perspective */
/* Flip the pane when hovered */
.flip-container:hover .flipper, .flip-container.hover .flipper {
transform: rotateY(180deg);
}
/* Flip speed goes here */
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
Here is the example:
/* Entire text flipped around */
div {
-webkit-transform:rotateY(180deg);
-moz-transform:rotateY(180deg);
-o-transform:rotateY(180deg);
-ms-transform:rotateY(180deg);
}