CSS transform does not work properly in Chrome - html

I have rewritten a book page flip animation based on Codrops to a more lightweight version with less JavaScript.
My animation runs as desired in Firefox (and Safari), but not in Chrome.
Clicking on the right half of the image for the next picture, Chrome does not show the picture on the flipping side. For demonstration purposes, I set background: red and created the div.helper-class-to-make-bug-visbile to make background: red visible. It only occurs the first time the picture flips. When I go back and flip again the animation is not lagging anymore. This is annoying, even the animation only lags on the first turn.
Demo: https://codepen.io/pizzabote/pen/xxxXmXN
How to fix this so the animation from the demo works in Chrome properly too (flipping the image the first time without lagging)? Or is this a bug in Chrome?
I'm using Chrome version 78.0.3904.87 (Official Build) (64-bit) on macOS Mojave. On Windows, the animation with this Chrome version does not work for me either.
HTML part:
<div class="container">
<div class="page" id="first">
<div class="back">
<div class="outer">
<div class="content">
<img src="img/1.jpg">
</div>
</div>
</div>
</div>
<div class="page" id="second">
<div class="front">
<div class="outer">
<div class="content">
<img src="img/1.jpg">
</div>
</div>
</div>
<div class="back" id="third">
<div class="outer">
<div class="content">
<div class="helper-class-to-make-bug-visbile">
<img src="img/2.jpg">
</div>
</div>
</div>
</div>
</div>
<div class="page" id="fourth">
<div class="front">
<div class="outer">
<div class="content">
<img src="img/2.jpg">
</div>
</div>
</div>
</div>
</div>
CSS part:
.container {
width: 400px;
height: 300px;
position: relative;
z-index: 100;
-webkit-perspective: 1300px;
perspective: 1300px;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.page {
position: absolute;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition-property: -webkit-transform;
transition-property: transform;
width: 50%;
height: 100%;
left: 50%;
-webkit-transform-origin: left center;
transform-origin: left center;
}
#first,
#first .back {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
}
#first {
z-index: 102;
}
#second {
z-index: 103;
transition: transform 0.8s ease-in-out;
}
#third .content {
width: 400px;
}
#fourth {
z-index: 101;
}
.page > div,
.outer,
.content,
.helper-class-to-make-bug-visbile {
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.page > div {
width: 100%;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.back {
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}
.outer {
width: 100%;
overflow: hidden;
z-index: 999;
}
/* problematic class: `.content` */
.content {
width: 200%;
background: red;
}
.front .content {
left: -100%;
}

So what's happening?
Backface Visibility
This is happening because you have backface-visibility in .page > div, .outer, .content, .helper-class-to-make-bug-visbile set to hidden. A simple set to visible will fix it.
Here is the functioning code:
let prev = document.getElementById("prev");
let next = document.getElementById("next");
prev.addEventListener("click", prevImg);
next.addEventListener("click", nextImg);
let second = document.getElementById('second');
function prevImg() {
second.style.msTransform = "rotateY(0deg)";
second.style.webkitTransform = "rotateY(0deg)";
second.style.transform = "rotateY(0deg)";
}
function nextImg() {
second.style.msTransform = "rotateY(-180deg)";
second.style.webkitTransform = "rotateY(-180deg)";
second.style.transform = "rotateY(-180deg)";
}
body {
margin: 4em;
}
.container {
width: 400px;
height: 300px;
position: relative;
z-index: 100;
-webkit-perspective: 1300px;
perspective: 1300px;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.page {
position: absolute;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transition-property: -webkit-transform;
transition-property: transform;
width: 50%;
height: 100%;
left: 50%;
-webkit-transform-origin: left center;
transform-origin: left center;
}
#first,
#first .back {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
}
#first {
z-index: 102;
}
#second {
z-index: 103;
transition: transform 0.8s ease-in-out;
}
#third .content {
width: 400px;
}
#fourth {
z-index: 101;
}
.page > div,
.outer,
.content,
.helper-class-to-make-bug-visbile {
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
-webkit-backface-visibility: visible;
backface-visibility: visible;
}
.page > div {
width: 100%;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.back {
-webkit-transform: rotateY(-180deg);
transform: rotateY(-180deg);
}
.outer {
width: 100%;
overflow: hidden;
z-index: 999;
}
/* problematic class: `.content` */
.content {
width: 200%;
background: red;
}
.front .content {
left: -100%;
}
/* controls */
#prev, #next {
position: absolute;
width: 50%;
height: 100%;
z-index: 999;
}
#prev:hover, #next:hover {
background: rgba(0,0,0,0.05);
cursor: pointer;
}
#prev {
top: 0;
left: 0;
}
#next {
top: 0;
left: 50%;
}
<div class="container">
<div class="page" id="first">
<div class="back">
<div class="outer">
<div class="content">
<img src="https://tympanus.net/Development/BookBlock/images/demo1/1.jpg">
</div>
</div>
</div>
</div>
<div class="page" id="second">
<div class="front">
<div class="outer">
<div class="content">
<img src="https://tympanus.net/Development/BookBlock/images/demo1/1.jpg">
</div>
</div>
</div>
<div class="back" id="third">
<div class="outer">
<div class="content">
<div class="helper-class-to-make-bug-visbile">
<img src="https://tympanus.net/Development/BookBlock/images/demo1/2.jpg">
</div>
</div>
</div>
</div>
</div>
<div class="page" id="fourth">
<div class="front">
<div class="outer">
<div class="content">
<img src="https://tympanus.net/Development/BookBlock/images/demo1/2.jpg">
</div>
</div>
</div>
</div>
<div id="prev"></div>
<div id="next"></div>
</div>
Run that snippet to see the problem erased from the face of the Universe!

