I create two squares with z translate and put in perspective-origin in css.
This is the link to jsbin: https://jsbin.com/bebucum/edit?html,output.
Following is the most relevant CSS:
.container {
-webkit-perspective: 700;
-webkit-perspective-origin: 450px 000px;
}
.square:nth-child(1) {
-webkit-transform: translateZ(100px);
}
.square:nth-child(2) {
background: yellow;
-webkit-transform: translateZ(-200px);
}
Most of the output makes sense to me. However there is one part I do not quite understand.
I think the yellow square should be below the blue one, as its translateZ is negative. But the output is the other way around.
Can someone help me understand this behavior?
To achieve correct 3d positioning, you need to set
transform-style: preserve-3D;
I have also removed webkit prefixes, they aren't necesary now.
.container {
perspective: 700px;
perspective-origin: 450px 0px;
transform-style: preserve-3D;
}
.square {
background: blue;
position: relative;
top: 300px;
left: 300px;
height: 100px;
width: 100px;
}
.square:nth-child(1) {
transform: translateZ(100px);
}
.square:nth-child(2) {
background: yellow;
transform: translateZ(-200px);
}
<div class="container">
<div class="square">
</div>
<div class="square">
</div>
</div>
Related
My end goal is a draggable, resizable, Scalable, and rotatable element, just like the example on: https://daybrush.com/moveable/ only by using css width,height, and transform: rotate, translate.
Say I have a div with following css:
.rect {
background-color: red;
width: 200px;
height: 100px;
top:100px;
left:100px;
position: absolute;
transform: rotate(0deg);
}
<div class="rect"></div>
If I want to resize the div horizontally to the left, I just change the width by x pixels. If I want to change it to the right I just change the width by x pixels, and translate(-xpx, 0).
But what if I change the angle? From trying a lot of stuff, I found some of the x and y values for translate to the respective angle, however I feel like there is a more straight forward way than just guessing. E.g: For 90deg, if I want to resize to the left by x px I do translate(-x0.5px, x0.5px).
More: what if I want to change both the width & height at the same time?
P.S.: I would rather avoid using libraries, transform: scale or svg
P.P.S:Example to further demonstrate the problem, just changing the width:
.rect {
background-color: red;
width: 200px;
height: 100px;
top:100px;
left:100px;
position: absolute;
transform: rotate(45deg);
animation: expand 5s infinite
}
#keyframes expand {
from {width: 200px;}
to {width: 2000px;}
}
<div class="rect"></div>
Fixed, stretching the left side of the original rectagle (now up since rotated 90deg):
.rect {
background-color: red;
width: 200px;
height: 100px;
top:100px;
left:100px;
position: absolute;
transform: rotate(90deg);
animation: expand 3s infinite
}
#keyframes expand {
from {
width: 200px;
}
to {
width: 800px;
transform: rotate(90deg) translate(-300px, 300px);
}
}
<div class="rect"></div>
You can apply several transformations to the same object and they will be composed in the order that you specify. Move then rotate, is different than rotate then move.
.rect {
background-color: red;
width: 200px;
height: 100px;
top:100px;
left:100px;
position: absolute;
}
.t1 {
background-color: #40d04080;
/* green shaded rectangle: rotate after translation */
transform: translate(2cm, 0) rotate(30deg);
}
.t2 {
background-color: #f0404080;
transform: rotate(30deg);
}
.t3 {
background-color: #4040f080;
/* blue shaded rectangle: translate after rotation */
transform: rotate(30deg) translate(2cm, 0) ;
}
<div class="rect t1"></div>
<div class="rect t2"></div>
<div class="rect t3"></div>
I am trying to understand what is really happening “3d” world of CSS.
I made a simple example
Particularly the code which bugs me the most is:
.back {
background-color: tomato;
transform: rotateY(180deg);
z-index: 1;
}
The thing which is not clear to me is why when you hover over .inner, its background color (gold) is not visible?? If you remove the transform property from .back or if you set the rotateY to 0deg then the gold background color of the .inner is clearly visible.
Why is the transform property of .back changing the stacking order?
Logically it makes sense that children(.front and .back) should appear in front of their parent(.inner).
Also, I would like to know what really happens when you set transform-style to flat? Does that make parent and all of its children collapse into single “unit” where element with highest stacking order takes priority/visibility?
in your code :
.outer {
display: block;
width: 200px;
height: 200px;
border: 2px solid gold;
perspective: 1000px;
padding: 10px;
margin: 0 auto;
}
.inner {
position: relative;
height: 100%;
width: 100%;
transition: transform 2s linear;
transform-style: preserve-3d;
background-color: gold;
backface-visibility: visible;
transform: rotateY(50deg);
}
.sides {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
color: white;
backface-visibility: hidden;
}
.front {
background-color: blue;
transform: translateZ(20px)
}
.back {
background-color: tomato;
transform: rotateY(180deg) translateZ(10px);
}
.inner:hover {
transform: rotateY(180deg)
}
<div class="outer">
<div class="inner">
<div class="sides front">Front Side</div>
<div class="sides back">Back Side</div>
</div>
</div>
you are using
transform: rotateY(180deg) translateZ(10px);
The transforms are applied right to left, so first it goes to the front 10px. But after that, it rotates 180deg. (around the transform-origin that is constant). That makes the previous 10px go towards the back instead of to the front.
if the order is the inverse
transform: translateZ(10px) rotateY(180deg);
now the rotation is done first, and so the translation is unafected by it and goes to the front.
and No, sorry, z-index is not a substitute for 3-d transforms, if you want to use 3d transforms, translation is the only way to go ....
In your first example, z-index is useless, as can be seen easily
codepen with z-index removed
This works because you are setting
backface-visibility: hidden;
So only the face that is facing front will be visible
Here is a simple horizontal flip animation - http://jsfiddle.net/vntajmgh/2/
and I see 2 issues:
Open the url in chrome. Hover over the red div. The flip is ok, but the background color for the back div(blue) is not applied.
Open the url in firefox. The flip is like stuck. I can see the blue colored back div sometimes.
I guess it's 'stuck' here because the height is 100vh, which when reduced works fine, but should it not work with the full height too?
.flip-container {
width: 150px;
height: 100vh;
perspective: 800px;
color: #fff;
position: relative;
}
.flipper {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transition: transform linear 0.6s;
}
.flipper div {
margin: 0;
display: block;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flipper .front {
background: red;
}
.flipper div:after {
content:"";
display: block;
position: absolute;
top: 0;
left: 0;
background-image: url("http://www.transparenttextures.com/patterns/3px-tile.png");
width: 100%;
height: 100%;
opacity: 0.5;
z-index: 1;
}
.flipper .back {
background: blue;
transform: rotateY(180deg);
}
.flipper:hover {
transform: rotateY(180deg);
}
<div class="flip-container">
<div class="flipper">
<div id="1front" class="front">1-front</div>
<div id="1back" class="back">1-back</div>
</div>
</div>
UPDATE:
Here is the working fiddle - http://jsfiddle.net/gf3g8sz1/1/
Add an overflow hidden to the parent div(flip-container). When we are using 100vh(view port height) with rotate transform property, its actually taking more height than the view port has. so hide it by using overflow hidden.
css
.flip-container {
overflow:hidden;
}
To get the same hover effect in both browser you have to modify the hover CSS.
DEMO
removing:
backface-visibility: hidden;
will make the back color visible
The problem in Chrome is caused by the pseudo element. I have changed the way to get the image blended with red without an pseduo element, and now it works OK.
The problem in FF is caused by the reduced-disappeared size of the element that receives the hover. I have changed the hover so that it is triggered by the container, and now it works also ok.
It is always a good idea to avoid using hover on transformed elements, they usually give some kind of problems
.flip-container {
width: 150px;
height: 100vh;
perspective: 800px;
color: #fff;
position: relative;
}
.flipper {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
transition: transform linear 0.6s;
}
.flipper div {
margin: 0;
display: block;
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flipper .front {
background: red;
background-image: linear-gradient(rgba(255,0,0,0.5),rgba(255,0,0,0.5)), url("http://www.transparenttextures.com/patterns/3px-tile.png");
}
.flipper .back {
background: blue;
transform: rotateY(180deg);
}
.flip-container:hover .flipper {
transform: rotateY(180deg);
}
<div class="flip-container">
<div class="flipper">
<div id="1front" class="front">1-front</div>
<div id="1back" class="back">1-back</div>
</div>
</div>
I would like to get an effect of an outer element tilting back along the z axis and an inner element standing up out of it in a normal 2d perspective. In other words given this html
<div id="outer">
<div id="inner"></div>
</div>
I would like the outer element to tilt backwards with its side lines approaching a vanishing point while the inner element's sides are vertical.
How do I achieve this? Using the css
div {
display: inline-block;
}
#outer {
padding: 20px;
background-color: blue;
-webkit-transform: perspective(400px) rotateX(45deg)
}
#inner {
height: 150px;
width: 150px;
background-color: tomato;
background-image: url(http://www.w3schools.com/html/smiley.gif);
background-size: 100%;
}
I thought I could just do
#inner {
-webkit-transform: rotateX(-45deg);
}
but that just makes it tilt more.
Here is a jsbin
You need to set preserve 3d
#outer {
padding: 20px;
background-color: blue;
-webkit-transform: perspective(400px) rotateX(45deg);
-webkit-transform-style: preserve-3d;
}
#inner {
height: 150px;
width: 150px;
background-color: tomato;
background-image: url(http://www.w3schools.com/html/smiley.gif);
background-size: 100%;
-webkit-transform: rotateX(-45deg);
-webkit-transform-origin: bottom center;
}
jsbin
I looked around but can't find any good resources for doing higher level animations (like card flip, cubes, etc). Like a ???:CSS :: jQuery:JS.
I know of transit but I'm looking for something that has more functionality and animations built in.
Have you thought about using Animate.css? Seems pretty good. Another good one seems like CSS3 Animations and for stuff like card-flipping, CSS3 Playground.
An edited version of this one: http://css3.bradshawenterprises.com/flip/:
JSfiddle: http://jsfiddle.net/PnUHr/1/
CSS
#f1_container {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
}
#f1_container {
-webkit-perspective: 1000;
perspective: 1000;
}
#f1_card {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: all 1.0s linear;
transform-style: preserve-3d;
transition: all 1.0s linear;
}
#f1_container:hover #f1_card {
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
box-shadow: -5px 5px 5px #aaa;
}
.face {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.face.back {
display: block;
-webkit-transform: rotateY(180deg);
transform: rotateY(180deg);
box-sizing: border-box;
color: white;
text-align: center;
background-color: #aaa;
}
HTML
<div id="f1_container">
<div id="f1_card" class="shadow">
<div class="front face">
<img src="Cirques.jpg"/>
</div>
<div class="back face center">
<img src="Cirques.jpg" style="transform:scaleX(-1), transform:scaleY(-1)"/>
</div>
</div>
</div>
All credits go to the original created (see link). I've just removed the padding that was on the back-facing <div> and added a mirrored background of the front-facing image.
For Mozilla/Gecko browsers you need to add the -moz-* prefixes too. Same for Opera (-o-*) and Internet Explorer (-ms-*`).
Direct image link: http://css3.bradshawenterprises.com/images/Cirques.jpg
Effeckt.css is STILL work in progress but look very promising– a pattern libary of multiple sources.