CSS Cube not rotating properly - html

I am trying to make a cube with basic HTML and CSS. I have rotated every side on their position but on rotating the whole cube, I can see some blank area. Don't know what the problem is. Please help me solve this.
body {
width: 100vw;
height: 100vh;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center; }
#container {
position: relative;
width: 100px;
height: 100px;
border-radius: 20px;
background: transparent;
perspective: 9990px;
transform: rotateY(80deg);
transform-style: preserve-3d;
transform-origin: 50px 50px 0; }
#container .face {
width: 100px;
height: 100px;
background: #ddd;
position: absolute;
transition: all 0.2s;
backface-visibility: hidden;
border: 1px solid black; }
#container #face1 {
background: green;
transform: translateZ(-50px); }
#container #face2 {
background: red;
transform: translateX(50px) rotateY(90deg); }
#container #face3 {
background: blue;
transform: translateX(-50px) rotateY(90deg); }
#container #face4 {
background: yellow;
transform: translateZ(50px); }
#container #face5 {
background: purple;
transform: translateY(-50px) rotateX(90deg); }
#container #face6 {
background: cyan;
transform: translateY(50px) rotateX(90deg); }
<div id="container">
<div class="face" id="face1"></div>
<div class="face" id="face2"></div>
<div class="face" id="face3"></div>
<div class="face" id="face4"></div>
<div class="face" id="face5"></div>
<div class="face" id="face6"></div>
</div>

You are almost good, you need to define perspective on the body element (the parent of the cube) and you can get rid of backface-visibility: hidden;
body {
width: 100vw;
height: 100vh;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
perspective: 500px; /* here */
}
#container {
position: relative;
width: 100px;
height: 100px;
border-radius: 20px;
background: transparent;
transform: rotateY(20deg) rotateX(30deg);
transform-style: preserve-3d;
transform-origin: 50px 50px 0;
}
#container .face {
width: 100px;
height: 100px;
background: #ddd;
position: absolute;
transition: all 0.2s;
/*backface-visibility: hidden;*/
border: 1px solid black;
}
#container #face1 {
background: green;
transform: translateZ(-50px);
}
#container #face2 {
background: red;
transform: translateX(50px) rotateY(90deg);
}
#container #face3 {
background: blue;
transform: translateX(-50px) rotateY(90deg);
}
#container #face4 {
background: yellow;
transform: translateZ(50px);
}
#container #face5 {
background: purple;
transform: translateY(-50px) rotateX(90deg);
}
#container #face6 {
background: cyan;
transform: translateY(50px) rotateX(90deg);
}
<div id="container">
<div class="face" id="face1"></div>
<div class="face" id="face2"></div>
<div class="face" id="face3"></div>
<div class="face" id="face4"></div>
<div class="face" id="face5"></div>
<div class="face" id="face6"></div>
</div>

I just made a light edit on #container .face css rules, and the blank area is not visble. Is it well what you need ?
body {
width: 100vw;
height: 100vh;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center; }
#container {
position: relative;
width: 100px;
height: 100px;
border-radius: 20px;
background: transparent;
perspective: 9990px;
transform: rotateY(80deg);
transform-style: preserve-3d;
transform-origin: 50px 50px 0; }
#container .face {
width: 100px;
height: 100px;
background: #ddd;
position: absolute;
transition: all 0.2s;
backface-visibility: visible; /* changed from hidden to visible */
border: 1px solid black; }
#container #face1 {
background: green;
transform: translateZ(-50px); }
#container #face2 {
background: red;
transform: translateX(50px) rotateY(90deg); }
#container #face3 {
background: blue;
transform: translateX(-50px) rotateY(90deg); }
#container #face4 {
background: yellow;
transform: translateZ(50px); }
#container #face5 {
background: purple;
transform: translateY(-50px) rotateX(90deg); }
#container #face6 {
background: cyan;
transform: translateY(50px) rotateX(90deg); }
<div id="container">
<div class="face" id="face1"></div>
<div class="face" id="face2"></div>
<div class="face" id="face3"></div>
<div class="face" id="face4"></div>
<div class="face" id="face5"></div>
<div class="face" id="face6"></div>
</div>

Related

(CSS) How to create a 3d element within another 3d element with CSS transforms?