Related

'card flips' using CSS flip as if the axis is off screen or the cards sit on top of each other

So I was trying to have a webpage with images that would flip to reveal text, and only the first two images seem to work without issue. Each image to the right of those two either sit on top of each other, or once I try and space them out more, they rotate with a insanely large axis? The images should rotate on the x-axis and be evenly spaced out, but I can't work out how to space them without distorting their rotation? I'm quite new to CSS, sorry. Sorry for the huge walls of text.
.flip-container {
position: relative;
-webkit-perspective: 1000;
perspective: 1000;
padding: 5px;
}
.flip-cards {
width: 200px;
height: 260px;
position: relative;
float: left;
-webkit-transition: all 1s ease;
transition: all 1s ease;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.flip-cards:hover {
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
}
.flip-cards div {
width: 200px;
height: 260px;
position: absolute;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.front-card {
z-index: auto;
}
.reverse-card {
font-family: "Georgia";
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
background-color: black;
}
.reverse-card p {
position: relative;
background-color: #e5e5e5;
}
.reverse-card h2 {
position: relative;
background-color: #e5e5e5;
text-align: center;
}
#card1 {background-image: url(http://placehold.it/200x260)}
#card2 {background-image: url(http://placehold.it/200x260)}
#card3 {background-image: url(http://placehold.it/200x260)}
#card4 {background-image: url(http://placehold.it/200x260)}
#card5 {background-image: url(http://placehold.it/200x260)}
<div class="flip-container">
<div class="flip-cards">
<div class="front-card" id="card1"></div>
<div class="reverse-card">
<p>Text</p>
</div>
</div>
<div class="flip-cards">
<div class="front-card" id="card2"></div>
<div class="reverse-card">
<h2>About</h2>
<p>Text</p>
</div>
</div>
<div class="flip-cards">
<div class="front-card" id="card3"></div>
<div class="reverse-card">
<p>Text</p>
</div>
</div>
<div class="flip-cards">
<div class="front-card"></div>
<div class="reverse-card" id="card4fix">
<p>Text</p>
</div>
</div>
</div>

Making Image Overlay more responsive?

Is there any way of making this overlay more responsive? As in, making the overlay not cut off words, or go outside the image when resolution changes?
To further clarify: I am having three images next to each other in a row, per the W3CSS framework I am using, with three images under that, etc. Each image has an overlay with text links that direct to other pages, as shown in the example below. My only issue is responsiveness. As I want the images, and the overlays, to be responsive to screen size changes and resolution.
Thank you!
.container {
position: relative;
width: 50%;
}
.image {
display: block;
width: 100%;
height: auto;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 0;
transition: .5s ease;
background-color: #008CBA;
}
.container:hover .overlay {
opacity: 1;
}
.text {
color: white;
font-size: 15px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
}
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet"/>
<div class="w3-row-padding">
<div class="w3-third w3-container w3-margin-bottom">
<div class="container">
<img src="https://www.google.com/images/branding/product/ico/googleg_lodp.ico" alt="Google" style="height:300px;width:400px" class="w3-hover-opacity">
<div class="overlay">
<div class="text">
Google Sample1<br>
GoogleSample2<br>
</div>
</div>
</div>
<div class="w3-container w3-white" style="height:50px;width:400px">
<h3>Example 1</h3>
</div>
</div>
</div>
To make sure, that your image is the same width as parent, you better use not only width = 100% property, but min-width = 100% and max-width = 100% too. If you want to keep the dimensions of image, you also should point height = auto, but in your case it should be height = auto !important. And for breaking long words in overlay, i have added the following rules:
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
hyphens: auto;
Here is the working snippet:
.container {
position: relative;
width: 50%;
}
.image {
display: block;
width: 100%;
min-width: 100%;
max-width: 100%;
height: auto !important;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
opacity: 0;
transition: .5s ease;
background-color: #008CBA;
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
hyphens: auto;
}
.container:hover .overlay {
opacity: 1;
}
.text {
color: white;
font-size: 15px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
}
<div class="w3-row-padding">
<div class="w3-third w3-container w3-margin-bottom">
<div class="container">
<img src="https://www.google.com/images/branding/product/ico/googleg_lodp.ico" alt="Google" style="height:300px;width:400px" class="w3-hover-opacity image"></a>
<div class="overlay">
<div class="text">
Google Sample1<br>
GoogleSample2<br>
</div>
</div>
</div>
<div class="w3-container w3-white" style="height:50px;width:400px">
<h3>Example 1</h3>
</div>
</div>
Background-size:cover is your friend when it comes to responsive images. With the image being the background, cover will position it so it fits the width/height automatically and will resize in the other direction that it doesn't fit so that it keeps the ratio. That way the image looks like it stays the same size the whole time, but it's responsive and doesn't get distorted.
.container {
position: relative;
width: 0%;
}
.w3-third{
background-image:url('http://www.fillmurray.com/200/300');
background-size:cover;
background-position:center center;
height:300px;
width:33.333%;
float:left;
display:block;
position:relative;
}
.overlay {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
opacity: 0;
transition: .5s ease;
background-color: #008CBA;
}
.w3-container:hover .overlay {
opacity: 1;
}
.text {
color: white;
font-size: 15px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
}
<div class="w3-row-padding">
<div class="w3-third w3-container w3-margin-bottom">
<div class="overlay">
<div class="text">
Google Sample1<br>
Google Sample2<br>
</div>
</div>
</div>
<div class="w3-third w3-container w3-margin-bottom">
<div class="overlay">
<div class="text">
Google Sample1<br>
Google Sample2<br>
</div>
</div>
</div>
<div class="w3-third w3-container w3-margin-bottom">
<div class="overlay">
<div class="text">
Google Sample1<br>
Google Sample2<br>
</div>
</div>
</div>
</div>

Can't get these rotating cubes to display side by side

I found the code here to rotating cubes, which I wanted to use to display a photo on the front side and text on the other once hovered over.
<div class='box-scene'>
<div class='box'>
<div class='front face'>
<img src='http://placehold.it/180x180/' alt=''>
</div>
<div class="side face">
<p>This is back</p>
</div>
</div>
</div>
<div class='box-scene'>
<div class='box'>
<div class='front face'>
<img src='http://placehold.it/180x180/' alt=''>
</div>
<div class="side face">
<p>This is back</p>
</div>
</div>
</div>
.box-scene {
-webkit-perspective: 700;
width: 400px;
height: 200px;
margin: auto;
z-index: 999;
}
.box-scene:hover .box {
-webkit-transform: rotateY(-90deg);
}
.box {
width: 180px;
height: 180px;
position: relative;
-webkit-transform-style: preserve-3d;
-webkit-transition: all 0.4s ease-out;
-webkit-transform-origin: 90px 90px -90px;
/* float: left; */
margin: 30px auto;
}
.face {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: visible;
-webkit-transform-origin: 0 0;
}
.front {
-webkit-transform: rotateY(0deg);
z-index: 2;
background: #d9d9d9;
}
.side {
background: #9dcc78;
-webkit-transform: rotateY(90deg);
z-index: 1;
left: 180px;
}
I've tried using display:inline, have tried putting them in separate columns using bootstrap, yet these two cubes will not line up side by side. Could anyone provide some more details on why they refuse to line up?
.box-scene css add float: left and change width to 49%;

How to hide a div containing text behind an image in 3D transform

I've been trying to make three images with a 'flipcard' effect for around a day and a half now and think I'm pretty close to a solution.
However, as you can see on the codepen, the only problem left is that when my images are in a static state (i.e. not being hovered over) you can still see the text lying on top of them.
I'd really appreciate it if anyone could come up with a way so that when the images are static, there is no text lying on top of them, but when they are hovered over they animate with the 'flipcard' effect - such as already occurs.
Basically, I'd just like the text hidden/removed when the images are in a static state but visible after the animation occurs - as if they were on the 'flipside' of the images! The rest is fine.
Appreciate any answers in advance, thanks guys! :-)
Codepen link - http://codepen.io/skoster7/pen/kkYEJk?editors=0100
HTML:
<div class="flexcontainer">
<div class="photo-container">
<div class="photo">
<img src="https://media2.giphy.com/media/kiXLfqncf42kg/200_s.gif" class="front" />
<div class="photo-desc back">Christmas tree</div>
</div>
</div>
<div class="photo-container">
<div class="photo">
<img src="http://hdwallpaperpoint.com/wp-content/uploads/2016/05/Happy-birthday-candles-on-cake-small-cake-hd-4k-wallpaper-300x200.jpg" class="front" />
<div class="photo-desc back">Happy Birthday</div>
</div>
</div>
<div class="photo-container">
<div class="photo">
<img src="https://www.walldevil.com/wallpapers/a76/thumb/halloween-jack-o039-lantern-pumpkin-ghost-cat-skull-spider.jpg" class="front" />
<div class="photo-desc back">Halloween</div>
</div>
</div>
</div>
CSS:
.flexcontainer {
display: flex;
perspective: 700px;
}
.photo {
position: relative;
z-index: 1000;
}
.photo-desc {
position: relative;
z-index: 100;
}
.photo-container {
position: relative;
margin-right: 10px;
transition-property: transform;
transition-duration: 2s;
transition-style: preserve-3d;
backface-visibility: hidden;
}
.photo-container:hover {
transform: rotateY(-180deg);
}
.back {
backface-visibility: visible;
position: absolute;
top: 10;
margin-top: -200px;
transform: rotateY(-180deg);
color: red;
}
The photo and back elements should be siblings (and not parent/child).
Here is a snippet (changed width/height of the elements to fit SO):
.flexcontainer {
display: flex;
perspective: 700px;
}
.photo {
width: 200px;
height: 150px;
transform: rotateY(0deg);
}
.photo img {
width: 200px;
height: 150px;
}
.photo-container {
transform-style: preserve-3d;
transition-property: transform;
transition-duration: 2s;
position:relative;
width: 200px;
height: 150px;
margin:10px;
}
.photo-container:hover {
transform: rotateY(-180deg);
}
.back {
transform: rotateY(180deg);
color: red;
}
.photo,
.back {
backface-visibility: hidden;
position:absolute;
left:0;
top:0;
}
.back {
transform: rotateY(180deg);
}
<div class="flexcontainer">
<div class="photo-container">
<div class="photo">
<img src="https://media2.giphy.com/media/kiXLfqncf42kg/200_s.gif" class="front">
</div>
<div class="back">Christmas tree</div>
</div>
<div class="photo-container">
<div class="photo">
<img src="http://hdwallpaperpoint.com/wp-content/uploads/2016/05/Happy-birthday-candles-on-cake-small-cake-hd-4k-wallpaper-300x200.jpg" class="front">
</div>
<div class="back">Happy Birthday</div>
</div>
<div class="photo-container">
<div class="photo">
<img src="https://www.walldevil.com/wallpapers/a76/thumb/halloween-jack-o039-lantern-pumpkin-ghost-cat-skull-spider.jpg" class="front">
</div>
<div class="back">Halloween</div>
</div>
</div>
And a working codepeng:
http://codepen.io/anon/pen/Egazvq?editors=1100
You can achieve this by adding display: none; to the .back class
and then adding a little something to your css:
.photo-container:hover .back {
display: block;
}
Here is an updated codepen as an example:
http://codepen.io/anon/pen/QKwRvA?editors=1100
Well, I enjoyed the challenge of this. I will go right ahead and add another solution for you.
.flexcontainer {
display: flex;
perspective: 700px;
}
.photo-desc {
position: absolute;
}
.photo-container {
position: relative;
z-index: 100;
margin-right: 10px;
transition-property: transform;
transition-duration: 2s;
transition-style: preserve-3d;
}
.photo-container:hover {
transform: rotateY(-180deg);
backface-visibility: visible;
}
.back {
position: absolute;
top: 10;
margin-top: -200px;
transform: rotateY(180deg);
color: red;
opacity: 0;
}
.photo-container:hover > .back {
opacity: 1;
transition: opacity 1s linear;
}
<div class="flexcontainer">
<div class="photo-container">
<img src="https://media2.giphy.com/media/kiXLfqncf42kg/200_s.gif" class="front">
<div class="back">
Christmas tree
</div>
</div>
<div class="photo-container">
<img src="http://hdwallpaperpoint.com/wp-content/uploads/2016/05/Happy-birthday-candles-on-cake-small-cake-hd-4k-wallpaper-300x200.jpg" class="front">
<div class="back">
Happy Birthday
</div>
</div>
<div class="photo-container">
<img src="https://www.walldevil.com/wallpapers/a76/thumb/halloween-jack-o039-lantern-pumpkin-ghost-cat-skull-spider.jpg" class="front">
<div class="photo-desc back">Halloween
</div>
</div>
</div>
Doing it this way, enables the text to "fade in" etc. Which i think looks kinda cool with your animation. I also got it so your images stay "appeared" when hovering over, rather than the flipside "disappearing" when animation is flipped.
As a side note: disappointed that others found another solution first :)

