Skip to content

Instantly share code, notes, and snippets.

@jq-87
Created October 5, 2014 21:29
Show Gist options
  • Save jq-87/68fa12099d2a92c7c25c to your computer and use it in GitHub Desktop.
Save jq-87/68fa12099d2a92c7c25c to your computer and use it in GitHub Desktop.
3d box with sass map
//colors
$turquoise: #1abc9c;
$amethyst: #9b59b6;
$silver: #bdc3c7;
$emerland: #2ecc71;
$white: white;
$black: black;
//dimensions
$size: 100px;
//maps
$panes: (
pane1: (
transform: translateZ($size/2)
),
pane2: (
transform: rotateY(-90deg) translateZ($size/2)
),
pane3: (
transform: rotateX(90deg) translateZ($size/2)
),
pane4: (
transform: rotateX(90deg) rotateY(180deg) translateZ($size/2)
),
pane5: (
transform: rotateY(90deg) translateZ($size/2)
),
pane6: (
transform: rotateY(180deg) translateZ($size/2)
)
);
//extends
%layer {
width: $size;
height: $size;
}
%center-stage {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
%button {
background: $amethyst;
color: $white;
width: auto;
height: auto;
padding: 0.5em;
border-radius: 20px;
}
%no-point-events {
pointer-events: none;
}
%transition {
transition: all 1s;
}
@mixin keyframes($name) {
@-webkit-keyframes #{$name} {
@content;
}
}
//open animation
@include keyframes(pane1-open) {
to {
transform: translateZ($size);
opacity: 0;
}
}
@include keyframes(pane2-open) {
to {
transform: rotateY(-90deg) translateZ($size);
opacity: 0;
}
}
@include keyframes(pane3-open) {
to {
transform: rotateX(90deg) translateZ($size);
opacity: 0;
}
}
@include keyframes(pane4-open) {
to {
transform: rotateX(90deg) rotateY(180deg) translateZ($size);
opacity: 0;
}
}
@include keyframes(pane5-open) {
to {
transform: rotateY(90deg) translateZ($size);
opacity: 0;
}
}
@include keyframes(pane6-open) {
to {
transform: rotateY(180deg) translateZ($size);
opacity: 0;
}
}
//close animation
@include keyframes(pane1-close) {
from {
transform: translateZ($size);
opacity: 0;
}
to {
transform: translateZ($size / 2);
opacity: 1;
}
}
@include keyframes(pane2-close) {
from {
transform: rotateY(-90deg) translateZ($size);
opacity: 0;
}
to {
transform: rotateY(-90deg) translateZ($size / 2);
opacity: 1;
}
}
@include keyframes(pane3-close) {
from {
transform: rotateX(90deg) translateZ($size);
opacity: 0;
}
to {
transform: rotateX(90deg) translateZ($size / 2);
opacity: 1;
}
}
@include keyframes(pane4-close) {
from {
transform: rotateX(90deg) rotateY(180deg) translateZ($size);
opacity: 0;
}
to {
transform: rotateX(90deg) rotateY(180deg) translateZ($size / 2);
opacity: 1;
}
}
@include keyframes(pane5-close) {
from {
transform: rotateY(90deg) translateZ($size);
opacity: 0;
}
to {
transform: rotateY(90deg) translateZ($size / 2);
opacity: 1;
}
}
@include keyframes(pane6-close) {
from {
transform: rotateY(180deg) translateZ($size);
opacity: 0;
}
to {
transform: rotateY(180deg) translateZ($size / 2);
opacity: 1;
}
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
position: relative;
font-family: sans-serif;
font-size: 16px;
}
html, body {
height: 100%;
overflow: hidden;
}
body {
background: $silver;
}
fieldset,
button {
border: none;
}
button {
@extend %transition;
}
.box {
@extend %center-stage;
@extend %no-point-events;
@extend %transition;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
transform-origin: 0 0;
transform: rotateX(45deg) rotateY(45deg) translateX(-$size / 2) translateY(-$size / 2);
&,
* {
@extend %layer;
position: absolute;
}
div {
$i: 1;
@each $pane, $paneProps in $panes {
$paneTransform: map-get(map-get($panes, $pane), transform);
&:nth-of-type( #{$i} ) {
background: rgba(
mix(
$turquoise,
mix( $turquoise, $black, 30% ),
100/$i ), 1 );
border: 1px solid rgba( mix( $turquoise, $white, 80% ), 0.7 );
@if $paneTransform {
transform: $paneTransform;
}
}
$i: $i + 1;
}
}
.close {
@extend %center-stage;
@extend %button;
}
}
.open {
@extend %no-point-events;
@extend %center-stage;
@extend %button;
}
<link rel="stylesheet" href="css/main.css" media="screen" />
<fieldset class="container">
<input type="radio" class="trigger-close" name="trigger" checked />
<input type="radio" class="trigger-open" name="trigger"/>
<div class="box">
<div></div>
<div></div>
<div></div>
<button class="close">Close</button>
<div></div>
<div></div>
<div></div>
</div>
<button class="open">Open</button>
</fieldset>
@import "box-settings";
@import "box";
.container {
@extend %layer;
@extend %center-stage;
&:hover {
button {
background: $emerland;
}
}
}
[type="radio"] {
@extend %layer;
-webkit-appearance: none;
outline: none;
cursor: pointer;
&:checked {
display: none;
}
}
.trigger-close {
&:checked {
~ .box .close { opacity: 0; }
~ .box div {
@for $i from 1 to 7 {
&:nth-of-type(#{$i}) {
-webkit-animation: pane#{$i}-close 1s forwards;
}
}
}
}
}
.trigger-open {
&:checked {
~ .open { opacity: 0; }
~ .open {
transform: translateX(-50%) translateY(-50%) scale(5);
opacity: 0;
}
~ .box {
transform: rotateX(0deg) rotateY(0deg) translateX(-$size/2) translateY(-$size/2);
div {
@for $i from 1 to 7 {
&:nth-of-type(#{$i}) {
-webkit-animation: pane#{$i}-open 1s forwards;
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment