In today’s tutorial, we’ll learn two different techniques for creating a “wipe fill” text effect on hover. We’ll even go one step further and give ourselves the flexibility to select the direction of the animation.
Here’s what we’ll be creating:
As you can see, when you hover over the text a fill is applied, wiping across from one side to the other. The upper menu links have no apparent fill to begin with, but instead have a text stroke which then appears to fill up on hover.
Using CSS transitions you can alter the speed and easing of the wiping effect to whatever suits your project.
Technique #1
Let’s walk through the first technique, in which we use a bit of extra markup to create each link’s “wipe fill” element.
Specify the Page Markup
We’ll start with a plain unordered list which will represent a typical page menu. Each menu link will include a text node and a span
element. The text inside the span
will match the list item’s text. We’ll give this element aria-hidden="true"
because we want to hide it from any accessibility devices. In actual fact, the only reason for its existence is to help us build the desired hover effect.
As a bonus, we’ll give ourselves the ability to set the direction of the hover effect animation. We can pass the data-animation
custom attribute to the list items which will determine the starting position of their animation. Possible attribute values are to-left
, to-bottom
, and to-top
. By default, the effect will appear from left to right.
Here’s the required markup:
<ul class="menu"> <li> <a href="#0"> About Us <span class="outer" aria-hidden="true"> <span class="inner">About Us</span> </span> </a> </li> <li data-animation="to-left"> <a href="#0"> Projects <span class="outer" aria-hidden="true"> <span class="inner">Projects</span> </span> </a> </li> <li data-animation="to-bottom"> <a href="#0"> Clients <span class="outer" aria-hidden="true"> <span class="inner">Clients</span> </span> </a> </li> <li data-animation="to-top"> <a href="#0"> Contact <span class="outer" aria-hidden="true"> <span class="inner">Contact</span> </span> </a> </li> </ul>
Specify the Basic Styles
Let’s continue with the CSS styles.
We’ll add a stroke to the menu links by using the native text-stroke
property. Nowadays, this property has great browser support. However, in case you need to support Internet Explorer or Microsoft Edge 12-14, you can use the text-shadow
property to simulate a stroke.
If you don’t like the stroke around the text, I’ve created an alternative layout which will append a background color to the menu along with its links. To enable it, just attach the has-bg
class to the menu.
The associated styles are as follows:
/*CUSTOM VARIABLES HERE*/ .has-bg { background: var(--stroke-color); padding: 40px 0 60px 0; margin-top: 20px; } .menu a { position: relative; display: inline-block; font-weight: bold; font-size: 60px; line-height: 1.4; overflow: hidden; color: var(--white); -webkit-text-stroke: 1px var(--stroke-color); /*text-shadow: -1px -1px 0 var(--stroke-color), 1px -1px 0 var(--stroke-color), -1px 1px 0 var(--stroke-color), 1px 1px 0 var(--stroke-color);*/ } .has-bg a { color: var(--secondary-color); text-shadow: none; }
And Now for the Animation Styles
The outer span
inside the links will be absolutely positioned. In addition, to this we’ll give it a dark cyan background color and set its overflow
property to hidden
. By default, we’ll move it 100% of its original position to the left and its inner span
100% of its original position to the right. Then, each time we hover over a link, we’ll remove their initial transform values. That simple trick will produce a fill text hover effect which will go from left to right.
Here are the associated styles:
/*CUSTOM VARIABLES HERE*/ .menu .outer { position: absolute; top: 0; left: 0; overflow: hidden; color: var(--fill-color); transform: translateX(-100%); } .menu .inner { display: inline-block; transform: translateX(100%); } .menu a .outer, .menu a .inner { transition: transform 0.15s cubic-bezier(0.29, 0.73, 0.74, 1.02); } .menu a:hover .outer, .menu a:hover .inner { transform: none; }
Specifying Direction
Lastly, as discussed in the markup section, we can customize the direction of our hover effect by passing the data-animation
attribute to a menu item. Depending on the effect direction (horizontal or vertical), we have to define reversed transform values for the .outer
and .inner
elements:
[data-animation="to-left"] .outer { transform: translateX(100%); } [data-animation="to-left"] .inner { transform: translateX(-100%); } [data-animation="to-top"] .outer { transform: translateY(100%); } [data-animation="to-top"] .inner { transform: translateY(-100%); } [data-animation="to-bottom"] .outer { transform: translateY(-100%); } [data-animation="to-bottom"] .inner { transform: translateY(100%); }
The resulting demo:
Technique #2
Let’s now examine the second technique, in which we keep our markup cleaner by using pseudo-elements to provide the “wipe fill”.
Specify the Page Markup
We’ll start again with a plain unordered list. Each menu link will include the data-text
custom attribute. The value of this attribute will match the text of the related link.
Similarly to the previous example, we’ll be able to customize the starting position of an animation via the data-animation
attribute. Possible attribute values are to-left
, to-bottom
, and to-top
. By default, the effect will appear from left to right.
Here’s the required markup to get us started:
<ul class="menu"> <li> <a data-text="About Us" href="#0">About Us</a> </li> <li data-animation="to-left"> <a data-text="Projects" href="#0">Projects</a> </li> <li data-animation="to-bottom"> <a data-text="Clients" href="#0">Clients</a> </li> <li data-animation="to-top"> <a data-text="Contact" href="#0">Contact</a> </li> </ul>
Specify the Animation Styles
The basic CSS styles for this are the same as in the previous technique. For the animation we’ll define the ::before
pseudo-element of each menu link and absolutely position it. Its content will come from the data-text
attribute value of the parent link. Initially, its width will be 0, but then, when we hover over the target link, it will be set to 100%. Also, we’ll give it white-space: nowrap
, so the text will never wrap to a new line.
The related styles for this are as follows:
/*CUSTOM VARIABLES HERE*/ .menu a::before { content: attr(data-text); position: absolute; top: 0; left: 0; width: 0; overflow: hidden; color: var(--fill-color); white-space: nowrap; transition: all 0.15s cubic-bezier(0.29, 0.73, 0.74, 1.02); } .menu a:hover::before { width: 100%; }
Add the Hover Effect Styles
Next, we’ll add the styles responsible for customizing the direction of our hover effect. So first, we have to check the direction of the desired animation (horizontal or vertical), then animate accordingly the width
or the height
property of the target pseudo-element. In addition, in case we’re interested in the “to left” or “to top” animation, we should swap the text color values of the target pseudo-element and its parent link.
The styles that handle these animations are as follows:
/*CUSTOM VARIABLES HERE*/ .menu [data-animation="to-left"] a, .menu [data-animation="to-top"] a { color: var(--fill-color); } .menu [data-animation="to-left"] a::before, .menu [data-animation="to-top"] a::before { color: var(--white); } .menu [data-animation] a::before { width: 100%; } .menu [data-animation="to-left"] a:hover::before { width: 0; } .menu [data-animation="to-top"] a::before { height: 100%; } .menu [data-animation="to-top"] a:hover::before { height: 0; } .menu [data-animation="to-bottom"] a::before { height: 0; } .menu [data-animation="to-bottom"] a:hover::before { height: 100%; }
The resulting demo:
Conclusion
And, we’re done! In this exercise we discussed two different ways for creating a wipe fill hover effect. Hopefully these have inspired you to build something similar, or at least, incorporate the effect in an existing project.
As always, thanks for reading!
Learn CSS With These Projects
Few things are as fun in the world of front end coding as messing around with CSS; take a look these CSS projects on Tuts+ and learn while playing!
No comments:
Post a Comment