How to make a hidden face appear from the top using -webkit-transform: rotateX();

I'm trying to do this 3D transformation effect using css transform :
In my attempt the hidden face appears from the right while it needs to appear from the bottom in mouse hover, I don't know what i'm doing wrong , any help on how to fix this would be greatly appreciated, thanks in advance for your feedback.
LIVE DEMO
HTML
<div class='box-scene'>
<div class='box'>
<div class='front face'>
<img src='http://placehold.it/180x180/' alt=''>
</div>
<div class="side face">
<p>This is back</p>
</div>
</div>
</div>
<div class='box-scene'>
<div class='box'>
<div class='front face'>
<img src='http://placehold.it/180x180/' alt=''>
</div>
<div class="side face">
<p>This is back</p>
</div>
</div>
</div>
CSS
.box-scene {
-webkit-perspective: 700;
width: 400px;
height: 200px;
margin: auto;
z-index: 999;
}
.box-scene:hover .box {
-webkit-transform: rotateX(-90deg);
}
.box {
width: 180px;
height: 180px;
position: relative;
-webkit-transform-style: preserve-3d;
-webkit-transition: all 0.4s ease-out;
-webkit-transform-origin: 90px -90px -90px;
/* float: left; */
margin: 30px auto;
}
.face {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: visible;
-webkit-transform-origin: 0 0;
}
.front {
-webkit-transform: rotateY(0deg);
z-index: 2;
background: #d9d9d9;
}
.side {
background: #9dcc78;
-webkit-transform: rotateY(90deg);
z-index: 1;
left: 180px;
}
If the hidden face shall come from the bottom, you have to change its position and some of the initial rotation. Here's the new fiddle.If you want it to come from the side the only thing to change is replacing rotateX(-90deg) with rotateY(-90deg) for the .box-scene:hover .box part. See fiddle.