Designing For Emotion With Hover Effects


Of the many factors that must be considered in Web design, emotional interaction is an important, but frequently neglected, component. In the real world, we experience the sensual interaction of design all the time. Reflect for a moment on the emotional engagement of slipping behind the wheel of a powerful luxury car: the welcoming embrace of the driving seat, the tactile experience of running your hands over the leather on the steering wheel, the subtle gleam reflected in the controls.

There is no technical requirement for any of these finely crafted details: The vehicle would perform equally well without them. Yet this singular focus on sensual and emotional engagement is what separates luxury goods from all others and what inspires deep loyalty from customers.

This drive for emotional design can be discovered in the most surprising places. Take the power light on the next to last-generation Apple MacBook. The company deserves credit for helping thousands of users avoid entanglements with power cords though the MagSafe connector, but the deeper emotional intimacy is held in the tiniest of details: the power status light on the front of the laptop. When in sleep mode, the light pulses, and not randomly: It does so 10 times a minute, the breathing rate of a resting human being.

macbook sleep light_mini1
The blink rate of Apple’s MacBook in sleep mode falls within the average breathing rate of a resting adult. (Image source: Michael Stillwell2)

To take another example: The front of a car is not two headlights and a grill. It is a face, one with its own character and communication. Look at cars and vans marketed to suburban mothers, on which lines tend to be round, curved, welcoming and friendly.

The front of the vehicle often demonstrates the neotenic effect: We regard “eyes” (headlights) that are larger than the body as being cute, safe, loveable. Compare this to the visual communication of vehicles marketed to men, particularly sports cars: Those lines are angular and aggressive, right down to the slitted eyes.

sport car front_mini3
Note how a sports car’s front interacts with you on an emotional level. (Image source: GabboT4)

Designing For Emotion

We can strive to achieve the same emotional engagement on websites — a promise to delight, surprise and affect users without resorting to manipulation or being too saccharine. While the digital realm lacks many sensual cues, it is possible to impart an emotional experience through a careful selection of color, stroke and typography.

CSS transitions help us to make interactions more human: Rather than flicking from one state to another, we can ease the motion of an element over a few hundred milliseconds to make a website feel more inviting. Paradoxically, the same techniques can also make a website feel faster, especially if we use the opportunity to preload content.

In creating such experiences, we must avoid the mistakes of the past: The engagement should encourage the visitor to explore the website, but should never hide important components such as navigation. Rewards for exploration should be a treated as a bonus, rather than a required interaction. Any information shared should also be accessible to those who don’t have the time or ability to use the interface.

Surprise In Boxes

(Please see the demo at “Hover Effect on Images From Different Directions Using Pure CSS,”5 on CodePen.)

One way to design for emotional surprise and stimulation might be to present different panes of information according to the way the user hovers over a responsive image. For this example, I’ll use a photo of the spiral galaxy NGC 1309, added to an HTML5 page:

<img src="ngc-1309.jpg" alt="">

(Note that I’ve intentionally left the alt value of the image blank. We’ll return to that attribute shortly.)

The information panels are created from four span elements, with the entire group wrapped in a div tag that includes a class:

<div class="multi-hover">
    <span>Spiral Galaxy NGC 1309</span>
    <span>Approximately 120 million light years from Earth</span>
    <span>Home to several Cephid variable stars</span>
    <span>Member of the Eridanus galactic cloud</span>
    <img src="ngc-1309.jpg" alt="">

We’ll write the CSS transition code sans vendor prefixes: Internet Explorer 10 does not use prefixes for animation, Firefox no longer requires them, Chrome is not far behind, and a piece of JavaScript magic such as Lea Verou’s -prefix-free6 will take care of those browsers that still do.

