<h2>Squash and Stretch</h2>
<div class="flex__grid">
<!-- Gives physical appearance during interaction -->
<button class="btn btn--squash-stretch">Continue</button>
</div>
<h2>Anticipation</h2>
<div class="flex__grid">
<!-- Draws attention to user to prepare them for a bigger action -->
<button class="btn btn--anticipation">Subscribe</button>
</div>
<h2>Staging</h2>
<div class="flex__grid">
<!-- Projecting the intentions of the element to a user -->
<button class="btn btn--staging">Loading</button>
</div>
<h2>Pose 2 Pose/Straight Ahead</h2>
<div class="flex__grid">
<!-- Showing the user a change in form for leading across the interface or new feature that's accessible -->
<button class="btn btn--pose-2-pose">Loading</button>
</div>
<h2>Follow through/Overlap</h2>
<div class="flex__grid">
<!-- Staggering motion of the main element as other pieces react to the motion change -->
<button class="btn btn--follow-through">Submit</button>
</div>
<h2>Slow in & Slow out</h2>
<div class="flex__grid">
<!-- Defining a natural motion by slowing the animation and speeding it up during an element/feature introduction -->
<button class="btn btn--slow-in-out">Continue</button>
</div>
<h2>Arcs</h2>
<div class="flex__grid">
<!-- Gives variety and natural motion to elements -->
<button class="btn btn--arcs">Begin</button>
</div>
<h2>Secondary Action</h2>
<div class="flex__grid">
<!-- Other elements react to primary actions to give more personality to main animation -->
<button class="btn btn--secondary-action">Wait!</button>
<button class="btn btn--secondary-action--sibling">Wait!</button>
<button class="btn">Wait!</button>
</div>
<h2>Timing</h2>
<div class="flex__grid">
<!-- Set up proper fast or slow animations with extending the time or shortening it, does a user need to see it for 5 seconds or a quarter second -->
<button class="btn btn--fast">Fast</button>
<button class="btn btn--slow">Slow</button>
</div>
<h2>Exaggeration</h2>
<div class="flex__grid">
<!-- If this element's motion is mimiced to real life, give it excessive values to close out it's animation to call attention and bring user's focus to the action -->
<button class="btn btn--exaggeration">Continue</button>
</div>
<h2>Solid Drawings</h2>
<div class="flex__grid">
<!-- Element is presented in a consistent 3D nature to give weight and space -->
<button class="btn btn--solid">Continue</button>
</div>
<h2>Appeal</h2>
<div class="flex__grid">
<!-- Motion has personality and light hearted motion to connect with the user -->
<button class="btn btn--appeal">Continue</button>
</div>
<h4><a href="https://vimeo.com/93206523" target="_blank">The Illusion of Life</a></h4>
body {
}
h1,
h2,
h3,
h4 {
text-align: center;
}
.flex__grid {
display: flex;
justify-content: center;
transform-style: preserve-3d;
transform-origin: center;
perspective: 300px;
}
.btn {
position: relative;
z-index: 1;
color: hsl(300, 70%,20%);
background-color: transparent;
border: none;
margin: 1rem;
padding: 1rem 1.5rem;
outline: none;
font-variant: small-caps;
font-size: 1.25rem;
font-weight: 600;
letter-spacing: 1px;
&:after,
&:before {
content: '';
position: absolute;
z-index: -1;
}
&:after {
border-radius: 0.5rem;
width: 100%;
margin: auto;
background-color: hsl(302, 41%, 76%);
top: 0;
right: 0;
bottom: 0;
left: 0;
box-shadow: 0 0.25rem 0 0.05rem hsla(302, 41%, 50%, 1);
transform-origin: center;
transform: translate(0%, 0%);
transition: all 0.25s ease;
}
}
.btn--squash-stretch {
&:after {
animation: 4s infinite squash-stretch;
}
}
.btn--anticipation {
&:after {
animation: 0.5s ease-in-out infinite alternate anticipation;
}
}
.btn--staging {
&:after {
transform-origin: center;
transform: translate(0%, 0%);
animation:
0.25s ease-out forwards pose-2-pose,
0.75s linear 0.25s staging infinite ;
}
}
.btn--pose-2-pose {
&:after {
transform-origin: center;
transform: translate(0%, 0%);
animation:
0.75s ease-out infinite pose-2-pose alternate;
}
}
.btn--follow-through {
opacity: 0;
transform: translate(100%);
animation: 1s cubic-bezier(1, 0.02, 0.39, 1.52) infinite follow-through;
&:after {
transform: translate(25%);
animation: 1s cubic-bezier(.04,.14,.89,1.74) infinite follow-through;
}
}
.btn--slow-in,
.btn--slow-out,
.btn--slow-in-out {
opacity: 0;
transform: translateY(-100%) rotateX(90deg);
animation: 3s cubic-bezier(1, 0.02, 0.39, 1.52) infinite alternate slide-in;
}
.btn--slow-in {
animation: 3s cubic-bezier(1, 0.02, 0.39, 1.52) infinite forwards slide-in;
}
.btn--slow-out {
animation: 3s cubic-bezier(1, 0.02, 0.39, 1.52) infinite reverse slide-in;
}
.btn--arcs {
&,
&:after {
opacity: 0;
transform-origin: 0% 0%;
transform: translate(200%, -60%) rotate(70deg);
animation: 2s cubic-bezier(1, 0.02, 0.39, 1.5) infinite arcs;
}
}
.btn--secondary-action {
transform: translate(0);
animation: 1s infinite cubic-bezier(1, 0.02, 0.39, 1.52) secondary-action;
}
.btn--secondary-action--sibling {
transform: translate(0);
animation: 1s -0.22s infinite cubic-bezier(1, 1.02, 0.81, 1.39) secondary-action--sibling;
}
.btn--fast {
transform: scale(0, 0);
animation: 2s infinite ease reverse timing-fast;
}
.btn--slow {
transform: scale(1, 1);
animation: 2s infinite ease timing-slow;
}
.btn--exaggeration {
opacity: 0;
transform: translate(0, -100%) scale(1, 1);
animation: 2s cubic-bezier(1, 1.02, 0.81, 1.39) infinite exaggeration;
}
.btn--solid {
animation: 2s ease-in-out infinite alternate solid-drawing;
}
.btn--appeal {
&:after {
animation: 2s cubic-bezier(0.79, 0.14, 0.15, 0.86) infinite appeal;
}
}
@keyframes squash-stretch {
92% {
transform: scale(1, 1);
}
94% {
transform: scale(1.75, 0.5);
}
100% {
transform: scale(1, 1);
}
}
@keyframes staging {
0% {
transform: translate(-50%, -50%) rotate(0deg) scale(1, 1);
box-shadow: 1em 0em 0 0 hsla(302, 41%, 50%, 1);
}
100% {
transform: translate(-50%, -50%) rotate(360deg) scale(1, 1);
box-shadow: 1em 0 0 0 hsla(302, 41%, 50%, 1);
}
}
@keyframes pose-2-pose {
0% {
width: 100%;
}
25% {
width: 1em;
padding-top: 1em;
}
100% {
top: 50%;
right: calc(-50% - 2rem);
bottom: 50%;
left: 50%;
width: 1em;
padding-top: 1em;
margin: auto;
border-radius: 50%;
transform: translate(-50%, -50%);
}
}
@keyframes anticipation {
0% {
transform: rotate(2.5deg);
}
100% {
transform: rotate(-2.5deg);
}
}
@keyframes follow-through {
100% {
opacity: 1;
transform: translate(0%);
}
}
@keyframes slide-in {
25%, 75% {
opacity: 1;
transform: translateY(0%) rotateX(0deg);
}
}
@keyframes arcs {
50%, 100% {
opacity: 1;
transform-origin: 100% 50%;
transform: translate(0, 0) rotate(0deg);
}
}
@keyframes secondary-action {
0% {
transform: translate(0%);
}
60% {
transform: translate(28%);
}
100% {
transform: translate(0%);
}
}
@keyframes secondary-action--sibling {
70% {
transform: translate(0);
}
80% {
transform: translate(10%);
}
100% {
transform: translate(0%);
}
}
@keyframes timing-fast {
25%, 100% {
transform: scale(1, 1);
}
}
@keyframes timing-slow {
95%, 100% {
transform: scale(0, 0);
}
}
@keyframes exaggeration {
10% {
opacity: 1;
transform: translate(0, 90%) scale(2, 0.25);
}
15%, 100% {
opacity: 1;
transform: translate(0, 0) scale(1, 1);
}
}
@keyframes solid-drawing {
0% {
transform: rotateY(25deg);
}
100% {
transform: rotateY(-25deg);
}
}
@keyframes appeal {
15% {
box-shadow: -0.5rem 0.25rem 0 0.05rem hsla(302, 41%, 50%, 1);
}
20% {
box-shadow: 0.5rem 0.25rem 0 0.05rem hsla(302, 41%, 50%, 1);
}
25%, 100% {
box-shadow: 0rem 0.25rem 0 0.05rem hsla(302, 41%, 50%, 1);
}
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.