Code unique 50/50 rollovers with jQuery & SVG

The yoocon developer team reveals how the Carerra sites unique GROOMING/STYLING footer was built


The yoocon developer team reveals how the Carerra sites unique GROOMING/STYLING footer was built



1. Define the HTML

Our markup starts with a simple HTML structure with some basic CSS styling, most importantly setting the link display property as inline-block. This current static state is essentially what non-JS capable browsers and search engines will see. We then include jQuery alongside the Bez plugin by Robert Dallas Gray (

2. Work with SVG

For the slanted clipping effect we need an SVG and note the two links shown on FileSilo, each with its own mask. On top, there is the slanted stroke drawn within a vector application. You can choose an angle of your choice, but be sure to note it. The initial position of the stroke is at the left side with a negative margin of half its own size.

3. The final SVG

This is how the final SVG should look like. We will just have to add some classes and fill in the placeholders:

<svg width="{{width}}" height="{{height}}">
<mask id="clip-slide-link1">
<polygon fill="white" points="0 0, {{right_top_x}} 0, {{right_bottom_x}} {{bottom_y}}, 0 {{bottom_y}}" />
<mask id="clip-slide-link2">
<polygon fill="white" points="{{left_top_x}} 0, {{right_top_x}} 0, {{right_bottom_x}} {{right_bottom_y}}, {{left_bottom_x}} {{left_bottom_y}}" />
<g mask="url(#clip-slide-link1)">
<text x="50%" y="50%"></text>
<g mask="url(#clip-slide-link2)">
<text x="50%" y="50%"></text>
<path id="stroke" fill="#ababab" d="M-44.023,277.106l-0.951-0.309L44.023,2.894l0.951,0.309L-44.023,277.106z">

4. Caching and templating

We will now begin our code process by inserting a jQuery.ready() method, caching all the necessary link properties like width and href as JS vars, before grabbing the containing element’s width. Save the stroke height and the ratio, calculated from the stroke angle in Step 3 using the tangent function. Put the SVG into a jQuery object, fill the variables with real values and add classes to some of the nodes.

5. Switch links for SVG

Next we write an init() function that detaches the original links and replaces them with the SVG, transferring the link texts into the SVG text nodes. Create a new object for the animation states and set a key for the start, middle and end positions, each with their respective value:

6. The animation bit

For animation we used the jQuery animate method, however animating CSS transform values in the SVG may fail in some browsers so use SVG’s own transform attribute instead. Unfortunately, jQuery can’t animate attributes so we use the animate method as a driver and change the SVG in a self-written function. The jQuery animate method can handle any object, with our object counting from 0 to 1 for moving the stroke right, and from 0 to -1 for moving it left. Additionally, we use custom easing via the Bézier plugin. This returns jQuery-like easing functions from CSS Bézier curve parameters.

$.bez('your_easing', [.17, .67, .21, 1]);
var $animation = $({t: 0});
function animateTo(destination) {
var t = destination == 'start' ? -1 : destination == 'end' ? 1 : 0;
$animation.stop().animate({t: t}, {
duration: 600,
step: render,
easing: 'your_easing'

7. The render function

Next we have the render function, with t accepting the values between -1 and 1 depending on the direction. From here we use the rule of three and calculate the current positions. Apply these values to the SVG masks and stroke by using the setAttribute method:

function render(t) {
var at = Math.abs(t);
var x1, x2, x;
x1 = x_state.middle;
x2 = t < 0 ? x_state.start : x_state.end;
x = x1 * (1 - at) + x2 * at;
mask1.setAttribute('transform', 'matrix(1 0 0 1 ' + (x - outer_width) + ' 0)');
mask2.setAttribute('transform', 'matrix(1 0 0 1 ' + x + ' 0)');
stroke.setAttribute('transform', 'matrix(1 0 0 1 ' + x + ' 0)');

8. Animate with the mouse

Finally we use mouse events to detect whether the mouse pointer is on the left or the right side of the document. Every time the pointer changes sides or leaves the SVG, an animation will be triggered. Be sure to set the right href attribute on every change, before triggering an initial rendering.

var lastPos = "middle";
var currentHref = link1_href;
$slide_link.on('mousemove', function(e) {
var currentPos = "";
if (e.pageX < $(window).width()/2) {
currentPos = "end";
currentHref = link1_href;
} else {
currentPos = "start";
currentHref = link2_href;
if (lastPos === currentPos)
}).on('mouseleave', function(e) {
}).on('click', function() {
window.location = currentHref;