I am learning React JS and also brushing up on some CSS styling. I have a small app that is basically a drum machine that I wanted to style to look as a launchpad using 3D transformations and CSS. The algorithm itself works, so I made the body of the launchpad, but I also wanted to make 3D buttons for it which would visually sink in when interacted with (either on click or key down). But I can't figure out how to make the buttons into cuboids that go on top of the main cuboid (the drumpad). They just remain flat in the top plane of the launchpad cuboid.
Codesandbox
Relevant JSX code:
The launchpad itself:
return (
<div className="drum-container">
<div className="drum-body">
<div id="drum-machine" className="side top">
<div className="drum-header">
<span>Beat Pro X</span>
<span>{clipName}</span>
</div>
<div id="display">
{keys.map((element, index) => {
return (
<Drumpad
key={element}
clip={clips[index]}
pressKey={element}
onClick={handleDrumpadClick}
onKeyDown={handleDrumpadClick}
/>
);
})}
</div>
</div>
<div className="side bottom"></div>
<div className="side left"></div>
<div className="side right"></div>
<div className="side front"></div>
<div className="side back"></div>
</div>
</div>
);
The Drumpad element:
return (
<div className="drumpad-button">
<div
ref={drumpadRef}
id={props.clip.name}
className="dpad-side dpad-top"
onClick={playAudio}
>
<span className="drum-pad-key">{props.pressKey}</span>
<audio ref={audioRef} className="clip" src={props.clip.source} />
</div>
<div className="dpad-side dpad-bottom"></div>
<div className="dpad-side dpad-left"></div>
<div className="dpad-side dpad-right"></div>
<div className="dpad-side dpad-front"></div>
<div className="dpad-side dpad-back"></div>
</div>
);
CSS:
* {
box-sizing: border-box;
}
body,
html {
margin: 0;
padding: 0;
background-color: darkgrey;
}
#root {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
.drum-container {
display: flex;
justify-content: center;
align-items: center;
border: 2px solid white;
border-radius: 4px;
height: 100%;
width: 100%;
perspective: 1500px;
perspective-origin: center;
}
.drum-body {
padding: 0;
margin: 0;
position: relative;
height: 700px;
width: 700px;
transform-style: preserve-3d;
transform: rotateX(-50deg);
}
.side {
border-radius: 15px;
position: absolute;
opacity: 0.9;
border: 2px solid white;
}
.front {
left: 100px;
top: 300px;
height: 100px;
width: 500px;
background-color: #d50000;
transform: translateZ(350px);
}
.back {
left: 100px;
top: 300px;
height: 100px;
width: 500px;
background-color: #aa00ff;
transform: translateZ(-350px);
}
.left {
top: 300px;
height: 100px;
width: 700px;
background-color: #304ffe;
transform: rotateY(90deg) translateZ(250px);
}
.right {
top: 300px;
height: 100px;
width: 700px;
background-color: #0091ea;
transform: rotateY(-90deg) translateZ(250px);
}
.top {
left: 100px;
height: 700px;
width: 500px;
background-color: #00bfa5;
transform: rotateX(90deg) translateZ(50px);
}
.bottom {
left: 100px;
height: 700px;
width: 500px;
background-color: #64dd17;
transform: rotateX(-90deg) translateZ(50px);
}
#display {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
row-gap: 20px;
column-gap: 20px;
padding: 0;
border: 0;
width: 80%;
margin: 200px auto 100px auto;
}
.drumpad-button {
border: 2px solid black;
position: relative;
padding: 0;
height: 120px;
width: 120px;
transform-style: preserve-3d;
transform: rotateX(30deg);
}
.dpad-side {
border-radius: 2px;
position: relative;
opacity: 0.9;
border: 2px solid white;
}
.dpad-front {
height: 20px;
width: 120px;
background-color: #d50000;
transform: translateZ(60px);
}
.dpad-back {
height: 20px;
width: 120px;
background-color: #aa00ff;
transform: translateZ(-60px);
}
.dpad-left {
height: 20px;
width: 120px;
background-color: #304ffe;
transform: rotateY(90deg) translateZ(60px);
}
.dpad-right {
height: 20px;
width: 120px;
background-color: #0091ea;
transform: rotateY(-90deg) translateZ(60px);
}
.dpad-top {
height: 120px;
width: 120px;
background-color: darkgreen;
transform: rotateX(90deg) translateZ(10px);
}
.dpad-bottom {
height: 120px;
width: 120px;
background-color: #64dd17;
transform: rotateX(-90deg) translateZ(10px);
}
Drumpads are in a grid, so I've tried setting the grid as the basis for the transform-style: preserve-3d, thinking that the grid elements as its children would then treat the top face of the launchpad as the base plane, but maybe there's something else I am doing wrong?
But from my understanding preserve-3d should be set on the element containing the elements that make up the figure in 3D space. When I change translateZ values I can see different planes popping up, but for some reason preserve-3d is ignored. Is it because of the grid? Or maybe specifics of the JSX nesting of imported components?

