I am trying to create a 3d cube effect using css3. I am using translateZ property to create the 3d cube environment when I use translateZ on parent div the child div automatically inherits the property. I have tried to use transform: none and the tried to give negative transform but of no use. Here is an example fiddle
HTML
<div class="box-big">
<div class="box">
<h1>ABCD</h1>
</div>
</div>
CSS
body{
perspective: 1000px;
}
.box-big{
transform-style: perserve-3D;
}
.box{
width: 300px;
height: 300px;
background: #FF0000;
transform: translateZ(400px);
}
h1{
font-color: white;
line-height: 300px;
text-align: center;
transform: translateZ(-400px);
}
All the children of the parent are going to be rendered according to the parent, so what you are asking is not possible. You would have to re-transform it to what you want, or probably your best bet is to use some "layering" technique (such as position: absolute or negative margins) so that the h1 can be outside of the .box element, but still appear "on top" of the .box element.
Here's a working example:
Modified HTML:
<div class="wrapper">
<div class="box-big">
<div class="box">
</div>
</div>
<h1>ABCD</h1>
</div>
Modified CSS:
body{
perspective: 1000px;
}
.wrapper {
position: relative;
}
.box-big {
transform-style: preserve-3D;
}
.box{
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 200px;
background: #FF0000;
transform: translateZ(300px);
z-index: 1;
}
h1 {
position: absolute;
top: 0;
left: 0;
width: 200px;
color: white;
line-height: 200px;
text-align: center;
z-index: 255555;
}
https://jsfiddle.net/kcobbvcL/4/
As a side note, your fiddle css has some typos. Be sure to use a good IDE or a browser tool to watch for illegal / invalid css.
every cube has 6 sides, so u should use 6 div s. As we want to move the whole cube we should include those 6 div s in one div (div#cube).
first, you should create the cube using css, as the example below, then you translate or rotate the cube, using transform in div#cube.
.container {
width: 200px;
height: 200px;
position: relative;
perspective: 1000px;
}
#cube {
width: 100%;
height: 100%;
position: absolute;
transform-style: preserve-3d;
}
#cube figure {
width: 196px;
height: 196px;
display: block;
position: absolute;
border: 2px solid black;
}
#cube .front { transform: rotateY( 0deg ) translateZ( 100px ); }
#cube .back { transform: rotateX( 180deg ) translateZ( 100px ); }
#cube .right { transform: rotateY( 90deg ) translateZ( 100px ); }
#cube .left { transform: rotateY( -90deg ) translateZ( 100px ); }
#cube .top { transform: rotateX( 90deg ) translateZ( 100px ); }
#cube .bottom { transform: rotateX( -90deg ) translateZ( 100px ); }
#cube{
transition: all 1s;
}
#cube:hover{
transform: rotateY( -20deg );
/*transform: translateZ( -100px );*/
}
<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>
Related
I have two div elements: one parent element, which is rotated, and one child element that I need to be unaffected by the rotation of the parent element.
To achieve this, I have attempted to rotate the child element in the opposite direction of the parent element. This works in some cases. For instance, if I rotate the elements like this ...
.parent {
transform: rotate(30deg);
}
.child {
transform: rotate(-30deg);
}
... the child element will appear straight and undistorted. But if I rotate them with rotateX ...
.parent {
transform: rotateX(30deg);
}
.child {
transform: rotateX(-30deg);
}
... the child element still looks rather distorted.
The actual code uses both rotateX and rotateZ in order to make the parent element appear isometric. It currently looks like this:
.happy_parent {
width: 100px;
height: 100px;
background-color: green;
transform: rotate(30deg);
}
.happy_child {
width: 50px;
height: 50px;
background-color: yellow;
transform: rotate(-30deg);
}
.sad_parent {
width: 100px;
height: 100px;
background-color: green;
transform: rotateX(-60deg) rotateZ(45deg);
}
.sad_child {
width: 50px;
height: 50px;
background-color: yellow;
transform: rotateX(60deg) rotateZ(45deg);
}
<div class="happy_parent">
<div class="happy_child"></div>
</div>
<div class="sad_parent">
<div class="sad_child"></div>
</div>
Notice that the upper divs are both rendered correctly, but the lower child-div is still distorted.
What am I missing here?
It is not possible to have the innerElement (childElement) to remain in initial state when rotated in 3D by rotating back in -ve deg.
It will work when rotation takes place in 2D .
But you can give a try to transform-style: preserve-3d to see the shapes in 3D effect when rotated with Z coordinate also and preserve the shape instead of just showing in 2D .
You have to reverse the order of rotation too in 3D rotation
You can try to remove the transform-style: preserve-3d and see the effect
.happy_parent {
width: 100px;
height: 100px;
background-color: green;
transform: rotate(30deg);
}
.happy_child {
width: 50px;
height: 50px;
background-color: yellow;
transform: rotate(-30deg);
}
.sad_parent {
width: 100px;
height: 100px;
background-color: green;
transform: rotateX(-60deg) rotateZ(45deg);
transform-style: preserve-3d;
}
.sad_child {
width: 50px;
height: 50px;
background-color: yellow;
transform: rotateZ(-45deg) rotateX(60deg);
}
<div class="happy_parent">
<div class="happy_child"></div>
</div>
<br><br><br><br>
<div class="sad_parent">
<div class="sad_child"></div>
</div>
I have a product div and whenever I hover over it, it rotated and shows the other side, it works and all but the thing is it becomes smaller, here's an idea of what it looks like here.
.product {
transform: scale(1.5);
transition: transform 1s cubic-bezier(.1, -.60, .50, 1.2);
perspective: 700px;
transform-style: preserve-3d;
}
.inner img {
height: 65px;
width: 65px;
}
.product:hover {
transform: rotateY(-180deg);
}
.product:hover .side-b {
transform: rotateY(180deg);
display: block;
}
.product:hover .side-a {
visibility: hidden;
}
.product-desc {
color: #fff;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding-left: 20px;
padding-right: 20px;
display: flex;
/* For centering text inside .photo-overlay */
flex-direction: column;
justify-content: center;
align-items: center;
display: none;
line-height: 0;
}
<li>
<div class="product">
<div style="height: 7px;visibility: hidden;"></div>
<div class="inner">
<img class="side-a" src="../images/test.jpg" alt="International Space Station">
<div class="product-desc side-b">
<h3>hi</h3>
buy
</div>
</div>
</div>
</li>
The resizing is because of your first rule transform: scale(1.5);. It tells the browser to initially resize the .product element to 50% more than its original size. But than on hover, you overwrite your transform- rule by only a rotation statement. Either delete this first rule or also use it in your :hover definition:
.product:hover {
transform: scale(1.5) rotateY(-180deg);
}
The transform: scale(1.5); created the problem!
Thanks to #Mohd Asim Suhail for pointing it out!
transform: scale(1.5); is creating problem for you, – Mohd Asim Suhail 3 mins ago
I have two identical elements. The top one, I'm scaling to double the size and then centering over the normal-sized one. I want its inner element to then be scaled back down to normal size and placed exactly where the normal sized element's inner element is placed.
This seems to be impossible. There seems to be no logic in the scaling + translation of position.
How would I do this?
https://jsfiddle.net/0urdrvao/
HTML:
<div class="top">
<div class="inner">
Inner
</div>
</div>
<div class="bottom">
<div class="inner">
Inner
</div>
</div>
CSS:
body, html
{
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
.top,
.bottom
{
position: relative;
top: 0px;
left: 0px;
width: 300px;
height: 300px;
background-color: gray;
z-index: 0;
}
.top
{
position: fixed;
transform-origin: 0 0 0;
transform: translate(-150px, -150px) scale(2);
opacity: .5;
z-index: 1;
}
.inner
{
position: relative;
top: 20vh;
left: 0px;
width: 100px;
height: 40px;
background-color: red;
}
.top .inner
{
/* This doesn't work */
transform: translate(150px,150px) scale(.5);
/* This also doesn't work (doing half)*/
/*transform: translate(75px,75px) scale(.5);*/
/* This also doesn't work (doing double)*/
/*transform: translate(300px,300px) scale(.5);*/
transoform-origin: 0 0 0;
background-color: yellow;
}
Since the top: 20vh will be scaled times 2, the transform-origin should be 0 -20vh.
When reverse a scale/translate you need to go backwards and start with scale and then the translate
.top{
position: fixed;
transform-origin: 0 0;
transform: translate(-150px, -150px) scale(2);
opacity: .5;
z-index: 1;
}
.top .inner{
transform: scale(.5) translate(150px, 150px);
transform-origin: 0 -20vh;
background-color: yellow;
}
Updated fiddle
Or one could do like this, setting origin to 0 0 and transform: scale(.5) translate(150px,150px) translateY(-20vh);
Updated fiddle
I currently need to make something with CSS that would look like this:
I managed to do it with this:
.top {
position: relative;
}
.top .gray-bar {
position: absolute;
width: 100%;
height: 50px;
background-color: #cdcbcc;
-ms-transform: rotate(1.2deg);
transform: rotate(1.2deg);
margin-top: -25px;
z-index: 2;
}
.top .cyan-bar {
position: absolute;
width: 100%;
height: 90px;
background-color: #2ca1ab;
-ms-transform: rotate(-3deg);
transform: rotate(-3deg);
z-index: 1;
margin-top: -30px;
margin-left: -400px;
}
.top .purple-bar {
position: absolute;
width: 100%;
height: 50px;
background-color: #b71e4c;
-ms-transform: rotate(0.7deg);
transform: rotate(0.7deg);
margin-top: -5px;
z-index: 0;
}
<div class="top">
<div class="gray-bar"></div>
<div class="cyan-bar"></div>
<div class="purple-bar"></div>
</div>
However, when I resize my window, at some point of time, the "cyan" triangle is causing issue because of the margins and the rotation. Therefore, I added some media queries to modify the rotation angle depending on the width of the screen but I feel that it's a bit "playing around" and that there is a better solution to achieve this.
I tried using borders to make the overlapping triangles but as it cannot be expressed as percentage, I'm a bit stuck. Indeed, the goal is that the result looks about the same whatever the user's screen resolution.
Is there a better solution than mine ?
Considering that the .top element uses the full viewport width, you can use viewport percentage units for the borders. This will make the triangles relative to the viewport width.
See this example with one div :
body,html{margin:0;padding:0;}
.topBar{
position:relative;
height:35px;
border-bottom:30px solid transparent;
border-right:100vw solid #B71E4C;
}
.topBar:before, .topBar:after{
content:'';
position:absolute;
top:0; left:0;
height:15px;
}
.topBar:before{
border-bottom:50px solid transparent;
border-left:100vw solid #2CA1AB;
}
.topBar:after{
border-bottom:40px solid transparent;
border-right:100vw solid #CDCBCC;
}
<div class="topBar"></div>
Maybe this help you, but, #web-tiki its the best solution, using pseudo-selectors: :before & :after
.top {
overflow: hidden;
height: 90px;
}
.top .gray-bar {
position: relative;
width: 100%;
height: 50px;
background-color:#cdcbcc;
-ms-transform: rotate(1.3deg);
transform: rotate(1.3deg);
margin-top:-35px;
z-index: 2;
}
.top .cyan-bar {
position: relative;
width: 150%;
height: 50px;
background-color:#2ca1ab;
-ms-transform: rotate(-2deg);
transform: rotate(-2deg);
z-index:1;
top: -5px;
margin-top:-30px;
margin-left:-100px;
}
.top .purple-bar {
position: relative;
width: 100%;
height: 20px;
background-color:#b71e4c;
-ms-transform: rotate(0.7deg);
transform: rotate(0.7deg);
margin-top: -20px;
z-index:0;
}
<div class="top">
<div class="gray-bar"></div>
<div class="cyan-bar"></div>
<div class="purple-bar"></div>
</div>
I have a main div (the red div in the fiddle) that has a smaller vertical tab on the side (the blue div in the fiddle).
The RED div is standard BUT the Blue div is rotated through 90 degrees (as I need to have vertical text in it). This is where the problems starts.
The red div is vertically positioned at 50% so it is in the middle of the page and locked with scrolling etc.
I want to align the blue div so that the top edge of the blue div is at the same Y position as the top edge of the red div.
I would prefer NOT to use jQuery but can do if required.
Desired output :
Fiddle is here : http://jsfiddle.net/kBKf6/
Here is the code I am using :
<div id="main" style="position: fixed; top: 50%; margin-top: -250px; left:0; height: 500px; width: 450px; background-color:red;">
Main Content Div
</div>
<div id="vertical_div" style="overflow:hidden; position: fixed; left:350px; height:40px; width:200px; margin: auto; background-color:blue; text-align:center; color:white; -webkit-transform: rotate(90deg) translate(-50%, -50%); -moz-transform: rotate(90deg) translate(-50%, -50%); -ms-transform: rotate(90deg) translate(-50%, -50%); -o-transform: rotate(90deg) translate(-50%, -50%); transform: rotate(90deg) translate(-50%, -50%);">
Side Tab
</div>
You don't need JS to align the rotated div. You can define a transform origin in CSS then, it becomes easy to align.
Side note : You can remove the -moz- and -o- vendor prefixes see caniuse
DEMO
HTML :
<div id="main">Main Content Div
<div id="verticaldiv">Side Tab</div>
</div>
CSS :
#main {
position: fixed;
top: 50%;
margin-top: -250px;
left:0;
height: 500px;
width: 450px;
background-color:red;
}
#verticaldiv {
overflow:hidden;
position: absolute;
left:100%;
bottom:100%;
height:40px;
width:200px;
background-color:blue;
text-align:center;
color:white;
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
-ms-transform-origin:0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
}
You can also do it without relying on hardcoded sizes that move your div into position, but you need a wrapper around your .verticaldiv
demo:
http://jsfiddle.net/MCr6f/
demo 2:
http://jsfiddle.net/9LtKw/ (to show that different sizes don't matter)
html:
<div class="one">
Hello
<div class="pivot">
<div class="two">
Pretty!
</div>
</div>
</div>
css:
.one {
background: red;
position: relative;
float: left;
/*strange and difficult sizes*/
font-size: 3.237827em;
padding: 10px;
}
.pivot {
position: absolute;
top: 0;
right: 0;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
transform: rotate(90deg);
width: 0px;
height: 0px;
}
.two {
background: blue;
color: white;
position: absolute;
left: 0;
bottom: 0;
/*strange and difficult sizes*/
font-size: 12px;
padding: 0.3em;
}