Many CSS button effects I’ve seen lately involve animating one or both of the :before
and :after
pseudo elements to create interesting visuals on hover. To get an idea what I’m talking about, take a look at the following submit buttons:
Here I’m using submit buttons, but the same effect can easily be applied to any container element, such as a <a>
element instead. Access or fork the full code here.
I thought it’d be helpful to break down the basic technique shared by all of these button styles, so that you can modify or create your own, completely unique CSS button effects using this simple but very versatile technique.
Setting Up Each Button
The basic set up of each of the buttons you see above is the same. Here’s a nifty diagram to visually explain the 3 moving parts:
Each button consists of:
- A main button container element (ie:
BUTTON
,A
etc) set toposition:relative
and with a transparent background to allow its pseudo elements behind to show through. - A :before pseudo element with
z-index: -2
to act as the solid background color of the button. In some cases we’ll be animating this layer as well. - A :after pseudo element with
z-index: -1
to overlay the:before
element. We’ll be animating this layer in all cases to create interesting hover effects.
Such a set up allows the button text to always remain on top while we animate layers beneath the main button.
Here is the stripped down code for the first “Slide Down” button example you see above:
The HTML:
<button class="buttonfx" type="submit">Slide Down</button>
Main CSS for Main Button Element:
.buttonfx{ color: black; /* button text color */ outline: none; background: transparent; border: none; border-bottom: 4px solid #eee; position: relative; display: inline-block; overflow: hidden; transition: all .5s; }
Main CSS for :before
and :after
pseudo elements:
/* //// Default effect: Slide from Top //// */ .buttonfx:before, .buttonfx:after{ content: ''; position: absolute; left: 0; top: 0; right: 0; bottom: 0; height: 100%; background: #259f6c; /* onhover background color */ z-index: -1; transform: translate3D(0,-100%,0); /* move elements above button so they don't appear initially */ transition: all .5s; } .buttonfx:before{ background: #fafcd6; /* button default background color */ z-index: -2; transform: translate3D(0,0,0); } .buttonfx:hover{ color: white; } .buttonfx:hover:after{ transform: translate3D(0,0,0); transition: all .5s; }
As you can see, we begin by transforming the :before
and :after
elements above the button element, so they’re both out of view.
Then, for the :before
element, we move it down so it shows through behind the button (transform: translate3D(0,0,0)
). This layer acts as the default solid background color of the button.
When the user hovers over the button, we slide the :after
element down to create the “slide down” effect. CSS3 transitions are used to animate the change in values.
Adding a Bounce Effect to Any Transition
The second row of buttons in the demo above are identical to the first, with the exception of a nifty bounce effect. This is accomplished by merely adding the following CSS class to any button:
.bouncein:hover:before, .bouncein:hover:after{ transition-timing-function: cubic-bezier(0.52, 1.64, 0.37, 0.66) !important; }
The key lies in the custom cubic-bezier value, which creates a transition with the following behavior visually (as visualized in Chrome’s Developer’s Console):
The dip in altitude near the end translates into the animation regressing temporarily before settling on the end value.
To add the bounce effect to any of the buttons, we just tag on the “bouncein
” class to the button container:
<button class="buttonfx bouncein" type="submit">Slide Down</button>
Animating both Pseudo Elements at Once on Hover
The last row of buttons in the demo shows animating both the :before
and :after
elements when the mouse mouses over a button. The downside of this is that we lose the ability to specify the button’s default background color, as that role was previously assigned to the :before
element. There are ways around this, however, such as by nesting the button inside a wrapper with a background color defined.
The following additional CSS class creates the “Curtain Down” effect you see in the first button of the 3rd row of the demo:
.curtaindown:before, .curtaindown:after{ background: #259f6c; transform: translate3D(0,-100%,0); } .curtaindown:after{ transform: translate3D(0,100%,0); } .curtaindown:hover:before, .curtaindown:hover:after{ transform: translate3D(0,-50%,0); transition: all .5s; } .curtaindown:hover:after{ transform: translate3D(0,50%,0); }
HTML:
<button class="buttonfx curtaindown" type="submit">Slide Down</button>
Nothing much to it right?
Go and Create Your Own Pseudo Elements Based Hover Effects!
Now that you understand the parts and mechanics that go into so many of the CSS button effects making the rounds on the internet, go ahead and create your very own, totally unique button hover effect!