Monday, March 10, 2014

Drawing Shapes with CSS3 Box Shadow

When I first looked at the box shadow style, I did not really give much thought to the fact you could specify multiple shadows. At least not until I stumbled upon this pixel art creator which used that ability to build pixel art in a single tag. So, of course I drew something and started thinking what else I could do with this interesting property. It meant that I could add more complex shapes to my content where I might otherwise have to use a graphic. I started with a comment bubble:







Which scaled down works nicely as an icon:



And the CSS to create it is probably smaller than an image or font file:

<div style="
  height: 1px; width: 1px; 
  box-shadow: 2px 3px 0 #3498DB,3px 3px 0 #3498DB,
              4px 3px 0 #3498DB,5px 3px 0 #3498DB,
              6px 3px 0 #3498DB,7px 3px 0 #3498DB,
              8px 3px 0 #3498DB,9px 3px 0 #3498DB,
              10px 3px 0 #3498DB,11px 3px 0 #3498DB,
              1px 4px 0 #3498DB,2px 4px 0 #3498DB,
              3px 4px 0 #3498DB,4px 4px 0 #3498DB,
              5px 4px 0 #3498DB,6px 4px 0 #3498DB,
              7px 4px 0 #3498DB,8px 4px 0 #3498DB,
              9px 4px 0 #3498DB,10px 4px 0 #3498DB,
              11px 4px 0 #3498DB,12px 4px 0 #3498DB,
              1px 5px 0 #3498DB,2px 5px 0 #3498DB,
              3px 5px 0 #3498DB,4px 5px 0 #3498DB,
              11px 5px 0 #3498DB,12px 5px 0 #3498DB,
              1px 6px 0 #3498DB,2px 6px 0 #3498DB,
              3px 6px 0 #3498DB,4px 6px 0 #3498DB,
              5px 6px 0 #3498DB,6px 6px 0 #3498DB,
              7px 6px 0 #3498DB,8px 6px 0 #3498DB,
              9px 6px 0 #3498DB,10px 6px 0 #3498DB,
              11px 6px 0 #3498DB,12px 6px 0 #3498DB,
              1px 7px 0 #3498DB,2px 7px 0 #3498DB,
              9px 7px 0 #3498DB,10px 7px 0 #3498DB,
              11px 7px 0 #3498DB,12px 7px 0 #3498DB,
              1px 8px 0 #3498DB,2px 8px 0 #3498DB,
              3px 8px 0 #3498DB,4px 8px 0 #3498DB,
              5px 8px 0 #3498DB,6px 8px 0 #3498DB,
              7px 8px 0 #3498DB,8px 8px 0 #3498DB,
              9px 8px 0 #3498DB,10px 8px 0 #3498DB,
              11px 8px 0 #3498DB,12px 8px 0 #3498DB,
              1px 9px 0 #3498DB,2px 9px 0 #3498DB,
              3px 9px 0 #3498DB,12px 9px 0 #3498DB,
              2px 10px 0 #3498DB,3px 10px 0 #3498DB,
              4px 10px 0 #3498DB,5px 10px 0 #3498DB,
              6px 10px 0 #3498DB,7px 10px 0 #3498DB,
              8px 10px 0 #3498DB,9px 10px 0 #3498DB,
              10px 10px 0 #3498DB,11px 10px 0 #3498DB,
              3px 11px 0 #3498DB,4px 11px 0 #3498DB,
              3px 12px 0 #3498DB;"
></div>


And then it seemed only natural to make a spinner:




@keyframes spin {
    from { transform: translate3d(0, 0, 0) rotate(0deg); }
    to { transform: translate3d(0, 0, 0) rotate(360deg); }
}

.spinner {
    height: 1px; 
    width: 1px;
    transform-origin: 14px 14px;
    animation-name: spin; 
    animation-duration: 1s;
    animation-iteration-count: infinite; 
    animation-timing-function: linear;    
}

