23

At my personal website, I'm using the CSS3 Transition property on the top nav to animate the margins and padding of an element with a border, to make the border swell on hover.

Relevant markup:

<nav>
        <a class="email" href="mailto:notmyrealemailaddress">
          <div class="icon-border">
            <img src="images/mail_icon.png" width="14" height="12">
          </div>Email Me</a>

        <a class="phone" href="tel:4075555555">
          <div class="icon-border">
            <img src="images/phone_icon.png" width="11" height="18">
          </div>Call Me</a>

        <a class="behance" href="http://behance.net/dannymcgee" target="_blank">
          <div class="icon-border">
            <img src="images/behance_icon.png" width="21" height="13">
          </div>See My Work</a>
</nav>

CSS:

header nav .icon-border {
  display: inline-block;
  border: 2px solid #000;
  border-radius: 30px;
  padding: 5px;
  margin: 0 10px;
  transition: 0.15s padding ease-out, 0.15s margin ease-out, 0.15s border ease-out;
}

header nav a:hover .icon-border {
  padding: 10px;
  margin: -10px 5px;
  border: 2px solid #ddd;
  transition: 0.15s padding ease-out, 0.15s margin ease-out, 0.15s border ease-out;
}

See what it's doing? By decreasing the margins and increasing the padding on hover, the circular border effectively gets bigger without altering the position of the image it's wrapped around.

It works pretty well, but the problem is that if I quickly move the mouse from EMAIL ME to CALL ME and vice versa, before the first animation completes, the whole nav "jumps" up and down by about a pixel. However, this issue doesn't happen between CALL ME and SEE MY WORK, which leads me to believe it's an issue that can be fixed. Any ideas?

dannymcgee
  • 621
  • 2
  • 9
  • 16

3 Answers3

32

I believe the issue is because you are transitioning the margins (and using negative margins which is always a little wonky).

A smoother solution might be using transform: scale(x)

someting like:

header nav .icon-border {
  display: inline-block;
  border: 2px solid #000;
  border-radius: 30px;
  padding: 5px;
  margin: 0 10px;
  transform: scale(1); /* you need a scale here to allow it to transition in both directions */
  transition: 0.15s all ease;
}

header nav a:hover .icon-border {
  transform: scale(1.2);
  border: 2px solid #ddd;
}
JustH
  • 1,372
  • 8
  • 8
  • 1
    Super smooth, thank you! Only "problem" is that the image also gets larger, but I can probably figure out a fix. Also, thanks for the transition shorthand! – dannymcgee Jan 29 '15 at 00:51
  • There are a couple ways you could deal with keeping the image the same size. The easiest might be taking the icon our of the boarder div and using absolute positioning to put it on top, then the transform wont't affect it. – JustH Jan 29 '15 at 17:31
  • I ended up using transform: scale() on the images as well to shrink them while the border expands, which worked perfect once I found the right value. You can see the result at dannymcgee.net. – dannymcgee Jan 29 '15 at 23:40
1
div {
  transition: all 0.5s ease;
  padding: 13px;
}

div:hover {
  padding: 23px;
}

or

* { transition: all 0.5s ease; }

div {
  padding: 13px;
}

div:hover {
  padding: 23px;
}
DEV Tiago França
  • 1,271
  • 9
  • 9
0

Maybe this works:

header nav a {
  display: inline-block;
}
fcastillo
  • 938
  • 1
  • 11
  • 24