One of my pens was featured under Editor’s Picks on CodePen the other day. As a result, the pen got a lot of views, hearts and it’s been added to a various number of collections. So given this, I thought that a tutorial on how I created this pen could be a great opportunity for me to start blogging and hopefully there’s someone out there who’ll enjoy to read how the buttons were created.
So here it goes. My first blog post and my first ever tutorial.
Browser support:
Chrome 27+, Safari 5.1+, Firefox 21+, IE10+ and Opera 15+
OK, before we jump into the code I’ll briefly explain what we want to achieve. The demo contains two buttons, but I’ll only walk you through how one of them was created. There isn’t much to say about the design, since it’s not vital for the demo to work. Focus will instead lie on how I created the text-transition that appears when the button is clicked.
Please note that I am using un-prefixed CSS properties.
HTML
There isn’t much to say about the markup other then that you should notice how the flip
div is wrapped around the submit
and sent
classes. The reason for this is simple. The effect we want to achieve when the button is clicked is to perform a “flip animation”, and this will be achieved by rotating the flip
div 180 degrees around its x axis.
<div class="wrapper">
<div id="btn1">
<div id="flip">
<div class="submit"><p>Submit</p></div>
<div class="sent"><p>Thank you!</p></div>
</div>
</div>
</div>
CSS
Now, let’s have a look at the CSS. First of all we got the wrapper
which is only used for centering the buttons and then we got the actual button styles. I tried to create a clean/flat design using plain colors with a slightly darker border. The border-radius
is used to smoothen the edges and I’ve also added a hover effect where I transition the background to the same color as the border. In this case, the transition-duration
is set to 0.2
seconds and the transition-timing-function
is set to ease-in-out
, which gives the transition a slow start and end.
.wrapper {
position: relative;
top: 2.52em;
width: 21.7em;
height: 100%;
margin: 0 auto;
}
#btn1 {
position: absolute;
width: 9.45em;
height: 3.15em;
background: #18a397;
border-radius: 0.189em;
text-align: center;
cursor: pointer;
border: 0.126em solid #0b988c;
z-index: 1;
}
#btn1:hover {
transition: 0.2s ease-in-out;
background: #0b988c;
}
Since we are performing a “flip animation” to change the message in the button we’ll need different messages on each side. The .submit
class holds the default message and the .sent
class holds the message that will be visible after the flip animation. To manage this I’ve used the backface-visibility
property which defines if an element should be visible or not when faced away from the screen.
In this case I’ve set the backface-visibility
to hidden;
on both .submit
and .sent
, and as you might of noticed I’ve also rotaded the sent class 180 degrees around it’s x axis. This way we’ll get one message before and after the “flip animation”.
#flip {
position: relative;
width: 9.45em;
height: 3.15em;
background: transparent;
transform-style: preserve-3d;
}
.submit {
position: absolute;
width: 9.45em;
height: 3.15em;
backface-visibility: hidden;
}
.sent {
position: absolute;
width: 9.45em;
height: 3.15em;
backface-visibility: hidden;
transform: rotateX(180deg);
z-index: 2;
}
To trigger the animation I’ve written a JavaScript onclick event which ads a class, in this case .animate
to the flip div. The class contains the following properties: animation-duration: .2s; animation-name: flip; animation-timing-function: linear;
, which gives the animation a consistent speed from start to end and animation-fill-mode: forwards;
which persists the end state (100%) of the animation.
.animate {
animation: .2s flip linear forwards;
}
@keyframes flip {
100% {
transform: rotateX(180deg);
}
}
JavaScript
(function () {
"use strict";
var flip = document.getElementById('flip'),
button = document.getElementById('btn1');
button.onclick = function () {
flip.className = 'animate';
};
})();
I may add that I’ve just started to digg into JavaScript, so there are surly better and more efficient ways to trigger an animation.
That’s about it!