.spinner.balls {
    box-shadow: 
       13px 2px 0 #8F8588,14px 2px 0 #8F8588,12px 3px 0 #8F8588,
       13px 3px 0 #8F8588,14px 3px 0 #8F8588,15px 3px 0 #8F8588,
       12px 4px 0 #8F8588,13px 4px 0 #8F8588,14px 4px 0 #8F8588,
       15px 4px 0 #8F8588,6px 5px 0 #8F8588,7px 5px 0 #8F8588,
       13px 5px 0 #8F8588,14px 5px 0 #8F8588,20px 5px 0 #8F8588,
       21px 5px 0 #8F8588,5px 6px 0 #8F8588,6px 6px 0 #8F8588,
       7px 6px 0 #8F8588,8px 6px 0 #8F8588,19px 6px 0 #8F8588,
       20px 6px 0 #8F8588,21px 6px 0 #8F8588,22px 6px 0 #8F8588,
       5px 7px 0 #8F8588,6px 7px 0 #8F8588,7px 7px 0 #8F8588,
       8px 7px 0 #8F8588,19px 7px 0 #8F8588,20px 7px 0 #8F8588,
       21px 7px 0 #8F8588,22px 7px 0 #8F8588,6px 8px 0 #8F8588,
       7px 8px 0 #8F8588,20px 8px 0 #8F8588,21px 8px 0 #8F8588,
       3px 12px 0 #8F8588,4px 12px 0 #8F8588,23px 12px 0 #8F8588,
       24px 12px 0 #8F8588,2px 13px 0 #8F8588,3px 13px 0 #8F8588,
       4px 13px 0 #8F8588,5px 13px 0 #8F8588,22px 13px 0 #8F8588,
       23px 13px 0 #8F8588,24px 13px 0 #8F8588,25px 13px 0 #8F8588,
       2px 14px 0 #8F8588,3px 14px 0 #8F8588,4px 14px 0 #8F8588,
       5px 14px 0 #8F8588,22px 14px 0 #8F8588,23px 14px 0 #8F8588,
       24px 14px 0 #8F8588,25px 14px 0 #8F8588,3px 15px 0 #8F8588,
       4px 15px 0 #8F8588,23px 15px 0 #8F8588,24px 15px 0 #8F8588,
       6px 19px 0 #8F8588,7px 19px 0 #8F8588,20px 19px 0 #8F8588,
       21px 19px 0 #8F8588,5px 20px 0 #8F8588,6px 20px 0 #8F8588,
       7px 20px 0 #8F8588,8px 20px 0 #8F8588,19px 20px 0 #8F8588,
       20px 20px 0 #8F8588,21px 20px 0 #8F8588,22px 20px 0 #8F8588,
       5px 21px 0 #8F8588,6px 21px 0 #8F8588,7px 21px 0 #8F8588,
       8px 21px 0 #8F8588,19px 21px 0 #8F8588,20px 21px 0 #8F8588,
       21px 21px 0 #8F8588,22px 21px 0 #8F8588,6px 22px 0 #8F8588,
       7px 22px 0 #8F8588,13px 22px 0 #8F8588,14px 22px 0 #8F8588,
       20px 22px 0 #8F8588,21px 22px 0 #8F8588,12px 23px 0 #8F8588,
       13px 23px 0 #8F8588,14px 23px 0 #8F8588,15px 23px 0 #8F8588,
       12px 24px 0 #8F8588,13px 24px 0 #8F8588,14px 24px 0 #8F8588,
       15px 24px 0 #8F8588,13px 25px 0 #8F8588,14px 25px 0 #8F8588;
}


Its important to shift the transform origin to match the final size of your box shadow "grid". The DIV is only 1 pixel high and wide so the point of rotation is in the top, left corner of the box shadow area.

While probably something that should be used in moderation, its still a fun trick that can come in handy in certain situations.