startv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource
via CSS Lint

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource
via JS Hint

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Want a Run Button?

If active, the preview will update automatically when you change code.

HTML

            
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<div>
  <h1>3D Parallax Buttons</h1>

  <p>Observe the 3D effect as you scroll around. The larger the monitor you use, the bigger the effect you'll be able to see.</p>
  <p></p>

<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<p>Observe all the sides of the buttons here as you scroll down.</p>
<p>The effect is noticable but not distracting.</p>
<p>Looks great on iOS and Android devices as well.</p>
<p>The JavaScript won't be a performance hit.</p>
<p>However, having a hundred 3D transformed objects will most likely slow down mobile devices and weaker computers so use them wisely.</p>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
<button>!</button>
  <h2>This title doesn't need JS, just like the &lt;hr&gt;s down below!</h2>
<p>You can use this technique for both inline links and important call to action buttons.</p>
<p>Combining different types also seems to work well:</p>
<button>Fancy Button!</button><br>
<button class="social">
<svg width="17" height="15" xmlns="http://www.w3.org/2000/svg">
 <g>
  <title>Layer 1</title>
  <g id="g2989" transform="matrix(0.0124718 0 0 -0.0124718 27.9323 53.5044)" fill="#00aced">
   <path id="path2991" d="m-1372.63623,4272.02979c-125,-45 -204,-160.99951 -195,-287.99951l3,-49l-50,6c-182,23 -341,101 -476.00024,231.99951l-66,65l-17,-48c-36,-106.99951 -13,-219.99951 62,-295.99951c40,-42 31,-48 -38,-23c-24,8 -45,14 -47,11c-7,-7 17,-98 36,-134c26,-50 79,-99 137.00024,-128l49,-23l-58,-1c-56.00024,0 -58.00024,-1 -52.00024,-22c20,-65 99.00024,-134 187.00024,-164l62,-21l-54,-32c-80,-46 -174.00024,-72 -268.00024,-74c-45,-1 -82,-5 -82,-8c0,-10 122,-66 193.00012,-88c213.00012,-65 466.00012,-37 656.00012,74c135,79 270,236 333,388c34,81 67.99994,229 67.99994,300c0,46 3,52 59,107c33,32 64,66.99951 70,76.99951c10,19 9,19 -42,2c-85,-29.99951 -97,-25.99951 -55,19c31,32 68,90 68,107c0,3 -15,-2 -32,-11c-18,-10 -58,-25 -88,-34l-53.99994,-17l-49,33c-27,18 -65,38 -85,44c-51,14 -129,12 -175,-4z" fill="#000000"/>
  </g>
 </g>
</svg>
</button>
<button class="social">
<svg width="7" height="15" xmlns="http://www.w3.org/2000/svg">
 <title>Facebook Home</title>
 <g>
  <title>Layer 1</title>
  <path id="path3857-4" d="m4.92885,0c-2.49491,0 -3.37211,1.26051 -3.37211,3.37858l0,1.55835l-1.55673,0l0,2.59617l1.55673,0l0,7.5331l3.11185,0l0,-7.5331l2.07726,0l0.27481,-2.59617l-2.35207,0l0.00323,-1.2997c0,-0.67724 0.06482,-1.03944 1.0362,-1.03944l1.29809,0l0,-2.59779l-2.07726,0z" mask="none" fill="#000000"/>
 </g>
</svg>
</button>
<button class="social">
<svg width="15" height="15" xmlns="http://www.w3.org/2000/svg">
   <circle id="svg_4" fill="#000" r="2.05961" cy="12.95838" cx="2.05961"/>
   <path id="svg_5" fill="#000" d="m9.95478,15.01799l-2.91778,0a7.037,7.037 0 0 0 -7.037,-7.037l0,-2.91778a9.95478,9.95478 0 0 1 9.95478,9.95478z"/>
   <path id="svg_6" fill="#000" d="m12.01439,15.01799a12.01439,12.01439 0 0 0 -12.01439,-12.01439l0,-3.0036a15.01799,15.01799 0 0 1 15.01799,15.01799l-3.0036,0z"/>
</svg>
</button>
<hr />
</div>
            
          
!

CSS

            
              @import "compass/css3";

/* button variables */
$bsize: 18px;
$blue: #aad1ee;
$titlefoldsize: 50px;
$animtiming: 80ms steps(20) both;

