POP has these cool hovers in the boxes that make up their homepage. The boxes have a white background by default, and as you hover over them a dark background slides up behind, the text colors change, and the text “pops” up a little. When you hover off, the dark background slides away, the text colors change back, and the text pops down a little. I thought I’d try and replicate it because, you know, eff yeah hovers.
Demo
Check out this Pen!
HTML
Each area is a “box”:
<a href="#" class="box">
<h2><span>Breaking news -</span> hippos are sorta dangerous</h2>
<h3>Tonight at nine</h3>
</a>
CSS (backgrounds)
The styling of the default box is trivial. The hovers are the interesting part. POP does the background slide by using an actual element they animate the position of. If we’re OK with this feature only working on browser that support gradients, we can ditch that element and just animate the background-position.
A top-half-white and bottom-half-black background is easy:
background: linear-gradient(
white, white 50%, black 50%, black
);
Then we make it twice as tall as the element itself:
background-size: 100% 200%;
Like this:

In reality, we’ll make the background a little bit taller than 200%, because right at 200% it was exposing a little bit of background into the element still (in Chrome).
.box {
background: linear-gradient(
white, white 50%, #333 50%, #333
);
transition: all 0.2s ease;
}
.box:hover {
background-position: 100% 100%;
}
CSS (colors)
The default text color is black, so no CSS needed at all there. On hover, we adjust the colors. The span changing is just a fun surprise and brings more pop to the party.
.box:hover h2 {
color: #48ad26;
}
.box:hover h2 span {
color: white;
}
.box:hover h3 {
color: #999;
}
CSS (bumping)
The tricky bit here is that the “bump” happens in different directions depending on if it’s a hover-on or hover-off. The fact that the text moves a bit and then back to it’s original position means a transition won’t help us here either, this is animation territory. We’ll make one @keyframes for the up-bump and another for the down bump. Just a bit of padding will help us, because our box-sizing choice keeps the height of each box the same.
@keyframes up-bump {
0% { padding-top: 2em; }
50% { padding-top: 1.5em; }
100% { padding-top: 2em; }
}
@keyframes down-bump {
0% { padding-top: 2em; }
50% { padding-top: 2.5em; }
100% { padding-top: 2em; }
}
By default (triggers on hover-off) the .box
will get the down bump and the :hover
will get the up bump. This matches the direction of the background sliding in and out.
.box {
animation: down-bump 0.4s ease;
}
.box:hover {
animation: up-bump 0.4s ease;
}
Initial bump fix
Adding that animation on the initial state makes it run right away on page load. Could be a neat effect, could be annoying. The POP site doesn’t run them on load. Matt Boldt had the good idea of adding the out-bump when the hover out occurs only (via a class) so it won’t run at first.
Check out this Pen!
On no-hover devices…
They are links and no vital content is hidden, so no big deal.
Sweet effect. Touch devices aren’t the only gotcha – for keyboard-only users, the results don’t appear to kick in consistently. Someone may have to tweak a little more before implementing if there is an obligation to that audience.
You could add the effect on the :active state as well.
Loooooveeeeee. (obviously).
Might want to add an outline to the whole box on :focus to tackle the keyboard issue and leave off the animations all together. This is something I’ve been thinking about: If keyboard users would be better served with a simpler effect/on state. I can come up with some use cases on why it would and also some why it wouldn’t.
Actually, is there a way to target keyboard-only users? I can think of a really complicated solution, but that’s probably not for the best.
im not sure but actually you could attach an event handler and see if it triggers “keydown” and add tabindex for every div, something like that
$(“#myid”).on(“keydown”, function(event){
if (event.keyCode == 9 )
{
//etc
}
});
Nice!
I thought that a pseudo ‘:before’ would be a good way of doing this but transitions fail on them it seems.
Eff yeah hovers, indeed.
But the text moving stop after continuous attempt on hover.
Yah, same problem. If I just let my mouse go apeshit over these, it breaks and no longer jumps up when hovered upon.
Any solution?
Can’t seem to replicate it here. But I’m not sure much could be done. I know that kind of thing was common in jQuery animation days where you needed to be careful to stop previous animations and generally handle things smarter. But all that’s going on here is some CSS animations that either apply or don’t. I’m sure if you could get a screencast of the breakage, it would be a great thing to report as a bug to the relevant browser.
Posted this earlier. But it didn’t go for some reason. I think it has something to do with the email address domain I used. @gmail works fine, but my work address doesn’t seem to work Chris. Maybe my previous post got placed in the moderation queue?
Anyway, here’s a screencast I made. Replicates the issue Solomon brought up. I’m on FX20.
http://www.screenr.com/fkJ7
Highly discourage anyone from doing this in real world scenarios. From a UX perspective, 1. The text bump effect serves no purpose, carries no message, does not serve as a transition to anything 2. Text should not jump up and down (esp. While the text color and the background are changing). Peronally, it hurts my eyes, like looking at a photo just out of focus.
Aw don’t be a grumpy gus!
Of course it doesn’t serve any purpose, it’s just a fun interactive experience. The web would be a boring place if nothing ever moved or surprised us.
It’s very difficult to make a judgement based on UX when such experience is awfully quite subjective. You for example, found the transitions to serve no real purpose. I found them to be a visually interesting way to show that the items on the page were not merely static, but linked to further information.
This effect was (for me) more appealing when it covered the entire container, rather than when it covered only 1/2. I actually found the latter to be a bit visually jarring.
I also didn’t see any issue with the text jumping. I wouldn’t say it adds anything that is structurally important – but no website or app is purely a matter of ‘function’. A certain level of accommodation must be allowed for ‘form’.
While I understand what you’re saying, I feel like if you took this argument to its fullest conclusion we’d have an internet full of completely effective yet really boring websites. When used sparingly and with good placement the “why the hell not” can be what a site needs to make it interesting.
No body NEEDS frosting. But it tastes good and I like it.
Being visually appealing is a purpose in itself.
This is very true.
Where is the like button for this comment? ;)
Hey love the site chris big fan , your pod casts RULE , also I wouldn’t be where I am now in the CSS / WordPress world without the lodge , just wanted to say that on the site www. protest.eu website they have a similar effect on there info boxes it looks like the box comes up on hover / focus state I also like the way the sliders scroll left as you scroll down the page think it was done with jquery what do u all think ?
Yes… well the web being as it is and respecting the content first mentality i find this effect adding playfulness to it… specially on this part…
Waka waka!!!!!
My personal favourite!
Love it!
I always loved the way you represent/develop things using CSS, I’ve just started learning CSS and sharing my learning on my newly created website csshacks.org, I actually want to know “Is there any way we can make a loop of transition effect? i.e. repeating the transition effects”
Thanks
Thanks again for a cool new css trick. It’s amazing that it can be done with no jquery. Anyone know the browser support for this trick? It works in current versions of Chrome, Safari, and Firefox on mac. I read that IE 10 does support gradients. I suppose you can server a background color change to non-compliant browsers.
Nice effect. I don’t think it would be too hard to adapt this to touch event.
If the initial box had a visual and once hovered revealed a message – as it is used on POP – then I have tons of uses for this. How can I achieve this. New kid on the block here.
Hey Chris, good trick!!! :)
Thanks!!
Hello Chris,
Nice trick. I tried this on my site for about a year or so to display a nice menu. Initial box shows the ICONs and on hover it would bring the initial Box up and show up related links. On hover out – Related links goes down and Box comes from top to bottom. I used
-webkit-transition
for animation.It looked very beautiful but The only drawback with that is many people didn’t click on the links as they are hidden beneath the original DIV. Only the people who show that happening and knew something is hidden beneath that clicked.
Just created a Pen on Codepen to show what I had implemented on my site zevolving.com.
Used CodePen first time, its awesome!
Can’t submit?
Really awesome! I think has some really great real world implementation. I’m all about getting the user to experience the site rather than just see it! I hope to see things like this more and more :)
I did a button with similar effect : http://codepen.io/burnandbass/pen/dvaql
I’m beginning to wonder how safe the “… and then we don’t worry about no hover on no-hover devices” attitude is.
I think it’s fine here, as you point out, there’s no loss. But it is something that should be considered carefully when making these decisions.
Otherwise, thank you for a thorough and easy to understand description of a great effect, there are some details I would have missed that really add to it.
You say a transition won’t work because of the ‘bump’, but maybe a custom
cubic-bezier
timing function would do the trick, e.g. http://cubic-bezier.com/#.4,1.4,.39,1.5Nice effect and great to learn more about css animations and transitions.
From this code, I copied it to modify it and try to learn more:
I added a “Read more” in every box just to try.
The “read more” uses a div (yes, I know It’snt very semmantic) with absolute position, and I added to .box class position:relative and overflow:hidden.
But I don’t get to work properly, it has a strange effect when hover the second box: the third one dissapears while during the transition.
Without animation property in .box:hover it seems to work fine but It’s not the same obviously
Great little trick mate!
This is nice Chris. Will be looking for an excuse to use this asap! Thanks :)
Love the effect, Chris.
I’ve used jQuery for similar techniques in the past but good to see a CSS alternative, thanks!
I noticed the problem with the text animation getting lost as well. It seems to happen once you’ve gotten a little crazy with the mouse pointer. I’ve also found CSS animations to be a bit unpredictable across various browsers, so I’m still using jQuery. Tsk tsk.
jQuery can fail when you move the mouse near the speed of light, but there are some good workarounds that do what Chris said: drop the previous action before starting a new one.
Here’s a Gist containing the code I use to add a .hover class when I can’t/won’t use the :hover pseudo-selector. I wonder if this was used to add a class, then the animation was tied to the class change if the behavior would be more reliable.
https://gist.github.com/ryanburnette/5337314
Here’s a Pen containing the same code, but using the more reliable jQuery hover. Who knows, maybe it helps.
http://codepen.io/ryanburnette/pen/JxcEo
Sorry my ignorance but…. h2 inside anchors? Should it be done?
Sure. HTML5 is cool with that.
Really cool code you have given
I love it!thanks!
Cool effect, but I guess it has limited usability in current form, and if everyone starts using it, than it wont be anything interesting/special. However, I do believe that its an interesting topic to think about and inspire new ways of implement it. So much can be done with this.
I had a litte css shape to move, ‘margin’ was the one that did it for me:
no thnks