Why is rotating element not showing?

Trying to create a rotating "card". The cover, inside-left, and inside-right all work fine. The back however is giving me issues. I applied the same rules to each panel so I don't know where the bug is coming from.
.scene {
margin-top: 10em;
margin-left: 20em;
width: 20em;
height: 20em;
perspective: 40em;
}
.cube {
width: 100%;
height: 100%;
position: relative;
animation: spinning 12s infinite;
transform-style: preserve-3d;
transform-origin: left;
}
#keyframes spinning {
from {
transform: translateY(5em) rotateY(0deg);
}
to {
transform: translateY(5em) rotateY(-360deg);
}
}
.front-left {
width: 60%;
height: 100%;
position: absolute;
line-height: 10em;
text-align: center;
transform-origin: left;
}
.panel-1 {
width: 100%;
height: 100%;
border-style: solid;
position: absolute;
backface-visibility: hidden;
}
.cover {
background-color: blue;
}
.left {
background-color: red;
transform: rotateY(180deg);
}
.right-back {
width: 60%;
height: 100%;
position: absolute;
line-height: 10em;
text-align: center;
transform: rotateY(130deg);
transform-origin: left;
}
.panel-2 {
width: 100%;
height: 100%;
border-style: solid;
position: absolute;
backface-visibility: hidden;
}
.end {
background-color: blue;
transform: rotateY(180deg);
}
.right {
background-color: red;
}
<div class="scene">
<div class="cube">
<div class="front-left">
<div class="panel-1 cover">cover</div>
<div class="panel-1 left">inner left</div>
</div>
<div class="right-back">
<div class="panel-2 end">back</div>
<div class="panel-2 right">inner right</div>
</div>
</div>
</div>
here is a fiddle of the code. https://jsfiddle.net/7xtv90as/
I suspect it might be because a transform is applied to the parent container but I am not sure.

Strange bug with divs at same height overlapped with different z-index and with parent overflow hidden: border-bottom always is visible?

