create cylinder shape in pure css 3d

18,322

Solution 1

There might be a couple of different aproaches on your problem.
The first (and simplest) one would be to have multiple stacked circles that would give you the impression of a cylinder.
But who wants hundreds of divs in a page just to render a simple graphic module? You can use multiple box-shadow values on a single element to simulate multiple circles that eventually simulates the cylinder:

div {
    box-shadow: black 0px 0px 1px,
        black 1px 1px 1px,
        black 2px 2px 1px,
        ...
        black 99px 99px 1px,
        black 100px 100px 1px;
}

Here's a fiddle with this example: http://jsfiddle.net/gion_13/nDCme/.

Solution 2

there are some advanced examples like these:
http://x.dtott.com/3d/
http://cssdeck.com/labs/pure-css-3d-primitives

and some useful CSS shapes like these:
http://css-tricks.com/examples/ShapesOfCSS/

personally I built this simple one HTML

.tank{
    position:relative;
     margin:50px;
}

.tank .middle{
    width:120px;
    height:180px;
    background-color:#444;
    position:absolute;
}

.tank .top{
    width: 120px;
    height: 50px;
    background-color:#666;
    -moz-border-radius: 60px / 25px;
    -webkit-border-radius: 60px / 25px;
    border-radius: 60px / 25px;
    position:absolute;
    top:-25px;
}

.tank .bottom{
    width: 120px;
    height: 50px;
    background-color:#444;
    -moz-border-radius: 60px / 25px;
    -webkit-border-radius: 60px / 25px;
    border-radius: 60px / 25px;
    position:absolute;
    top:155px;
    box-shadow:0px 0px 10px rgba(0,0,0,0.75)
}
<div class="tank">
    <div class="bottom"></div>
    <div class="middle"></div>
    <div class="top"></div>  
</div>

and you can see a DEMO

Solution 3

Answer that provides ACTUAL example in 3D:

Final result looks like so:

Green 3D Cylinder

JSfiddle demo: https://jsfiddle.net/allenski/xyfhag8d/ (added animation for fun).

HTML markup:

<div id="container">
  <div id="frame">
    <div class="strips">
      <div class="strip-1"></div>
      <div class="strip-2"></div>
      <div class="strip-3"></div>
      <div class="strip-4"></div>
      <div class="strip-5"></div>
      <div class="strip-6"></div>
      <div class="strip-7"></div>
      <div class="strip-8"></div>
      <div class="strip-9"></div>
      <div class="strip-10"></div>
      <div class="strip-11"></div>
      <div class="strip-12"></div>
      <div class="strip-13"></div>
      <div class="strip-14"></div>
      <div class="strip-15"></div>
      <div class="strip-16"></div>
      <div class="strip-17"></div>
      <div class="strip-18"></div>
      <div class="strip-19"></div>
      <div class="strip-20"></div>
      <div class="strip-21"></div>
      <div class="strip-22"></div>
      <div class="strip-23"></div>
      <div class="strip-24"></div>
    </div>
  </div>
</div>

CSS markup:

#container {
  width: 100%;
  height: 100%;
  perspective: 900px;
}
#frame {
  position: relative;
  top: 50%;
  left: 50%;
  width: 23px;
  transform-style: preserve-3d;
  transform: rotateX(-20deg) rotateY(0deg) rotateZ(0deg);
}
.strips {
  transform-style: preserve-3d;
  transition: all 420ms;
}
.strips > div {
  position: absolute;
  top: -60px;
  left: -12px;
  margin-top: -10px;
  background: limegreen;
  border: solid darkgreen;
  border-width: 5px 0;
  height: 120px;
  width: 24px;
}
.strip-1 { transform: rotateY(0deg) translateZ(85px); }
.strip-2 { transform: rotateY(15deg) translateZ(85px); }
.strip-3 { transform: rotateY(30deg) translateZ(85px); }
.strip-4 { transform: rotateY(45deg) translateZ(85px); }
.strip-5 { transform: rotateY(60deg) translateZ(85px); }
.strip-6 { transform: rotateY(75deg) translateZ(85px); }
.strip-7 { transform: rotateY(90deg) translateZ(85px); }
.strip-8 { transform: rotateY(105deg) translateZ(85px); }
.strip-9 { transform: rotateY(120deg) translateZ(85px); }
.strip-10 { transform: rotateY(135deg) translateZ(85px); }
.strip-11 { transform: rotateY(150deg) translateZ(85px); }
.strip-12 { transform: rotateY(165deg) translateZ(85px); }
.strip-13 { transform: rotateY(180deg) translateZ(85px); }
.strip-14 { transform: rotateY(195deg) translateZ(85px); }
.strip-15 { transform: rotateY(210deg) translateZ(85px); }
.strip-16 { transform: rotateY(225deg) translateZ(85px); }
.strip-17 { transform: rotateY(240deg) translateZ(85px); }
.strip-18 { transform: rotateY(255deg) translateZ(85px); }
.strip-19 { transform: rotateY(270deg) translateZ(85px); }
.strip-20 { transform: rotateY(285deg) translateZ(85px); }
.strip-21 { transform: rotateY(300deg) translateZ(85px); }
.strip-22 { transform: rotateY(315deg) translateZ(85px); }
.strip-23 { transform: rotateY(330deg) translateZ(85px); }
.strip-24 { transform: rotateY(345deg) translateZ(85px); }
Share:
18,322

Related videos on Youtube

user3820621
Author by

user3820621

Updated on June 05, 2022

Comments

  • user3820621
    user3820621 almost 2 years

    I was working on canvas 3D shapes I am very new to this. I am trying to create Pure css3d cylinder without any plugin.

    Here is what I am trying and with the output code, I am getting a circle.

    CSS Code:

    div {
        height:200px;
        width:200px;
        border:solid 5px black;
        background:#159;
        border-radius:100%;
        display:inline-block;
        margin:1em;
        position:relative;
        text-align:center;
        line-height:200px;
        color:white;
        font-size:2em;
        transform:rotate(45deg);
        box-shadow:0 0 5px black, inset 0 0 5px #48a;
    }
    

    HTML code

    <div>&nbsp;</div>
    

    Can some one help me.

    • gion_13
      gion_13 almost 10 years
      Post your code. Post what have you tried. SO is not the place to get full solutions out of the box.
    • user3820621
      user3820621 almost 10 years
      Hi @gion_13 i added the code i am trying the output was only circle but i want in cylinder shape
  • user3820621
    user3820621 almost 10 years
    hi @gion_13 thanks for sharing the code is that possible can you make it as string and reduce opacity of the cylinder. When i change the transform value it was not happening kindly help me
  • user3820621
    user3820621 almost 10 years
    It was really awesome code i was searching for this type of solution now I want only two calarification 1) making straight and 2) giving opacity to the cylinder
  • user3820621
    user3820621 almost 10 years
    hi @gion_13 kindly help to my above query please do the needful
  • gion_13
    gion_13 almost 10 years
    the direction of the cylinder is given by the first 2 coordinates of the box-shadow value. They actually form a vector that gives you an angle. For example, if you want it straight down, then you should change the box-shadow vector to something like: black 0 1px 1px, black 0 2px 1px, black 0 3px 1px... and so on.
  • gion_13
    gion_13 almost 10 years
    @user3820621 regarding the opacity.. it may be a bit unclear what you're asking for. You can either set the css opacity property of the div or you could mess with the actual colors by using rgba() values instead of rgb/hex/color names.
  • user3820621
    user3820621 almost 10 years
    hi @gion_13 I have tried giving the value for the box-shadow with your values but still it was not working for straight and down kindly help me here
  • gion_13
    gion_13 almost 10 years
    @user3820621 here's the updated fiddle. It now is a bit transparent and vertical
  • Harry
    Harry about 9 years
    Nice answer. Can be done with a single HTML element also by using pseudos.
  • xxstevenxo
    xxstevenxo over 8 years
    @harry what do you mean? Which pseudos would you use since there's a top middle and bottom in his example?
  • Harry
    Harry over 8 years
    @xxstevenxo You can use the main element for the middle part and the two pseudos for top and bottom like in this fiddle.
  • xxstevenxo
    xxstevenxo over 8 years
    oh duh.. dunno how i missed that
  • undefined
    undefined over 5 years
    That's actually 2D. Rotating the .tank is exposing that.