.multi-hover {
	position: relative;
	font-family: Orbitron, sans-serif;
	max-width: 500px;
	line-height: 0;

.multi-hover img {
	max-width: 100%;

.multi-hover span {
	position: absolute;
	width: 100%;
	height: 100%;
	line-height: 1.5;
	font-weight: 100;
	text-align: center;
	box-sizing: border-box;
	font-size: 3em;
	transition: .3s linear;
	color: white;
	padding: 15%;
	opacity: 0;

The CSS takes advantage of the rule that absolutely positioned elements inside relative containers will be transformed relative to their parent. Because the image determines the height and width of the div, the span elements will always be exactly the same size, protected from growing further by the use of box-sizing, max-width and line-height: 0. In this example, I’m using Orbitron7 by The League of Moveable Type8 as an appropriate typeface.

Next, locate the span elements, so that each lies just over the inner edge of the image. We’ll do so by writing offsets from the containing div in percentages, to keep everything responsive:

.multi-hover span:nth-child(1) {
	top: 0;
	left: 90%;
	background: hsla(0,70%,50%,0.6);  } /* right panel */

.multi-hover span:nth-child(2) {
	top: -90%;
	left: 0;
	background: hsla(90,70%,50%,0.6); } /* top panel */

.multi-hover span:nth-child(3) {
	top: 0;
	left: -90%;
	background: hsla(180,70%,50%,0.6); } /* left panel */

.multi-hover span:nth-child(4) {
	top: 90%;
	left: 0;
	background: hsla(270,70%,50%,0.6); } /* bottom panel */

As you’ll see in a moment, the order of the panel declarations matters. The result looks something like this:

Positioned span elements with text.9
Positioned span elements with text. (Large view10)

To clip the outside edges of the panels, use overflow: hidden on the containing div:

.multi-hover {
	position: relative;
        overflow: hidden;
	font-family: Orbitron, sans-serif;

Now, the result appears like this:

Span elements clipped to image.11

The colored sections we can see for now will function as the “hit areas” of our panels. Increasing the size of these areas will increase the panel’s ability to respond to quicker and broader mouse movements, but will also increase the overlap between them, making it more likely that a different panel will be activated than the one expected.

Finally, we’ll hide the panels entirely by setting their opacity to 0 and moving them on hover, taking advantage of the fact that transparent elements still respond to mouse events.

.multi-hover span {
	position: absolute;
	width: 100%;
	height: 100%;
	line-height: 1.5;
	font-weight: 100;
        z-index: 2;
	text-align: center;
	box-sizing: border-box;
	font-size: 3em;
	transition: .3s linear;
	color: white;
	padding: 15%;
	opacity: 0;

.multi-hover span:hover {
	opacity: 1;

.multi-hover span:nth-child(odd):hover {
	left: 0;
        z-index: 3;

.multi-hover span:nth-child(even):hover {
	top: 0;
        z-index: 3;

The odd and even declarations set each panel to the opposite side of the box, positioning them entirely over the image and completing the design. Note that this interface pattern requires exploratory mouse movement from the outside of the box inwards to activate each panel; alternately, a completely “in box” exploration model could be created by lowering the z-index of the :hover states to 1.

Accessibility Testing

Making the panels invisible brings up the issue of accessibility. Partially sighted users might be able to see and interact with the panels, but blind users obviously will not.

Screen readers treat such content as being truly “invisible” (leaving them, therefore, unread), depending on the context; content that is set to display: none is usually left unread, for example. However, opacity does not trigger this behavior. On a Mac, you can easily test this by activating VoiceOver and having it read the page we’ve created in the browser:

  • Command + F5 to start VoiceOver,
  • Control + Option + A to read Web page content,
  • Command + F5 to stop VoiceOver.

You’ll hear the span content being read in the order that it appears on the page; all that’s missing is a description of the image at the end:

<div class="multi-hover">
<span>Spiral Galaxy NGC 1309</span>
<span>Approximately 120 million light years from Earth</span>
<span>Home to several Cephid variable stars</span>
<span>Member of the Eridanus galactic cloud</span>
<img src="ngc-1309.jpg" alt="Photograph of NGC 1309">

Note that this only treats the visual aspects of accessibility. There are other important areas (cognitive, motor and language) that I will leave unaddressed in this example for the sake of space but that have been detailed by other Smashing Magazine authors12.

Adding Touch Support

The majority of mobile devices that depend on touch interfaces do not support a pure “hover” state: An element is either “in touch” or not. With rare exceptions, there is no registration of a fingertip being just above the screen of a mobile device. A brief touch might be interpreted as a hover event by mobile browsers, but this behavior is not perfectly predictable. As such, our interface will not work on most tablets or phones, at least as it currently exists.

To solve this issue, we’ll add a little JavaScript (by way of jQuery) to the page:

<script src="//">
function is_touch_device() {
  return !!('ontouchstart' in window)
      || !!('onmsgesturechange' in window);

$(document).ready(function() {
  if (is_touch_device()) {
    $('span').unbind('mousenter mouseleave touchend touchstart');
    $('span').bind('touchstart', function() {

The JavaScript applies a class of hover to any span element that is touched. So, we just need to alter our CSS declarations to make this class equivalent to the :hover event:

.multi-hover span:hover { opacity: 1; }
.multi-hover span:nth-child(odd):hover { left: 0; z-index: 3; }
.multi-hover span:nth-child(odd).hover { left: 0; z-index: 1; }
.multi-hover span:nth-child(even):hover { top: 0; z-index: 3; }
.multi-hover span:nth-child(even).hover { top: 0; z-index: 1; }

Note that in the mobile version, the extended panel goes “under” the level of those that are retracted, allowing them to be tapped.

Disengaging the copy controls on handheld devices might also be wise. This is not some futile pursuit of DRM, but a practical response to the fact that longer touch times on mobile devices can bring up copy prompts that could get in the way of the user interface:

.multi-hover span {
  -ms-touch-action: none;
  -webkit-touch-callout: none;
  -webkit-user-select: none;

This user interface pattern of exploration on a mobile device may now be described as “tap on edge.” This could be further enhanced by increasing the overlap of the original position of the span elements in an @media query to provide larger hotspots, making the panels easier to activate, along with further improvements for smartphones. This code is not the only way to achieve this effect either: Ana Tudor has written an alternative technique using CSS transforms and SASS13.


Crafting an element of surprise on Web pages can raise visitor engagement without obfuscating important content, sidelining mobile visitors or disadvantaging users who require accessibility features. Naturally, this must always be balanced with the need to guide users through the website: Visitors will only be surprised by the effects described here if they explore the page for themselves, or are led to it. How much users should be led and how much opportunity they should be given to discover a delight on their own initiative is a central question of user experience design.

(al) (ea)


  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13

↑ Back to topShare on Twitter

Dudley Storey has been making web pages for almost has long as there has been a web to create them on. A writer, designer and teacher of web development and 3D, he is the recent author of Pro CSS3 Animation.


Note: Our rating-system has caused errors, so it's disabled at the moment. It will be back the moment the problem has been resolved. We're very sorry. Happy Holidays!

  1. 1

    oh that reminds me, I really must write a book and then do a guest post somewhere to promote it.

  2. 2

    Thibaut de Hollain

    September 2, 2013 10:02 am

    I agree with Ian’s point. Hover effects should only make the overall experience more enjoyable, not bring new content.

    I have to say, I’ve been putting little effort in hover effects lately, because they don’t work on touch devices. I find it too frustrating to build a complex effect knowing that a substantial (and growing!) share of users won’t see any of it. But then I’m no professional so I have no contractual requirement to satisfy :)

  3. 3

    This raises some really nifty techniques, but as a UI element I think it’s not so great.

    If you use it without reading the article first (as I did) then it’s not really clear what’s going on. I hovered over it and a box came over but then when I tried to get it to do it again, I couldn’t. I didn’t know it had been activated by coming in from a certain direction.

    I know this is only a simple example, but there is a trend of ‘mystery hovering’ and I think it is dangerous. The emotion it is in danger of evoking is frustration! Elements must give some indication that they are ‘hover-able’.

    • 4

      Totally agree. This fails on a couple levels: mystery meat navigation and unknown content. I didn’t “get” it at all when I first used it. Designing for emotion is absolutely important but it needs to be done correctly.

      There definitely needs to be some kind of visual indication that you can hover in from all 4 sides to get to the different sides of content, otherwise it’s just another image on a page someone will overlook.

      And before anyone tries implementing this on their blog as “the new hotness” it probably goes without saying that it needs to be presented in the right context to use it. It might be a useful teaching tool, for example, but unless told otherwise, people scan web pages, not “play” with them so all that extra content will be for not.

      Lastly, while mobile devices are exploding, here we are still designing widgets for desktop/mouse users. How would this content work on mobile for example? If you can’t answer that question, the content is superfluous.

      • 5

        Hi Ian, and thanks for your comment.

        I do mention the delicate balance between leading the user to additional experiences and letting them explore for themselves. We’ve all seen (and are heartily sick of) “punch the monkey” interfaces and popups over every control.], so any indication has to be subtle (and is the primary reason I left it to the developer).

        While it is very true that people scan web pages, there’s also something to be said for providing extra richness for users who stay and explore. (One could make a similar argument that fussing over the transition on a control is superfluous, as it doesn’t directly affect the functionality and “users won’t care”… yet it’s those small touches that have shown to be deeply valued by users, if only at a subconscious level.)

        Lastly, while mobile devices are exploding, here we are still designing widgets for desktop/mouse users. How would this content work on mobile for example?

        Designing for touch and mobile is addressed at the end of the piece.

        • 6

          One could make a similar argument that fussing over the transition on a control is superfluous

          Not me! :-)

          Your details regarding mobile were great too, cheers. But on a touchscreen device I think that this ‘hidden’ content is even less likely to be discovered. Whilst a user may lazily drag their cursor across the screen, I think they are less likely to do so with a finger. But that last bit is just my opinion.

  4. 7

    I do like that effect and I can visualize some uses for that. I am wondering if would be intuitive if the scroll appeared from the middle rather from the outside. Say, for quick navigation to adjacent squares. Perhaps even a toggle so you could have a choice, i.e.inside/outside. Or rather than just having it as a square, it could have options for any number of sides. say a pentagon, hexagon or octagon.

  5. 8

    Like the effect. You can do stuff like:

    • 9

      Awesome example Blazoon. I think this should have been used in this article as an example. Unfortunately before seeing your comment this post seemed a) backwards in terms of usability b) does not seem to do much with the title and introduction.

      I don’t think one can claim that “exploring” is the reason to hide content. Easter eggs are nice, but this example seems like it has some useful information related to the image.

      I do like the solution that Dudley gives to trigger different effects from different hover directions though. Would not use it that way though.

  6. 10

    Thank you for being one of the few authors to actually include a detect for IE10+ touch support. People love to trash IE and ignore it, but the reality is many people will buy those devices and it’s bad form to give a segment of your users with current browsers a subpar experience.

  7. 11

    sorry to say but demo is not promising in matter of usability. User must not be familiar in case of hovering over the same box from four directions to get different results. Even hover effect doesn’t work at fast pace of mouseover(chrome). well you can make more usable demo with free of bug.

  8. 12

    The web has completely changed and now we are living the right time for anyone who can find new approaches that are able to convey emotions and not just information.

    Let’s break down this border and make it to another level.

  9. 13

    You mention in the article that you are not addressing people with physical and cognitive disabilities and do acknowledge screen readers. However, it doesn’t require much work to give keyboard users benefit of the animation.
    Add tabindex=”0″ to your spans to allow keyboard focus.

    I would also argue for using the Definition List in this example.

    Add :focus and :active rules wherever you mention :focus.
    .multi-hover span:nth-child(even):hover becomes
    .multi-hover span:nth-child(even):hover, .multi-hover span:nth-child(even):focus, .multi-hover span:nth-child(even):active

  10. 15

    What I do not understand is that you test for touch support with touchstart (webkit) and msgesturechange (IE) events but later only cater for touchstart but ignore IE which does not support touchstart. The demo works nicely on IE11 (have not IE10 touch device currently) due to its long press support for hover. But the code does not makes sense there.

  11. 16

    I enjoyed the intro of your post about how human being respond to emotional design and how animation and interactivity plays a great roll in it.
    I call it crafting a visual story for users.
    The “time” factor in any interactive and animated design, creates an anticipation.
    If we over do this anticipation we loose user but as you mentioned if use it correctly it will be so useful. I agree with some other folks about that above example has some issues in how user can or will “find” the hover. But the concept has potential. Blazoon example above is a good one.
    I enjoyed and learned from your post – Thanks!

  12. 17

    Alexander kazachkov

    February 12, 2014 2:32 pm

    Hi! I love the concept and the finished example.

    i only want to wait ’till I can do some of these things, too. :) Love it to see such nice examples of really deep understanding of code.

    Thanks for my words on this Website!!!!

    Alex to Smashing magazine readers!

  13. 18

    Please don’t teach bad jQuery techniques. Remember to cache selectors!

    You have:

    That’s two expensive DOM tree lookups. Save it to a variable!

    var span = $(‘span’);

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top