Sometimes you want to draw a user’s attention to a certain input or element. One way to do that is to flash or pulse the element. But when you google this, most examples involve flashing the whole background, such as with jQuery UI’s highlight effect. But if you’re like me—as I definitely am— you might think that is a little much. Or maybe it just doesn’t fit well with your design. Here’s how to do it without extra plugins. (Well, except for jQuery UI. Need that.)

There are a lot of methods out there suggested for doing this, such as using .addClass() with a CSS transition, and then removing it with .removeClass(). Problem: It’s difficult and convoluted to get the timing right. If you chain them right together, you get no effect. And they don’t use .delay(), as that only works on animations.

Well, maybe you could do it using .queue()? Yeah, but that’s inelegant to say the least. So let’s use .animate().

$('input').animate({borderColor:'red'});

Well, okay. Now our input is red. How do we change it back?

$('input')
  .animate({borderColor:'red'}, 400)
  .delay(400)
  .animate({borderColor:'black'}, 1000);

The “400” you see on the first animate() defines how long the animation will last, in this case 400 milliseconds or 0.4 seconds. The delay() is important because without it, your second animation will begin immediately after the first. Meaning that the moment the border color begins to change, it will also begin to change back. Kind of worthless. Make sure your delay is at least as long as your initial animation. If you want the border color to remain changed for longer, make the delay longer.

I like to make the return animation slower than the first one. It just looks smoother.

Okay, but you’ve probably noticed a problem already. The return animation makes the inputs’ borders black. What if you don’t want black? Well, you could specify exactly what color it should be based on your CSS, but then if you ever change the style, you’ll have to change your code too. Inelegant.

So maybe you’re thinking, “Hey, self. What if we use jQuery to get the color before we change it?” Nice idea, you. Seems easy.

var original_color = $("input").css("border-color");

Yeah, that won’t work. Why? Because it seems easy, that’s why. (And other technical reasons blah blah moving on.) But the good news is you’re close. Turns out you’ve got to specify which part of the border you want to get the color from. Again, because your original idea would simply be too easy.

var original_color = $("input").css("border-left-color");

I chose left here, but you could use right or top or whatever, since we’re assuming here that your border is the same color on all side. (If not, then I’m sorry. May the fates be kind to you.)

So, let’s put it all together:

var original_color = $('input').css('border-left-color');

$('input')
  .animate({borderColor:'red'}, 400, 'linear')
  .delay(400)
  .animate({borderColor:original_color}, 2800, 'easeOutCirc');

Now you’re asking what’s up with the ‘linear’ and ‘easeOutCirc’. Those are easings, which let you finagle with, well, the easing. Look here for examples. I’ve found that sometimes the return trip can get a little jerky, especially toward the end. So I chose ‘easeOutCirc’, which has the slowest tail end. Feel free to tinker with the timings and easings as you see fit.

Bonus!

I’m highly caffeinated at the moment, so let’s get ambitious. What if we have a whole bunch of inputs we want to highlight? In my case, this would be on a form which I’m validating using jQuery Validation. To make things easy on the user—since it’s bad enough they’re having to deal with validation errors in the first place—I like to scroll to the first error on the form, in case it’s off screen. (Otherwise the form will just sit there dumbly and not give any indication why it’s not submitting. #rage)

$('html, body')
  .animate({scrollTop: $(".error:first")
  .offset().top -90}, 500);

Here’s where we go very slightly crazy with the animations. Assuming there are more than one, let’s get all smooth ‘n smarmy and highlight them one after another:

// Get the border color of the first input on the form.
// (.form-control is a class I have on all inputs.)
var original_color = $("#process-form .form-control:first").css("border-left-color");

// Init this
offset = 0;

// For each one pulse the border color, with the duration extending for each
$('.form-control').each(function(){
  $(this)
    .animate({borderColor:'red'}, 400+offset, 'linear')
    .delay(400+offset)
    .animate({borderColor:original_color}, 2800+offset, 'easeOutCirc');

  // Set this to whatever interval you want between input animations.
  // 200 works pretty well.
  offset = offset + 200;
});

Have fun out there, campers.