How to create cube with only HTML and CSS?

前端 未结 9 1966
星月不相逢
星月不相逢 2021-01-30 17:03

I have this and I want to make a cube with HTML & CSS only like in the above image. My best try:

相关标签:
9条回答
  • 2021-01-30 17:39
          y         
          |          
          |____ x 
         ╱        
        z 
    

    Imagine a cube from the front side. What you can see? A square that comes out over the screen. So, for the front side, we have:

    .front {
      transform : translateZ(50px);
    }
    

    for the right side, we have a square that is rotated 90 degrees on Y-Axis and moved on own new Z-Axis:

    .right {
      transform : rotateY(90deg) translateZ(50px);
    }
    

    for the left side, we have a square that is rotated -90 degrees on Y-Axis and moved on own new Z-Axis:

    .right {
      transform : rotateY(-90deg) translateZ(50px);
    }
    

    for the top side, we have a square that is rotated 90 degrees on X-Axis and moved on own new Z-Axis:

    .right {
      transform : rotateX(90deg) translateZ(50px);
    }
    

    for the back side, we have a square that is rotated -180 degrees on Y-Axis and moved on own new Z-Axis:

    .right {
      transform : rotateY(-180deg) translateZ(50px);
    }
    

    Then, Just package them in a shape container class with transform-style: preserve-3d property:

    .cube {
      transform-style: preserve-3d;
    }
    

    finally, you can rotate your cube and see the CSS-3D magic.

    .cube {
      transform-style: preserve-3d;
      transform: rotateX(-40deg) rotateY(45deg);
    }
    

    .cube {
      transform-style: preserve-3d;
      transform: rotateX(-40deg) rotateY(45deg);
    }
    
    .side {
      position: absolute;
      width: 100px;
      height: 100px;
      background: #c52329;
      border: solid 3px white;
    }
    
    .front {
      transform: translateZ(53px);
    }
    
    .top {
      transform: rotateX(90deg) translateZ(53px);
    }
    
    .right {
      transform: rotateY(90deg) translateZ(53px);
    }
    
    .left {
      transform: rotateY(-90deg) translateZ(53px);
    }
    
    .bottom {
      transform: rotateX(-90deg) translateZ(53px);
    }
    
    .back {
      transform: rotateY(-180deg) translateZ(53px);
    }
    <div class="cube">
      <div class="side front"></div>
      <div class="side back"></div>
      <div class="side right"></div>
      <div class="side left"></div>
      <div class="side top"></div>
      <div class="side bottom"></div>
    </div>
    It is a full cube. For your approach, you can ignore the back, right, and bottom sides.

    Thanks to css-tricks.com

    0 讨论(0)
  • 2021-01-30 17:46

    Basically, you want to do 2 transformations:

    1. rotate the rectangle
    2. squeeze it (skew it)

    so basically, you need to do a transform: rotate(x) skew(y, y) and play a bit with size and placing.

    here's a little demo I created, based on your own demo:

    (I did remove the borders since they felt unneeded to me)

    .mainDiv{
      position: relative;
      width: 206px;
      height: 190px;
      margin: 0px auto;
      margin-top:100px;
    }
    .square{
      width:100px;
      height:100px;
      background:#c52329;
      float:left;
      transform: skew(180deg,210deg);
      position: absolute;
      top: 43px;
    }
    .square2{
      width:100px;
      height:100px;
      background:#c52329;
      float:left;
      transform: skew(180deg,150deg);
      position: absolute;
      left:102px;
      top: 43px;
    }
    .square3{
      width:110px;
      height:110px;
      background:#c52329;
      float:left;
      transform: rotate(45deg) skew(-15deg, -15deg);
      position: absolute;
      left: 46px;
      top: -42px;
    }
    <div class="mainDiv">
      <div class="square"></div>
      <div class="square2"></div>
      <div class="square3"></div>
    </div>

    0 讨论(0)
  • 2021-01-30 17:49

    A single box and 2 pseudos can do this as well.

    http://codepen.io/gc-nomade/pen/vGeajp

    #square {
    
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 5px;
      background: #C52329;
      /*box-shadow: 0 0 5px;*/
      width: 90px;
      height: 150px;
      margin: 5em;
      position: relative;
      transform: skew(30deg) rotate(30deg);
    }
    
    #square:before,
    #square:after {
      display: inherit;
      align-items: center;
      justify-content: center;
      content: 'before';
      position: absolute;
      top: 0;
      left: 2px;
      right: -2px;
      bottom: 0;
      background: inherit;
      border-radius: inherit;
      box-shadow: inherit;
      transform: translate(100%, -31%) skew(0, -45deg) rotate(0deg);
    }
    #square:after {
      content: 'after';
      top: -2px;
      left: 0%;
      height: 60%;
      right: 0;
      bottom: 2px;
      transform: translate(50%, -100%) rotate(0deg)skew(-45deg)
    }
    <div id="square">
      boxe
    </div>

    0 讨论(0)
  • 2021-01-30 17:50

    I seen this and thought I would add something I came up with while trying to make some old fashioned abc blocks. Making them into 3d I only had to label the main container with another class to change positions and saved on the code. I commented the tutorial in the code. Hope this helps someone. :)

              
    /*-------------------------------------------------------------   
    First we need to create our container for later reference
        -I put this to show in the center of the screen if you wanted to 
        copy and paste the code into a document for play. 
        -The width is just to give the margin auto something to center on. 
        -You really on need the element itself to reference later, but this is prettier
    -------------------------------------------------------------*/
    .box{
        width: 100px;
        margin: 200px auto;
        text-align: center;
        line-height: 5;
    }
    
    /*---------------------------------------------------------------------------
    The box-wrapper is our real hero container here. This is where we nail our box together. 
        -set this to relative position for child elements to reference to.
        -transform-style is set to preserve-3d because I wanted to keep the look as the text turns with the box. You can also set this to flat, but its not near as cool. 
    ---------------------------------------------------------------------------*/
    
    
    .box-wrapper{
        position: relative;
        transform-style: preserve-3d;
        -webkit-transform-style: preserve-3d;    
    }
    /*-------------------------------------------------------------------------
    Here I am just giving the box its needed dimesions and setting them to absolute so nothing gets any ideas of wandering off.
        -PLEASE NOTE: the border has 2px and our w:98 h:98 making it a total of 100px. (this is important when we translate later)
    -------------------------------------------------------------------------*/
    .box-wrapper div{
        width: 98px;
        height: 98px;
        position: absolute;    
        border: 2px solid black;
        border-radius: 5px;
    }
    
    /*----------------------------------------------------------------------
    Since our sides are 100px we only need to move our box sides 50px to get the edges to match up without gaps.
        -Meaning "translate" moves to the position relative to your .box-wrapper. (You can play with this code to see it in action, try to take a visible section of the box and take it down 10). 
        -Also I use "rotate" y and x to turn our box sheets (.box-wrapper div's)
    -----------------------------------------------------------------------*/
    .front{
        transform: translateZ(50px) rotateY(0deg);
    }
    .back{
        transform: translateZ(-50px) rotateY(180deg);
    }
    .top{
        transform: translateY(-50px) rotateX(90deg);
    }
    .bottom{
        transform: translateY(50px) rotateX(-90deg);
    }
    
    .right{
        transform: translateX(50px) rotateY(90deg);
    }
    .left{
        transform: translateX(-50px) rotateY(270deg);
    }
    
    /*-----------------------------------------------------------------------
    Then after all of this we can use our cool box-wrapper to turn this baby
    Hope this is helpful! :) Enjoy!
    -------------------------------------------------------------------------*/
    
    .box .box-wrapper{
        transform: rotateX(-30deg) rotateY(-40deg);
    }
    .box .box-wrapper div{
        background-color: yellow;
    }
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>Bob the box builder</title>
            <link rel="stylesheet" type="text/css" href="boxstyle.css">
            <style>
                
    
            </style>
        </head>
        <body>
    <!--Create our box that holds our stuff -->
               <div class="box">
    <!--Create our real container that keeps our box sides nailed together-->
                        <div class="box-wrapper">
    <!--Make our box sheets that we will nail together with css-->
                            <div class="front">Front</div>
                            <div class="back">Back</div>
                            <div class="left">Left</div>
                            <div class="right">Right</div>
                            <div class="top">Top</div>
                            <div class="bottom">Bottom</div>
                        </div>
                    </div>
        </body>
    </html>

    0 讨论(0)
  • 2021-01-30 17:58

    First let me point out that a skew angle should be between -90deg and 90deg, non-inclusive. All of your skews fall way outside this range.

    Limiting myself to sensible skew numbers, it turned out to be quite simple:

    .mainDiv{
      position: relative;
      width: 206px;
      height: 190px;
      margin: 0px auto;
      margin-top:100px;
    }
    .tile {
      width:100px;
      height:100px;
      background:#c52329;
      border:solid 2px #FFF;
      position: absolute;
    }
    .square{
      transform: skewY(30deg);
      top: 43px;
    }
    .square2{
      transform: skewY(-30deg);
      left:102px;
      top: 43px;
    }
    .square3{
      height: 58px;
      left: 50px;
      top: -18px;
      transform: skew(60deg, -30deg);
    }
    <div class="mainDiv">
      <div class="tile square"></div>
      <div class="tile square2"></div>
      <div class="tile square3"></div>
    </div>

    Job done. I've also tidied up the huge repetition of styles into a common class for you.

    0 讨论(0)
  • 2021-01-30 18:00

    You can also achieve a cube with 3d transforms. This will give your cube a more realistic perspective. As if the cube was a real 3d shape like this:

    In the following I used one div with 2 pseudo elements :

    body {
      perspective: 900px;
      padding-bottom:50%;
    }
    div {
      position: relative;
      width: 20%;
      padding-bottom: 20%;
      margin: 0 auto;
      transform-style: preserve-3d;
      background: #C52329;
      transform: rotateX(60deg) rotatez(45deg);
    }
    div:before, div:after {
      content: '';
      position: absolute;
      width: 100%;
      height: 100%;
      transform-origin: -2% -2%;
      background: inherit;
    }
    div:before {
      top: 104%; left: 0;
      transform: rotateX(-90deg);
    }
    div:after {
      top: 0; left: 104%;
      transform: rotateY(90deg);
    }
    <div></div>

    CSS 3d cube with 6 faces:

    This technique allows you to make a "real cube" with 6 faces:

    body{
      perspective-origin:50% -100%;
      perspective: 900px;
      overflow:hidden;
    }
    h1{position:absolute;font-family:sans-serif;}
    .cube {
      position:relative;
      padding-bottom:20%;
      transform-style: preserve-3d;
      transform-origin: 50% 100%;
      transform:rotateY(45deg) rotateX(0);
      transition:transform 3s;
    }
    .cubeFace {
      position: absolute;
      left:40%;top:0;
      width: 20%;height:100%;
      margin: 0 auto;
      transform-style: inherit;
      background: #C52329;
      box-shadow:inset 0 0 0 5px #fff; 
      transform-origin:50% 50%;
      transform: rotateX(90deg);
      backface-visibility:hidden;
    }
    .face2{
      transform-origin:50% 50%;
      transform: rotatez(90deg) translateX(100%) rotateY(90deg);
    }
    .cubeFace:before, .cubeFace:after {
      content: '';
      position: absolute;
      width: 100%;
      height: 100%;
      transform-origin:0 0;
      background: inherit;
      box-shadow:inherit;
      backface-visibility:inherit;
    }
    .cubeFace:before {
      top: 100%; left: 0;
      transform: rotateX(-90deg);
    }
    .cubeFace:after {
      top: 0; left: 100%;
      transform: rotateY(90deg);
    }
    
    body:hover .cube{
      transform:rotateY(405deg) rotateX(360deg);
    }
    <h1>Hover me:</h1>
    <div class="cube">
      <div class="cubeFace"></div>
      <div class="cubeFace face2"></div>
    </div>

    Note that I didn't add the vendor prefixes in the examples. For more info about browser support and what vendor prefixes are needed according to your target audience, see canIuse for 3d transforms.

    0 讨论(0)
提交回复
热议问题