I was following a Youtube tutorial to create a Memory Card game. Halfway through I started to tinker to see if I could figure out the steps myself. I have a div that looks like this:
<div class="memory-card">
<img class="front-face" src="img/aurelia.svg" alt="Aurelia">
<img class="back-face" src="img/js-badge.svg" alt="JSBadge">
</div>
The CSS for this div looks like this
.memory-card {
width: calc(25% - 10px);
height: calc(33.33% - 10px);
position: relative;
margin: 5px;
transition: transform 0.2s;
}
.memory-card:active {
transform: scale(0.97);
transition: transform 0.2s;
}
.flip {
transform: rotateY(180deg);
transition: transform 0.2s;
}
The class "flip" is added to the div by toggling on the classList of the memory-card element when a click occurs. Essentially what this does is that when the memory-card is clicked and held it becomes active and scales to 0.97 and when released it is rotated by 180 degrees around the Y-axis (class="memory-card flip").
Before click
However, when I click again (and hold) it rotates again without waiting for the click to be released. As per my understanding (which has a hole that I hope you can fill), the card (which the div represents btw) should rotate only after I release the click. Can anybody help? This seems like an issue that must have been answered before but for the life of me, I could not find it.
Try like this:
var memorycard = document.querySelector('.memory-card');
memorycard.onclick = function(e) {
memorycard.classList.toggle('flip');
};
.memory-card {
width: calc(25% - 10px);
height: calc(33.33% - 10px);
position: relative;
margin: 5px;
transition: transform 0.2s;
}
.memory-card:active {
transform: scale(0.97);
}
.memory-card.flip:active {
transform: rotateY(180deg) scale(0.97);
}
.flip {
transform: rotateY(180deg);
}
img {
width: 100%;
height: auto;
}
<div class="memory-card">
<img class="front-face" src="https://i.stack.imgur.com/esMJU.png" alt="Aurelia">
<img class="back-face" src="https://i.stack.imgur.com/xR2ZZ.png" alt="JSBadge">
</div>
.flip has this CSS property: transform: rotateY(180deg);. However, as soon as the click begins, .memory-card:active is applied, so that property gets overwritten as transform: scale(0.97);. The solution is to specify that when the .flip class is present, both transform functions should be applied:
.memory-card.flip:active {
transform: rotateY(180deg) scale(0.97);
}
Related
Long story made short I am trying to work on a page that will be showing a playing card that I want to animate flipping over to the back side and back again at certain points. So far I've been using a lot of the code from this useful blog post to do so: https://manjitkarve.com/posts/card-flip-interaction/
What I'm trying to add on now is a clip-path as the majority of my card images are not 'clean' and have some jank white lines around the image and using clip-path in CSS seemed like the cleanest way to nail this. And so far isolated on its own it is doing the job swimmingly.
However with the clip-path added in, my card flip transitions are messed up. As an example: If I am sitting on the 'front' face of the card and ask it to flip to the back, it flips to a mirrored version of the front face instead. Once I take clip-path out, it's back to normal.
There's a LOT of moving parts to my code now but I'll post what I can/what's relevant. As an addition note, I'm also using the SWUP JS library in here but that functionality is working fine and best I can tell is not interfering with this currently. If I call these card transitions manually outside of SWUP, I get the same behavior:
HTML:
<main id="swup">
<div id="swup-card-img card_img_overlay" class="card-left-half card transition-flip center">
<div class="front face" style="background-image:url('{{ card.card_image.url }}')"></div>
<div class="back face" style="background-image:url('{% static 'img/fow_cardback.png' %}')"></div>
</div>
</main>
CSS:
.transition-flip {
transition: transform 1.0s;
transform-style: preserve-3d;
}
.transition-flip .card .front {
transform: rotateX(0deg);
}
.transition-flip .card .back {
transform: rotateX(180deg);
}
html.is-animating .transition-flip {
transform: rotateY(180deg);
transition: transform 1.0s;
}
html.is-leaving .transition-flip {
transform: rotateY(180deg);
transition: transform 1.0s;
}
.card {
/* Card height to width ratio is 1.396 rounded */
width: 50vw;
height: 69.8vw;
position: relative;
perspective: 100vw;
perspective-origin: 50% 50%;
transform-style: preserve-3d;
display: inline-block;
clip-path: inset(0.3% 0.2% 0.0% 0.2% round 3.9%);
background: rgba(0, 0, 0, 1.0);
}
.card .face {
backface-visibility: hidden;
position: absolute;
width: 100%;
height: 100%;
transition: transform 0.35s cubic-bezier(0.13, 1.03, 0.39, 0.98), box-shadow 0.35s cubic-bezier(0.13, 1.03, 0.39, 0.98), border-width 0.35s cubic-bezier(0.13, 1.03, 0.39, 0.98);
box-shadow: 0px 1.2vw 4vw -1vw rgba(0, 0, 0, 0.6);
background-position: 0 0;
background-size: 50vw;
background-repeat: no-repeat;
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 1.1vw;
}
.card .front {
}
.card .back {
transform: rotateY(180deg);
transform: rotateX(180deg);
}
.center {
margin:0 auto;
}
So, I was trying to get an image to, when hovered over, spin 360 degrees and scale up by 1.4, all with its centre staying in place. I tried this:
.logo img[data-v-4fbac4e1] {
width: 50px;
height: 50px;
content: url(https://i.imgur.com/txz1IXI.png);
transition: width 2.0s, height 2.0s, transform 2.0s;
}
with this:
.logo img[data-v-4fbac4e1]:hover{
width: 65px;
height: 65px;
transform: rotate(360deg);
}
and it works fine, but it moves off-centre as it expands. How do I make sure the width and height increase from the centre so it stays in the same place? Sorry if this seems elementary, I'm new to CSS.
Edit: the part of the HTML I'm using looks like this:
<a data-v-4fbac4e1 href="/home" class="logo">
<img data-v-4fbac4e1 src="/img/icons/icon.svg">
</a>
If more is required I can add it, but this is the HTML for the image I'm trying to transform.
Since I'm not entirely sure what you mean, point to which is your culprit and we'll get you sorted out but here's some examples of the differences between techniques.
img, div {
display: inline-block;
margin: 1rem;
height: 10rem;
width: 10rem;
}
.fancy-img1, .fancy-img3 {
object-fit: cover;
outline: red 2px solid;
}
.fancy-img2, .fancy-img4 {
background: url(https://picsum.photos/200) no-repeat center center / cover;
outline: blue 2px solid;
}
/* grow by height value change transition */
.fancy-img1 {
transition: transform .5s, height .5s;
}
.fancy-img2 {
transition: transform .5s, height .5s;
}
.fancy-img1:hover, .fancy-img2:hover {
transform: rotate(360deg);
height: 15rem;
}
/* Scale with transition */
.fancy-img3 {
transition: transform .5s;
}
.fancy-img3:hover {
transform: scaleY(1.5) rotate(360deg);
}
/* Scale with keyframes */
#keyframes spinGrow {
to { transform: scaleY(1.5) rotate(360deg); }
}
.fancy-img4:hover {
animation: spinGrow .5s forwards;
}
<h2>Are you talking about transition height which cause the jumpy effect?</h2>
<img class="fancy-img1" src="https://picsum.photos/200">
<div class="fancy-img2"></div>
<h2>Or actually scale so it remains in its original position?</h2>
<img class="fancy-img3" src="https://picsum.photos/200">
<div class="fancy-img4"></div>
Hi i'm just a student I just wanna know if its possible to combine hover, transition, and transform by just using css.
How can transformed image transitioned back to it's original size and shape when hovered?
<html>
<style>
.sample {
display: inline-block;
border: 0px solid #fff;
margin: 10px;
overflow: hidden;
height: 500px;
width: 140px;
transform: rotate(0deg);
webkit-transition: 0.8s;
transition: 0.7s;
}
.sample img {
display: block;
transform: rotate(2deg);
transform-origin: 200% -600%;
}
.sample img:hover {
width: 600px;
height: 600px;
transform: rotate(0deg);
transform-origin: 0% 0%;
-webkit-transition-timing-function: ease-in-out;
}
</style>
<body>
<div class="sample">
<img src="http://www.freegreatpicture.com/files/39/1264-tree.jpg" height="600" width="600">
</div>
</body>
</html>
If you only define the CSS "transformed" rules in the hover pseudo-class, then when the image is no longer being hovered-over it will automatically transition back to its original state.
Here is a simplified example using part of your code (I changed the image to the Wikipedia logo since your image was coming up broken):
.sample img {
transform: rotate(30deg);
transition: ease-in-out 700ms;
}
.sample img:hover {
transform: rotate(0deg);
}
<div class="sample">
<img src="https://en.wikipedia.org/static/images/project-logos/enwiki.png">
</div>
The hover pseudo-class is an "active state class", meaning it only comes into play while that action is taking place (i.e., the pointer is hovered over the element).
If you want to include special easing and timing rules on the change from default state to hovered state then include the transition property in the default rule. You can specify lengths of time over which the transition takes place so the change can be more "animated". You'll notice that in the example above I stretched the rotation to 700ms so you can see it turning when hovered, then turning back when no longer hovered.
I am having a bit of an issue with rotation of a cube. I want to make it cross-browser so I am transforming every side of the cube. When I am rotating from left to right the sides align perfectly on all browsers Chrome, Firefox and IE, BUT when the cube is rotated from top to bottom, the sides align only on Chrome (If I make the animation slower on Chrome the sides are broken the same way as the other browsers, so I think working properly is a bug :D). I have provided an example on jsfiddle:
http://jsfiddle.net/0n9bnxe5/
HTML:
<div class="flip-card-content">
<div class="flip-card-side-a" style="background:red">
FRONT
</div>
<div class="flip-card-side-b" style="background:green">
BACK
</div>
<div class="flip-card-side-c" style="background:aqua">
LEFT
</div>
</div>
<button id="button">Flip-top</button>
<button id="button2">Filp-right</button>
CSS:
.flip-card-content {
position: relative;
margin: 100px;
width: 200px;
height: 200px;
transform-style: preserve-3d;
perspective:1000px;
}
.flip-card-side-a,
.flip-card-side-b,
.flip-card-side-c{
width: 100%;
position: absolute;
height: 100%;
backface-visibility: hidden;
transform-origin:50% 50% 0px;
transition: all .5s ease-in-out;
}
.flip-card-side-a {
transform: rotateY(0deg) translateZ(100px);
z-index: 1;
}
.flip-card-side-b {
transform: rotateX(90deg) translateZ(100px);
}
.flip-card-side-c {
transform: rotateY(-90deg) translateZ(100px);
}
.flip .flip-card-side-a {
transform: rotateX(-90deg) translateZ(100px);
}
.flip .flip-card-side-b {
display:block;
transform: rotateY(0deg) translateZ(100px);
z-index: 1;
}
.flip-right .flip-card-side-a {
transform: rotateY(90deg) translateZ(100px);
}
.flip-
right .flip-card-side-b {
display:none;
}
.flip-right .flip-card-side-c {
transform: rotateY(0deg) translateZ(100px);
z-index:1;
}
JQUERY:
$("#button").on('click', function(){
$(".flip-card-content").removeClass("flip-right");
setTimeout(function(){
$(".flip-card-content").toggleClass("flip");
},500);
});
$("#button2").on('click', function(){
$(".flip-card-content").removeClass("flip");
setTimeout(function(){
$(".flip-card-content").toggleClass("flip-right");
},500);
});
Any advice is welcomed!
Your translateZ doesn't quite work in the way you expect. Have look at how I've positioned the faces on the cube here and compare it to your own. Ultimately, I find the easiest way to rotate items such as cubes etc. is to position all the elements and then just rotate the container.
Also for nice scaling of fonts, images etc. its preferable to leave the front face at its natural size rather than scale up (i.e. move everything backward in 3d space):
.box {
height: 100%;
position: relative;
transform: rotateX(0deg);
transform-origin: 50% 50% -100px;
transform-style: preserve-3d;
transition: all 1s;
width: 100%;
}
.box--rotate-top {
transform: rotateX(-90deg);
}
.box--rotate-left {
transform: rotateY(90deg);
}
.box__face {
backface-visibility: hidden;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.box__face--front {
background: #f90;
}
.box__face--top {
background: #369;
transform: rotateX(90deg) translateZ(200px);
transform-origin: 0 100% 0;
}
.box__face--left {
background: #867;
transform: rotateY(-90deg) translateZ(200px);
transform-origin: 100% 0 0;
}
Here is the fiddle.
Transition in 3d space are tricky, and different browsers can handle them differently.
Here you have your fiddle corrected.
Your best bet is to leave nothing to the browser imagination
so, instead of changing
transform: rotateY(0deg) translateZ(100px);
to
transform: rotateX(-90deg) translateZ(100px);
make the change happen from
transform: rotateX(0deg) rotateY(0deg) translateZ(100px);
to
transform: rotateX(-90deg) rotateY(0deg) translateZ(100px);
Notice that I didn't change the transform from a mathematical point of view; but now every property matches a similar one.
Note just in case you want to know, in the first case IE is making the followng transition: change the angle of rotation from 0 to -90deg. At the same time, change the axis of rotation from Y to X. So, at the middle of the transition, the rotation is wrong (from your point of view), but in a mathematic sense, both ways of understanding the transition make sense.
I'm trying to create a cube with CSS. I actually think it's already there but I can't see it.
Feel free to edit the fiddle.
I don't understand why the perspective is not working.
Is this best practice?
Is it possible to rotate the cube as a whole??
Source: 24ways.
HTML:
<section class="container">
<div id="cube">
<figure class="front">1</figure>
<figure class="back">2</figure>
<figure class="right">3</figure>
<figure class="left">4</figure>
<figure class="top">5</figure>
<figure class="bottom">6</figure>
</div>
</section>
CSS:
.container {
margin: 200px auto;
width: 200px;
height: 200px;
position: relative;
-webkit-perspective: 800px;
}
#cube {
width: 100%;
height: 100%;
position: absolute;
-webkit-transform-style: preserve-3d;
}
#cube figure {
width: 198px;
height: 198px;
display: block;
position: absolute;
border: 1px solid #ddd;
background-color: rgba(0,0,0,0.2);
}
#cube .front { -webkit-transform: rotateY(0deg) translateZ(100px); }
#cube .back { -webkit-transform: rotateX(180deg) translateZ(100px); }
#cube .right { -webkit-transform: rotateY(90deg) translateZ(100px); }
#cube .left { -webkit-transform: rotateY(-90deg) translateZ(100px); }
#cube .top { -webkit-transform: rotateX(90deg) translateZ(100px); }
#cube .bottom { -webkit-transform: rotateX(-90deg) translateZ(100px); }
The problem could be that the hardware acceleration was not supported on your PC and it was on your mac... css3d transformations such as rotateX and rotateY require hardware accelerations.
in chrome go to your address bar and enter
chrome://gpu
you will see
3D CSS: Unavailable. Hardware acceleration disabled.
if this is the case then 3d cube is not visible.
Have a look at http://css3.bradshawenterprises.com/transforms/#transDemo3.
I have a wrapper around the cube that I rotate - in this case to keep it simple, I actually use three divs, one for X, one for Y and one for Z.
The playground underneath should show you how perspective etc work.
I used to work with a lot of 3D Transforms a while ago but recently noticed that CSS3 perspective does not have any effect on my web browsers including Chrome.
Tried the following and it helped in Google Chrome:
Navigate to "chrome://flags"
Find an item labeled "Override software rendering list" and disable it
Relaunch your browser
I know its a bit late but just in case it might help you...