Why for the following HTML:
<div class="container">
<div class="bottom">
<div class="face"></div>
</div>
</div>
And CSS:
.container {
width: 300px;
height: 300px;
position: relative;
transform: perspective(900px);
transform-style: preserve-3d;
animation: rot 8s infinite linear;
}
.bottom {
width: 200px;
height: 200px;
background-color: blue;
position: absolute;
top: 15%;
left: 15%;
opacity: 1;
}
.face {
width: 100px;
height: 200px;
background-color: red;
position: absolute;
left: 0px;
top: 0px;
transform-origin: 0% 0%;
transform: rotateY(60deg);
}
A blue square doesn't cover the red rectangle when it turns back (backface-visibility doesn't help)? At the same time when .bottom and .face are not in a parent-child relationship everything works as expected.
See plunker
Note: works in Chrome. In Firefox the first example doesn't work. In IE both of them.
Most of the CSS propertis inherit.
transform-style is an exception
setting
.bottom {
transform-style: preserve-3d;
}
or
.bottom {
transform-style: inherit;
}
will solve the problem
demo
Related
I have a simple scaling animation applied to a circle using keyframes.
There is an unexpected and undesirable line that scales with the circle in Chrome Version 85.0.4183.102 (Official Build) (64-bit) and not in Firefox or Safari.
I cannot remove it - do you know how to? I have tried adding border: 0 to the various divs unsuccessfully.
#parent { overflow: hidden; background: #F0F4FF; height: 500px; width: 100%; position: relative; user-select: none; margin-block-end: 5rem; z-index: 3; }
.child { width: 100%; height: 100%; }
.child .inner { background: radial-gradient(circle at center, #D90368 20%, #F0F4FF 20%); }
.inner { position: relative; left: 0; top: 0; animation: circle 2s linear infinite; display: block; height:100%; width: 100%; content: " "; }
#keyframes circle { 0% { transform: scale(0.5) } 50% { transform: scale(1.2) } 80% { transform: scale(0.95) } 100% { transform: scale(1.0) } }
<div id='parent'>
<div class='child'>
<span class='inner'></span>
</div>
</div>
I have tried to search SO however I find a lot of similar line / scale / keyframe posts but these are intentional line animation posts.
I had the line to on Chrome. So I edited the code a bit, and the line was gone. Not sure what the problem was, just a different solution:
The html:
<div id="parent">
<div class="child">
<div class="inner"></div>
</div>
</div>
And the CSS
#parent {
overflow: hidden;
background: #f0f4ff;
height: 500px;
width: 100%;
position: relative;
user-select: none;
margin-block-end: 5rem;
z-index: 3;
}
.child {
width: 100%;
height: 100%;
position: relative;
}
.inner {
background-color: #d90368;
width: 10rem;
height: 10rem;
position: absolute;
left: calc(50% - 5rem);
top: calc(50% - 5rem);
animation: circle 2s linear infinite;
display: block;
content: " ";
border-radius: 50%;
}
#keyframes circle {
0% {
transform: scale(0.5);
}
50% {
transform: scale(1.2);
}
80% {
transform: scale(0.95);
}
100% {
transform: scale(1);
}
}
I want my image to start with top:0 and ends with bottom:0 with smooth animation. I am struggling to find out the solution.
To be very clear i cannot use background images for SEO purpose. JS solutions are also welcome.
.element {
height: 200px;
width: 400px;
background-color: red;
position: relative;
margin: auto;
overflow: hidden;
}
.element img {
animation: nudge 5s linear infinite alternate;
position: absolute;
top: 0;
left: 0;
}
#keyframes nudge {
0%, 100% {
top: 0;
bottom: auto;
}
50% {
bottom: 0%;
top: auto;
}
}
<div class="element">
<img src="https://www.neelnetworks.com/wp-content/uploads/2018/08/ecommerce-bg.png" alt=""></div>
Instead of trying to animate on top and bottom, you can animate on translateY and move it down with top so it doesnt go off screen
.element {
height: 200px;
width: 400px;
background-color: red;
position: relative;
margin: auto;
overflow: hidden;
}
.element img {
animation: nudge 2s linear infinite alternate;
position: absolute;
top: 0;
transform: translateY(0);
}
#keyframes nudge {
100% {
transform: translateY(-100%);
top: 100%;
}
}
<div class="element"><img src="https://www.neelnetworks.com/wp-content/uploads/2018/08/ecommerce-bg.png" alt=""></div>
I am trying to create a cube out of shorter, stacked rectangular prisms but have run into some issues. I am not concerned about IE just yet, but I am concerned about the huge difference in rendering between Chrome, FF and Safari.
Chrome (v44.0.2403.155)
Safari (v8.0.3)
Firefox (v40.0.2)
Check out the live demo here: http://codepen.io/okeegan/pen/yNWNaw
The basic structure is (edited for brevity):
<div class="allsort positioned"><!-- Wrapper -->
<div class="allsort__layer"><!-- Individual prism in cube -->
<div class="allsort__layer-side bottom"></div><!-- side of prism -->
<div class="allsort__layer-side left"></div>
<div class="allsort__layer-side right"></div>
<div class="allsort__layer-side top"></div>
<div class="allsort__layer-side front"></div>
<div class="allsort__layer-side back"></div>
</div>
</div>
With the following styles:
.page {
perspective: 1000px;
position: fixed;
width: 100%;
height: 100%;
}
.allsort {
backface-visibility: visible;
transition: all 2s;
position: relative;
top: calc(50% - 50px);
width: 100px;
height: 100px;
margin: 0 auto;
}
.allsort.positioned .allsort__layer.pink-1 {
transform: translateY(0) rotateX(-45deg) rotateZ(45deg);
}
.allsort.positioned .allsort__layer.black-1 {
transform: translateY(8px) rotateX(-45deg) rotateZ(45deg);
}
.allsort.positioned .allsort__layer.cream {
transform: translateY(16px) rotateX(-45deg) rotateZ(45deg);
}
.allsort.positioned .allsort__layer.black-2 {
transform: translateY(24px) rotateX(-45deg) rotateZ(45deg);
}
.allsort.positioned .allsort__layer.pink-2 {
transform: translateY(30px) rotateX(-45deg) rotateZ(45deg);
}
.allsort__layer {
backface-visibility: visible;
transform-style: preserve-3d;
transform: translateY(1000px) rotateX(-45deg) rotateZ(45deg);
transition: all 2s ease-in-out;
position: absolute;
top: 0;
left: 0;
width: 65px;
height: 65px;
}
.allsort__layer-side {
backface-visibility: visible;
transition: all 400ms;
transition-delay: 2s;
transform-origin: 50% 50%;
}
.allsort__layer-side.top {
background-color: magenta !important;
height: 55px;
left: 0;
position: absolute;
top: 0;
width: 55px;
}
.allsort__layer-side.bottom {
transform: translateZ(12px);
background-color: yellow !important;
height: 55px;
left: 0;
position: absolute;
top: 0;
width: 55px;
}
.allsort__layer-side.left {
transform-origin: top center;
transform: rotateX(90deg);
background-color: green !important;
height: 12px;
left: 0;
position: absolute;
top: 0;
width: 55px;
}
.allsort__layer-side.right {
transform-origin: center left;
transform: rotateY(-90deg);
background-color: orange !important;
height: 55px;
left: 0;
position: absolute;
top: 0;
width: 12px;
}
.allsort__layer-side.front {
transform-origin: top center;
transform: rotateX(90deg);
background-color: blue !important;
height: 12px;
left: 0;
position: absolute;
top: 55px;
width: 55px;
}
.allsort__layer-side.back {
transform-origin: center left;
transform: rotateY(-90deg);
background-color: red !important;
height: 55px;
left: 55px;
position: absolute;
top: 0;
width: 12px;
}
I have tried fiddling with the order of side stacking in the HTML with poor results. Are there any obvious problems with my setup? I'm pretty sure I've tried every combo of transform-style: preserve-3d and backface-visibility: visible possible but maybe there's a secret formula?
I'm trying to implement a flip on an image but its preserve 3d (or probably backface-visibility) is not working on ie11.
This solution didn't work for me: -webkit-transform-style: preserve-3d not working
Here is a pen for you to try stuff and also a fiddle: http://codepen.io/vandervals/pen/XbedKY?editors=110
.container {
-ms-perspective: 1500px;
perspective: 1500px;
}
.canvas {
position: relative;
width: 300px;
-ms-transform-origin: 50% 50%;
transform-origin: 50% 50% 0;
transition: transform 1s ease 0s;
-ms-transform-style: preserve-3d;
transform-style: preserve-3d;
overflow: visible;
}
.canvas img {
max-width: 100%;
backface-visibility: hidden;
position: relative;
z-index: 2;
}
input:checked + .canvas {
transform: rotateY(180deg);
}
.red {
background: red;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
backface-visibility: hidden;
transform: rotateY(180deg);
}
<div class="container">
<input type="checkbox">
<div class="canvas">
<img src="http://todofondosdeamor.com/wp-content/uploads/images/48/gatitos-1__400x300.jpg">
<div class="red"></div>
</div>
</div>
<p>That checkbox over there</p>
Internet Explorer doesn't support preserve-3d in any version (probably Spartan will).
You need to change the way you have set the transforms if you want it to work (on the item directly instead of the container)
.container{
perspective: 1500px;
}
.canvas{
position: relative;
width: 300px;
transform-origin: 50% 50% 0;
transform-style: preserve-3d;
overflow: visible;
}
.canvas img{
max-width: 100%;
backface-visibility: hidden;
position: relative;
z-index: 2;
transition: transform 1s ease 0s;
}
input:checked + .canvas img {
transform: rotateY(180deg);
}
.red{
background: red;
width: 100%;
height: 100%;
position: absolute;
top:0;
left:0;
z-index: 1;
backface-visibility: hidden;
transform: rotateY(180deg);
transition: transform 1s ease 0s;
}
input:checked + .canvas .red {
transform: rotateY(360deg);
}
<div class="container">
<input type="checkbox">
<div class="canvas">
<img src="http://todofondosdeamor.com/wp-content/uploads/images/48/gatitos-1__400x300.jpg">
<div class="red"></div>
</div>
</div>
<p>That checkbox over there</p>
I have a fiddle http://jsfiddle.net/nLhgT/
I followed the instructions here http://davidwalsh.name/css-flip and http://desandro.github.io/3dtransforms/docs/card-flip.html When I flip the card, only the front side is being shown (flipped). I can't seem to get the backface to show. I've read similar questions on stackoverflow saying the backface must be rotated first. It is indeed rotated initially in my example.
HTML
<ul>
<li>
<div class="container">
<div class="card">
<div class="front">
front
</div>
<div class="back">
back
</div>
</div>
</div>
</li>
</ul>
CSS
li {
width: 300px;
height: 260px;
position: relative;
perspective: 800px;
list-style-type: none;
}
.card {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
-webkit-transition-duration: 400ms;
transition-duration: 400ms;
}
.card div {
display: block;
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.card .front {
background: red;
}
.card .back {
background: blue;
-webkit-transform: rotateY( 180deg );
transform: rotateY(180deg);
}
.card.flip {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
}
JS
$(document.body).on('click', '.card', function() {
console.log("CLICK");
document.querySelector('.card').classList.toggle("flip");
});
The only difference in my example is that the card is within an unordered list. I intend to make a list of these cards. But I don't think that should affect things.
So the main problem is that preserve-3d isn't supported by IE. Huge bummer, but not much that can be done about it. Therefore, you should be applying the transform to each child element, not the entire card.
The best way I've found of making a card flip is as follows:
Transform each face. The front should default to 0, the back to 180. When flipped, they should be 180 and 360 respectively.
Apply a z-index to them. The visible face should have something like 10, while the hidden one has 0. This ensures that the right one is in front at all times (even in browsers that don't support transformations)
Here is my update to your Fiddle showing a working card flip.
Here you go...
Demo Fiddle
HTML:
<ul>
<li>
<div class="container" id="flip-toggle">
<div class="card">
<div class="front">front</div>
<div class="back">back</div>
</div>
</div>
</li>
</ul>
CSS:
li {
width: 300px;
height: 260px;
position: relative;
perspective: 800px;
list-style-type: none;
}
.container {
-webkit-perspective: 1000;
-moz-perspective: 1000;
perspective: 1000;
border: 1px solid #ccc;
}
#flip-toggle.flip .card {
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
filter: FlipH;
-ms-filter:"FlipH";
}
.container, .front, .back {
width: 300px;
height: 260px;
}
.card {
-webkit-transition: 0.6s;
-webkit-transform-style: preserve-3d;
-moz-transition: 0.6s;
-moz-transform-style: preserve-3d;
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
width: 100%;
height: 100%;
}
.front, .back {
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
.front {
background: red;
z-index: 2;
}
.back {
background: blue;
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
transform: rotateY(180deg);
}
JS:
$(document.body).on('click', '.card', function () {
console.log("CLICK");
document.querySelector('#flip-toggle').classList.toggle('flip');
});