title: How can I create pure CSS 3-dimensional spheres?
body: <p><strong>tl;dr:</strong> <em>I would like to create an actual 3d sphere with CSS - not just an illusion</em></p>
  <p>Note: some of the snippet examples are not responsive. Please use full screen.</p>
  <hr />
  <p>With pure CSS you can <strong>create and animate</strong>  a 3d cube like so:</p>
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>#cube-wrapper {
    position: absolute;
    left: 50%;
    top: 50%;
    perspective: 1500px;
  }
  
  .cube {
    position: relative;
    transform-style: preserve-3d;
    animation-name: rotate;
    animation-duration: 30s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }
  
  @keyframes rotate {
    0% {
      transform: rotate3d(0, 0, 0, 0);
    }
    100% {
      transform: rotate3d(0, 1, 0, 360deg);
      ;
    }
  }
  
  .face {
    position: absolute;
    width: 200px;
    height: 200px;
    border: solid green 3px;
  }
  
  #front_face {
    transform: translateX(-100px) translateY(-100px) translateZ(100px);
    background: rgba(255, 0, 0, 0.5);
  }
  
  #back_face {
    transform: translateX(-100px) translateY(-100px) translateZ(-100px);
    background: rgba(255, 0, 255, 0.5);
  }
  
  #right_face {
    transform: translateY(-100px) rotateY(90deg);
    background: rgba(255, 255, 0, 0.5);
  }
  
  #left_face {
    transform: translateY(-100px) translateX(-200px) rotateY(90deg);
    background: rgba(0, 255, 0, 0.5);
  }
  
  #top_face {
    transform: translateX(-100px) translateY(-200px) rotateX(90deg);
    background: rgba(0, 255, 255, 0.5);
  }
  
  #bottom_face {
    transform: translateX(-100px) rotateX(90deg);
    background: rgba(255, 255, 255, 0.5);
  }
  
  .cube {
    transform: rotateX(90deg) rotateY(90deg);
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id="cube-wrapper"&gt;
    &lt;div class="cube"&gt;
      &lt;div id="front_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="right_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="back_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="left_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="top_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="bottom_face" class="face"&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p><strong>I want to create and animate a 3d sphere in the same manner.</strong></p>
  <p>So... the first idea I get is to use <code>border-radius</code> and...well... it doesn't work.</p>
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>#cube-wrapper {
    position: absolute;
    left: 50%;
    top: 50%;
    perspective: 1500px;
  }
  
  .cube {
    position: relative;
    transform-style: preserve-3d;
    animation-name: rotate;
    animation-duration: 30s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }
  
  @keyframes rotate {
    0% {
      transform: rotate3d(0, 0, 0, 0);
    }
    100% {
      transform: rotate3d(0, 1, 0, 360deg);
     
      ;
    }
  }
  
  
  .face {
    position: absolute;
    width: 200px;
    height: 200px;
    border: solid green 3px;
    border-radius: 100vw
  }
  
  
   
  
  #front_face {
    transform: translateX(-100px) translateY(-100px) translateZ(100px);
    background: rgba(255, 0, 0, 0.5);
  }
  
  #back_face {
    transform: translateX(-100px) translateY(-100px) translateZ(-100px);
    background: rgba(255, 0, 255, 0.5);
  }
  
  #right_face {
    transform: translateY(-100px) rotateY(90deg);
    background: rgba(255, 255, 0, 0.5);
  }
  
  #left_face {
    transform: translateY(-100px) translateX(-200px) rotateY(90deg);
    background: rgba(0, 255, 0, 0.5);
  }
  
  #top_face {
    transform: translateX(-100px) translateY(-200px) rotateX(90deg);
    background: rgba(0, 255, 255, 0.5);
  }
  
  #bottom_face {
    transform: translateX(-100px) rotateX(90deg);
    background: rgba(255, 255, 255, 0.5);
  }
  
  .cube {
    transform: rotateX(90deg) rotateY(90deg);
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id="cube-wrapper"&gt;
    &lt;div class="cube"&gt;
      &lt;div id="front_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="right_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="back_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="left_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="top_face" class="face"&gt;&lt;/div&gt;
      &lt;div id="bottom_face" class="face"&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>So, I reconsidered my approach and looked for a different method.</p>
  <p>I looked at:</p>
  <ul>
  <li><a href="https://stackoverflow.com/questions/29300573/implementing-pure-css-sphere-into-website-how-do-i-do-it">Implementing &quot;Pure CSS Sphere&quot; into website - how do I do it?</a></li>
  <li><a href="https://stackoverflow.com/questions/30891893/how-to-create-a-sphere-in-css">How to create a sphere in css?</a></li>
  <li><a href="https://stackoverflow.com/a/24561907/8157693">Display an image wrapped around a sphere with CSS/Javascript
  </a></li>
  <li><a href="https://cssanimation.rocks/spheres/" rel="nofollow noreferrer">cssanimation.rocks - CSS spheres</a></li>
  <li><a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle" rel="nofollow noreferrer">MDN -
  Circle</a></li>
  </ul>
  <p>Then I tried again...the best I got were overly <em>complicated</em> 3d object <strong>illusions</strong>.</p>
  <p>Like this:</p>
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body {
    overflow: hidden;
    background: #333;
  }
  
  .wrapper {
    margin: 1em;
    animation-duration: 20s;
  }
  
  .planet,
  .planet:before,
  .planet:after {
    height: 300px;
    width: 300px;
    border-radius: 100vw;
    will-change: transform;
    margin: 0 auto;
  }
  
  .planet {
    box-shadow: inset 0px 0px 10px 10px rgba(0, 0, 0, 0.4);
    position: relative;
  }
  
  .wrapper,
  .planet,
  .planet:before {
    animation-name: myrotate;
    animation-duration: 20s;
  }
  
  .wrapper,
  .planet,
  .planet:before,
  .planet:after {
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }
  
  .planet:before,
  .planet:after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
  }
  
  .planet:before {
    box-shadow: inset 20px 20px 100px 00px rgba(0, 0, 0, .5), 0px 0px 5px 3px rgba(0, 0, 0, .1);
  }
  
  .planet:after {
    filter: saturate(2.5);
    background: linear-gradient(rgba(0, 0, 0, 1), transparent), url("https://i.stack.imgur.com/eDYPN.jpg");
    opacity: 0.3;
    box-shadow: inset -20px -20px 14px 2px rgba(0, 0, 0, .2);
    animation-name: myopacity;
    animation-duration: 5000000s;
  }
  
  @keyframes myrotate {
    0% {
      transform: rotatez(0deg);
    }
    100% {
      transform: rotatez(360deg);
    }
  }
  
  @keyframes myopacity {
    0% {
      background-position: 0px;
      transform: rotatez(0deg);
    }
    50% {
      background-position: 100000000px;
    }
    100% {
      background-position: 0;
      transform: rotatez(-360deg);
    }
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="wrapper"&gt;
    &lt;div class="planet"&gt;&lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>And this:</p>
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>body {
    background: #131418;
  }
  
  .wrapper {
    margin: 1em;
    max-width: 100%;
    position: fixed;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }
  
  .planet,
  .planet:before,
  .planet:after {
    height: 500px;
    width: 500px;
    max-height: 30vw;
    max-width: 30vw;
    border-radius: 100vw;
    will-change: transform;
  }
  
  .planet {
    box-shadow: inset 0px 0px 100px 10px rgba(0, 0, 0, .5);
    position: relative;
    float: left;
    margin: 0 2em;
  }
  
  .planet,
  .planet:before,
  .planet:after {
    animation-name: myrotate;
    animation-duration: 10s;
  }
  
  .wrapper,
  .planet,
  .planet:before,
  .planet:after {
    animation-timing-function: linear;
    animation-iteration-count: infinite;
  }
  
  .planet:before,
  .planet:after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
  }
  
  .planet:before {
    box-shadow: inset 50px 100px 50px 0 rgba(0, 0, 0, .5), 0 0 50px 3px rgba(0, 0, 0, .25);
    background-image: -webkit-radial-gradient( top, circle cover, #ffffff 0%, #000000 80%);
    opacity: .5;
  }
  
  .planet:after {
    opacity: .3;
    background-image: -webkit-radial-gradient( bottom, circle, #ffffff 0%, #000000 -200%);
    box-shadow: inset 0px 0px 100px 50px rgba(0, 0, 0, .5);
  }
  
  @keyframes myrotate {
    0% {
      transform: rotatez(0deg);
    }
    100% {
      transform: rotatez(-360deg);
    }
  }
  
  .bg {
    background: wheat;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="wrapper"&gt;
    &lt;div class="planet bg"&gt;&lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>Which are okay until you try to actually rotate them on either the <strong>x-axis</strong> or the <strong>y-axis</strong> like the cube in my first example...here's what happens then: (simplified example)</p>
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.sphere {
    background: black;
    width: 300px;
    height: 300px;
    border-radius: 100vw;
    animation: myrotate 10s linear infinite
  }
  
  @keyframes myrotate {
    0% {
      transform: rotate3d(0, 0, 0, 0);
    }
    100% {
      transform: rotate3d(0, 1, 0, 360deg);
    }
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="sphere"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>All you get is a flat 2d object - which is expeceted considering that it's what the element is</p>
  <hr />
  <p>The closest thing I found is the following shape created in a <a href="http://timokorinth.de/css-3d-sphere/" rel="nofollow noreferrer">tutorial by Timo Korinth</a></p>
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>@-webkit-keyframes animateWorld {
    0% {
      -webkit-transform: rotateY(0deg) rotateX(0deg) rotateZ(0deg);
    }
    50% {
      -webkit-transform: rotateY(360deg) rotateX(180deg) rotateZ(180deg);
    }
    100% {
      -webkit-transform: rotateY(720deg) rotateX(360deg) rotateZ(360deg);
    }
  }
  
  html {
    background: #FFFFFF;
  }
  
  . world {
    -webkit-perspective: 1000px;
  }
  
  .cube {
    margin-left: auto;
    margin-right: auto;
    position: relative;
    width: 200px;
    height: 200px;
    -webkit-transform-style: preserve-3d;
    -webkit-animation-name: animateWorld;
    -webkit-animation-duration: 10s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-timing-function: linear;
  }
  
  .circle {
    position: absolute;
    width: 100%;
    height: 100%;
    border: 2px dashed #009BC2;
    border-radius: 50%;
    opacity: 0.8;
    background: rgba(255, 255, 255, 0);
  }
  
  .zero {
    -webkit-transform: rotateX(90deg);
  }
  
  .two {
    -webkit-transform: rotateY(45deg);
  }
  
  .three {
    -webkit-transform: rotateY(90deg);
  }
  
  .four {
    -webkit-transform: rotateY(135deg);
  }
  
  .five {
    width: 173px;
    height: 173px;
    margin: 14px;
    -webkit-transform: rotateX(90deg) translateZ(50px);
  }
  
  .six {
    width: 173px;
    height: 173px;
    margin: 14px;
    -webkit-transform: rotateX(90deg) translateZ(-50px);
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div class="world"&gt;
    &lt;div class="cube"&gt;
      &lt;div class="circle zero"&gt;&lt;/div&gt;
      &lt;div class="circle one"&gt;&lt;/div&gt;
      &lt;div class="circle two"&gt;&lt;/div&gt;
      &lt;div class="circle three"&gt;&lt;/div&gt;
      &lt;div class="circle four"&gt;&lt;/div&gt;
      &lt;div class="circle five"&gt;&lt;/div&gt;
      &lt;div class="circle six"&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  <hr />
  <p>So here's my</p>
  <h2>Question:</h2>
  <p><strong>How do I create an actual 3 dimensional sphere with pure CSS? More specifically, one that is covered - not just a frame - and doesn't involve hundreds of html elements.</strong></p>
  <hr />
  <p><strong>Notes:</strong></p>
  <ol>
  <li>Three dimensional spheres have <strong>height, width and depth</strong> -  just
  like the cube in my first example snippet</li>
  <li>I don't need any physics and there's no need for any
  user-interaction. Just an animated spinning sphere.</li>
  </ol>
  <hr />
  <p><strong>Additional resources:</strong></p>
  <ol>
  <li><a href="https://paulrhayes.com/creating-a-sphere-with-3d-css/" rel="nofollow noreferrer">Paul Hayes - A sphere built with CSS 3D transforms</a> (<a href="https://fofr.github.io/paulrhayes.com-experiments/sphere/" rel="nofollow noreferrer">demo</a>)</li>
  <li><a href="http://w3bits.com/css-earth/" rel="nofollow noreferrer"><s>3d</s> (2d illusion) Earth with Rotating Animation with CSS</a></li>
  <li><a href="http://robosparrow.github.io/Css3dSphere/" rel="nofollow noreferrer">Interactive CSS sphere</a></li>
  </ol>