I created a speedometer that works very well and is to light (with CSS3,html and js code).
But i noticed a strange bug with iphone....
This is the CODE:
$('#first').addClass('first-start');
//SECOND BAR
$('#second').addClass('second-start');
setTimeout(function() {
$('#second').addClass('second-pause');
}, 400);
#page {
margin-top: 50px;
width: 300px;
height: 300px;
background-color: #000;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
z-index: 4;
overflow: hidden;
}
#box-first,
#box-second {
width: 200px;
height: 100px;
background-color: #fff;
border-radius: 200px 200px 0 0;
margin-top: 10px;
margin-bottom: 10px;
position: relative;
display: flex;
justify-content: flex-end;
align-items: flex-start;
z-index: 3;
overflow: hidden;
}
#first,
#second {
border-radius: 200px 200px 0 0;
margin: 0;
background: red;
width: 200px;
height: 100px;
transform: rotate(180deg);
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform-origin: 50% 100%;
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
position: absolute;
top: 0px;
right: 0px;
border: 0;
z-index: 1;
}
#n1,
#n2 {
font-size: 20px;
color: #fff;
font-weight: bold;
position: absolute;
left: 50px;
right: 0;
text-align: center;
top: 50px;
bottom: 0;
display: flex;
align-items: flex-end;
justify-content: center;
width: 100px;
height: 50px;
background: #000;
border-radius: 100px 100px 0 0;
z-Index: 1;
overflow: hidden;
}
#keyframes first {
0% {
background-color: green;
transform: rotate(180deg);
}
33% {
background-color: yellow;
transform: rotate(240deg);
}
66% {
background-color: orange;
transform: rotate(300deg);
}
100% {
background-color: red;
transform: rotate(360deg);
}
}
#keyframes second {
0% {
background-color: green;
transform: rotate(180deg);
}
33% {
background-color: yellow;
transform: rotate(240deg);
}
66% {
background-color: orange;
transform: rotate(300deg);
}
100% {
background-color: red;
transform: rotate(360deg);
}
}
.first-start,
.second-start {
animation: first 2s linear forwards;
}
.first-pause,
.second-pause {
animation-play-state: paused;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="page">
<div id="box-first">
<div id="first"></div>
<div id="n1">1500</div>
</div>
<div id="box-second">
<div id="second"></div>
<div id="n2">270</div>
</div>
</div>
With iphone, so with safari, under (at the bottom side) div #n1 (the black div where there's number 1500) is visible a small white border or sometimes red (like #first).
And this is impossible because the container has overflow: hidden, all divs have different z-Index and the absolute position of #n1 is correct.
How is possibile ?
Thanks and sorry for my english
This is the jsfiddle: This is jsfiddle: https://jsfiddle.net/k85t9zgq/33/
This is a bug's screenshot:
THIS IS NEW "BUG" adding box-sizing:border-box
it seems to me that adding this new property not work the overflow:hidden property.
Is possible?
I cannot test this, but I am pretty sure it's related to the fact that background use background-clip border-box by default and this is somehow a rendring issue. A potential fix is to make the background far from the border by adding a small padding and adjusting background-clip
$('#first').addClass('first-start');
//SECOND BAR
$('#second').addClass('second-start');
setTimeout(function() {
$('#second').addClass('second-pause');
}, 400);
#page {
margin-top: 50px;
width: 300px;
height: 300px;
background-color: #000;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
z-index: 4;
overflow: hidden;
}
#box-first,
#box-second {
width: 200px;
height: 100px;
/* Changes*/
background: linear-gradient(#fff,#fff) content-box;
padding:1px;
box-sizing:border-box;
/**/
border-radius: 200px 200px 0 0;
margin-top: 10px;
margin-bottom: 10px;
position: relative;
display: flex;
justify-content: flex-end;
align-items: flex-start;
z-index: 3;
overflow: hidden;
}
#first,
#second {
border-radius: 200px 200px 0 0;
margin: 0;
background: red;
width: 200px;
height: 100px;
transform: rotate(180deg);
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform-origin: 50% 100%;
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
position: absolute;
top: 0px;
right: 0px;
border: 0;
z-index: 1;
}
#n1,
#n2 {
font-size: 20px;
color: #fff;
font-weight: bold;
position: absolute;
left: 50px;
right: 0;
text-align: center;
top: 50px;
bottom: 0;
display: flex;
align-items: flex-end;
justify-content: center;
width: 100px;
height: 50px;
background: #000;
border-radius: 100px 100px 0 0;
z-Index: 1;
overflow: hidden;
}
#keyframes first {
0% {
background-color: green;
transform: rotate(180deg);
}
33% {
background-color: yellow;
transform: rotate(240deg);
}
66% {
background-color: orange;
transform: rotate(300deg);
}
100% {
background-color: red;
transform: rotate(360deg);
}
}
#keyframes second {
0% {
background-color: green;
transform: rotate(180deg);
}
33% {
background-color: yellow;
transform: rotate(240deg);
}
66% {
background-color: orange;
transform: rotate(300deg);
}
100% {
background-color: red;
transform: rotate(360deg);
}
}
.first-start,
.second-start {
animation: first 2s linear forwards;
}
.first-pause,
.second-pause {
animation-play-state: paused;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="page">
<div id="box-first">
<div id="first"></div>
<div id="n1">1500</div>
</div>
<div id="box-second">
<div id="second"></div>
<div id="n2">270</div>
</div>
</div>
I believe it's your border-radius property on #first and #second - Play around with the values on it and you will totally see what I mean.
Change this:
#first,
#second {
border-radius: 200px 200px 0 0; /* ← CHANGE THIS */
margin: 0;
background: red;
width: 200px; /* ← CHANGE THIS TOO */
height: 100px;
transform: rotate(180deg);
transform-origin: 50% 100%;
position: absolute;
top: 0px;
right: 0px;
border: 0;
z-index: 1;
}
to:
#first,
#second {
border-radius: 0; /* ← THIS IS WHAT YOU WANT */
margin: 0;
background: red;
width: 100%; /* ← THIS IS ALSO WHAT YOU WANT */
height: 100px;
transform: rotate(180deg);
transform-origin: 50% 100%;
position: absolute;
top: 0px;
right: 0px;
border: 0;
z-index: 1;
}
That faint white/gray line around your speedometer is no longer present.
Cheers and Happy coding :)

CSS: backface-visibility not working?