html {
  height: 100%;
  overflow: hidden;
  background: #777;
}


/* the perspective set here is the most important declaration for the 3d look of the buttons (values over 1000px make the buttons look almost flat) */
body {
  margin: 0;
  height: 100%;
  overflow-y: scroll;
  font-family: sans-serif;
  font-size: 16px;
  perspective: 350px;
}

div {
  width: 600px;
  margin: 0 auto;
  padding: 20px 20px 600px;
  background: #fff;
  transform-style: preserve-3d;
}

h1, h2 {
  text-align: center;
}

h1, h2, hr {
  position: relative;
  background: #444;
  color: #fff;
  line-height: 2em;
  margin-left: -$titlefoldsize;
  margin-right: -$titlefoldsize;
  transform-style: preserve-3d;
  transform: translateZ(1px);
  
  &::before, &::after {
    content:"";
    position: absolute;
    top: 0;
    width: $titlefoldsize;
    height: 100%;
    background: darken(#444, 10%);
  }
    
  &::before {
    left: -$titlefoldsize;
    transform-origin: 100% 0%;
    transform: rotateY(-130deg);
  }
  &::after {
    right: -$titlefoldsize;
    transform-origin: 0% 0%;
    transform: rotateY(130deg);
  }
}

hr {
  border: 0;
  height: 10px;
  background: #444;
}

button {
  position: relative;
  display: inline-block;
  padding: 4px 16px;
  border: 0;
  min-width: 48px;
  margin: 10px;
  font-size: 24px;
  font-weight: bold;
  background-color: $blue;

  background-image: radial-gradient(ellipse at top, rgba(255,255,255,0.15) 50%, transparent);
  color: #222;
  transform-style: preserve-3d;
  transform: translateZ( $bsize );
  cursor: pointer;
  user-select: none;

  &:focus {outline: none;}
  /* double colon syntax for pseudo elements because IE8 doesn't need to see them (no transforms) */
  &::before, &::after {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    background: darken($blue, 25%);
    transform-origin: 0% 0%;
  }
  &::before {
    content:"";
    height: $bsize;
    background: darken($blue, 15%);
    transform: rotateX(-90deg);
  }
  &::after {
    content:"";
    width: $bsize;
    transform: rotateY(90deg);
  }

  &.top-half::before {
    top: auto;
    bottom: 0;
    background: darken($blue, 35%);
    transform-origin: 100% 100%;
    transform: rotateX(90deg);
  }

  &.left-half::after {
    left: auto;
    right: 0;
    transform-origin: 100% 100%;
    transform: rotateY(-90deg);
  }


/* pushing the button down; done with animations with steps because transitions are too buggy and jumpy */
  &:active {  
    animation: button $animtiming;
    &::before {
      animation: buttonbefore $animtiming;
    }
    &::after {
      animation: buttonafter $animtiming;
    }
  }
}

@keyframes button {
    to { transform: translateZ( $bsize/2 ) }
}
@keyframes buttonbefore {
    to { height: $bsize/2; }
}
@keyframes buttonafter {
    to { width: $bsize/2; }
}


/* hide pseudo elements in IE9 and IE10 (no 3D transforms) */
@media screen and (min-width:0\0) {  
  button::before, button::after {
    display: none;
  }
}

/* hide pseudo elements in non-webkit Opera) */
x:-o-prefocus, button::before, button::after {
  display: none;
}
            
          
!

JS

            
              // changing the sides of the button only on load and on browser resize
$(window).on("load resize", function() {
	topHalf();
	leftHalf();
});

// when scrolling vertically only top and bottom sides need to be recalculated
$("body").scroll(function() {
	topHalf();
});

// toggle button class if it's in the top or bottom half of the screen
function topHalf() {
	$("button").each(function() {
		var self = $(this),
        offTop = self.offset().top,
        scrTop = $(window).scrollTop(),
        halfWindowHeight = ($(window).height())/2;

		self.toggleClass("top-half", (offTop - scrTop) < halfWindowHeight);
	});
}

// toggle button class if it's in left or right half of the screen
function leftHalf() {
	$("button").each(function() {
		var self = $(this),
        offLeft = self.offset().left,
        halfWindowWidth = ($(window).width())/2;

		self.toggleClass("left-half", offLeft < halfWindowWidth);
	});
}
            
          
!
999px
Loading ..................

Console