I'm trying to create a card flipping effect, but I can't get the backface-visibility: hidden; working. What am I doing wrong?
.content {
width: 100%;
height: 70vh;
margin-left: auto;
margin-right: auto;
position: relative;
top: 50px;
}
.card {
margin: 10px;
width: 300px;
height: 450px;
border: 1px solid black;
float: left;
position: relative;
left: 10%;
background-color: green;
transition: all 0.6s ease;
}
.card:hover {
transform: rotateY(180deg);
}
.front, .back {
width: 300px;
height: 450px;
position: absolute;
backface-visibility: hidden;
}
<div class="content">
<div class="card">
<div class="front">
<p>hello</p>
</div>
<div class="back">
<p>goodbye</p>
</div>
</div>
</div>
Instead of rotating the parent, you have to rotate the two sides individually.
.content {
width: 100%;
height: 70vh;
margin-left: auto;
margin-right: auto;
position: relative;
top: 50px;
}
.card {
margin: 10px;
width: 300px;
height: 450px;
float: left;
position: relative;
left: 10%;
}
.front,
.back {
width: 300px;
height: 450px;
position: absolute;
backface-visibility: hidden;
transition-duration: 600ms;
border: 1px solid black;
}
.front {
background-color: green;
transform: none;
}
.back {
background-color: red;
transform: rotateY(180deg);
}
.card:hover .front {
transform: rotateY(180deg);
}
.card:hover .back {
transform: none;
}
<div class="content">
<div class="card">
<div class="front">
<p>hello</p>
</div>
<div class="back">
<p>goodbye</p>
</div>
</div>
</div>
http://jsfiddle.net/tj3eacxL/
Your original CSS is at the top. The necessary changes are:
.card {
-webkit-transform-style: preserve-3d;
background: none; /* Apply a background colour to the whole card to cover up the faces */
}
.back {
transform: rotateY(180deg); /* because the back should be flipped initially when it's in the back */
}
.front, .back {
background-color: green;
}
Here is a good example how do flip cards...
CSS:
.content {
perspective: 1000;
}
.content:hover .card {
transform: rotateY(180deg);
}
.content, .front, .back {
width: 300px;
height: 450px;
}
.front, .back {
border: 1px solid black;
background: green;
}
.card {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
.front {
z-index: 2;
/* for firefox 31 */
transform: rotateY(0deg);
}
/* back, initially hidden pane */
.back {
transform: rotateY(180deg);
}
.content:hover .card {
transform: rotateY(180deg);
}

Issue in transform property in CSS

I am trying to rotate a div which is inside another div. whats wrong with my code.I come across with another method(:before child) but whats wrong with this methods? Thanks
body {
background: #ccc
}
.box {
width: 70%;
height: 200px;
background: #FFF;
margin: 40px auto;
}
.effect2 {
position: relative;
}
.box1 {
transform: rotate3d;
position: absolute;
width: 20%;
height: 20px;
background-color: aqua;
}
<div class="box effect2">
<div class="box1"></div>
</div>
body {
background: #ccc
}
.box {
width: 70%;
height: 200px;
background: #FFF;
margin: 40px auto;
}
.effect2 {
position: relative;
}
.box1{
transition: 1.5s;
position: absolute;
width: 20%;
height: 20px;
background-color: aqua;
}
.box1:hover{
transform: rotate3d(1,-1, 1,60deg);
}
<div class="box effect2">
<div class="box1"></div>
</div>
Give x,y or z to rotate and add the value
body {
background: #ccc
}
.box {
width: 70%;
height: 200px;
background: #FFF;
margin: 40px auto;
}
.effect2 {
position: relative;
}
.box1 {
transform: rotateZ(45deg);
position: absolute;
width: 20%;
height: 20px;
background-color: aqua;
}
<div class="box effect2">
<div class="box1"></div>
</div>
Here are some posible values
transform: rotate3d(1, 2.0, 3.0, 10deg)
transform: rotateX(10deg)
transform: rotateY(10deg)
transform: rotateZ(10deg)
SOURCE
rotate3d, where supported, needs parameters, example:
transform: rotate3d(1, 2.0, 3.0, 10deg)
body {
background: #ccc
}
.box {
width: 70%;
height: 200px;
background: #FFF;
margin: 40px auto;
}
.effect2 {
position: relative;
}
.box1 {
transform: rotate3d(1,2.0,3.0,90deg);
position: absolute;
width: 20%;
height: 20px;
background-color: aqua;
}
<div class="box effect2">
<div class="box1"></div>
</div>
You need to adapt to different browsers.
.class {
-webkit-transform:rotate(deg);
-moz-transform:rotate(deg);
-o-transform:rotate(deg);
transform:rotate(deg);
}