Grow your CSS skills. Land your dream job.

Uniqlo Stripe Hovers

Published by Chris Coyier

For the larger promotional boxes in the design of Uniqlo.com, they use animated stripes that reveal on hover. It's kind of awesome, if you ask me. Perhaps because they wanted to share the awesome with as many different browsers as possible, they used an animated GIF to produce the effect. It's fairly small at 4K, but as we know around here, it is also another HTTP request. Let's reproduce the effect in a progressive enhancement style: less browser support but more efficient.

Still image of the effect in action.

The HTML

We could do this with only the parent element, changing it's background to animated stripes on :hover. However, the stripes on Uniqlo fade in, they don't just instantly appear. Unfortunately for us, there is no such thing as background-opacity that we could transition to help us.

We could use the ::before pseudo element instead and use opacity to fade the whole thing in and out, but the support for transitions on pseudo elements is just only starting to get OK.

Just this once, let's use an additional element to handle our special background:

<div class="product">
  <div class="product-hover"></div>

  <!-- all the product information and stuff -->
</div>

The CSS

The .product will have some padding, which essentially reveals the big thick white border where the animated stripes will appear.

.product {
  background: white;
  padding: 20px;
  position: relative;
}

Then if we absolutely position our .product-hover to each corner, the background of it will show up in that 20px padding around the product. By default, we'll make the opacity 0 so it's not seen.

.product-hover {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
}

The Stripes

Now to create that "barber pole" animated stripe, we need to use a 45 degree linear gradient to create a repeatable square that ends up looking like stripes. Here's the code for that.

.product-hover {
  background-size: 30px 30px;
  background-image: linear-gradient(
    45deg, 
    rgba(black, 0.1)  25%, 
    transparent       25%, 
    transparent       50%, 
    rgba(black, 0.1)  50%, 
    rgba(black, 0.1)  75%, 
    transparent       75%, 
    transparent
  );  
}

There are also some diagonal stripes available at Lea Verou's pattern gallery. The code is a bit lighter as well, but don't allow the background to be white or transparent.

Here's how the gradient works:

That's all standard CSS except the "black" in the RGBa value, that's made possible through Sass.

That 30px ✕ 30px block is perfectly repeatable and will fill the .product-hover with stripes.

Revealing the Stripes

It's an element onto itself, so it's very easy:

.product:hover .product-hover {
  opacity: 1;
}

That's an instant-reveal though. To get the fade-in fade-out going, we set a CSS3 transition.

.product-hover {
  transition: opacity 0.3s ease;
}

Animating the Stripes

We need animation here (as opposed to transition), since we want the stripes to animate indefinitely.

Moving the background-position around on the .product-hover will change where our little 30px ✕ 30px box begins, and thus appear to be moving like a barber pole.

@keyframes barberpole {
  from { background-position: 0 0; }
  to   { background-position: 60px 30px; }
}

Then we set that animation on the element, having it move in a linear fashion (no easing) and repeat indefinitely:

.product-hover {
  animation: barberpole 0.5s linear infinite;
}

Demo

And done! Demo on CodePen:

Check out this Pen!

Comments

  1. Would be cool to use this approach to mimic the “marching ants” selection effect in Adobe Photoshop, too!

  2. Can’t you juzt use rgba() values in lieu of background-opacity?

    • For a solid color fill, yep. But we’re using a gradient here, in which individual values inside the gradient can’t be transitioned (I don’t think).

    • cnwtx
      Permalink to comment#

      I use rgba in gradients all the time! It works great for me. The only drawback is the syntax suddenly gets much longer.

    • The background gradient syntax for me is actually a single line:

      @include background(linear-gradient(black, gray));

      Sass does the rest.

      BTW, the above declaration block is from Compass‘s Background Image mixin.

  3. zzzzBov
    Permalink to comment#

    There’s no need for an additional element. All you need to do is animate the white bars, and transition the background from white to grey on hover.

    • Looks like you lose the fade-in fade-out though yeah?

    • zzzzBov
      Permalink to comment#

      I had the transition too abrupt. It’s fading in nicely for me in chrome now that I’ve bumped it up to 1s, but of course that could be tweaked.

  4. Nathan
    Permalink to comment#

    Impressive solution, but in the real world I think I’d go for the 4K request for broader support.

    • I very possibly would too, but the “real world” doesn’t automatically mean “go for the deepest browser support possible all the time.” I find it more reasonable to declare official browser targets and make decisions based off that. And even then, it depends on how vital you think different parts of this are. Is the stripe the most important part? Or the animation? Or would some kind of solid color fallback be OK? Perhaps a Modernizr based fallback is in order? Maybe 4k and a request is no big deal, or maybe it would push you past your performance budget and this way fits. It’s a complex world out there for front end devs!

  5. Permalink to comment#

    Nice job Chris! It’s always exciting to see what we can do with CSS without the help of images.

  6. Permalink to comment#

    I have seen this effect on your tutorial for first time…. It’s really cool man… Thanks you for such a hard work for US

  7. Several questions about positioning .product-hover to all four sides (left, top, right, bottom)

    A. What does that do?

    B. Any other examples one would use this “4-side-positioning” technique?

    Thanks.

    • It makes it the exact same size as the parent element, assuming the parent isn’t position: static; Common for stuff like full site overlays.

      I have found that top: 0; left: 0; width: 100%; height: 100%; is a bit “safer” – for instance, an iframe only works that way, won’t take right/bottom. But, if you aren’t using box-sizing: border-box; then you’re at risk for 100% turning into 100% + padding which is also a safety risk (trigging scrollbars).

    • Hmmm, interesting Chris.

      I created an extremely similar animated GIF for my website several years ago, and so:

      I went ahead and created a pen with this case/question, check it out: Making position:absolute; top:0; left:0; right:0; bottom:0; work.

      Notes:

      • I used rem units instead of px

      • I used Sass + Compass so you’ll see a couple of mixins (nothing fancy)

      • The ‘animated’ frame is always visible

      Let me know what you think.

      Thanks.

  8. Andrew Pham
    Permalink to comment#

    I have the same question as Ricardo. So you’re saying that if you set all the margins to 0px (with position and top/left/right/bottom, not with the margin property), the element will be “stretched” and become as wide and tall as the parent? I mean, it doesn’t even have a width or height in order for it to be shown. How does this technique work?

  9. Permalink to comment#

    Thanks Chris! I love this effect :) Using it now on my site (still in dev)

  10. Permalink to comment#

    Hi, why didn’t you used rgba(0,0,0,0.1) for the gradient?

    • Because Chris is using Sass to create his CSS file, so things like #000, or #000000, or rgb(0,0,0) can be accomplished just by declaring black, ie:

      rgba(0,0,0,.5) = rgba(black,.5)

      Quote from the article: “That’s all standard CSS except the “black” in the RGBa value, that’s made possible through Sass.”

  11. Nice trick Chris! I loved =)

  12. strages
    Permalink to comment#

    I once tried to solve a harder one, would like to see you give a try :)

    https://droplr.com/hello + drag a file over the dropzone

    the problem is they use a hack i don’t want to use… there should be a better way in order to be able to do this!

  13. Permalink to comment#

    FYI for those wondering this will only work in IE10. Chris also wrote another article on RGBa support here: RGBa Support. Great article, but will not work cross-browser and would need fallback for IE for those interested. That being said always great to learn something new! Cheers & thanks for the share.

  14. Permalink to comment#

    Nice work!

    The gif is actually 1.7k :) — but at that point the http request is more of an issue (somewhat mitigated for repeat visitors by a long expiry header). The IE9 support would probably be a dealbreaker but assuming the performance is as good or better on that page (there is a lot going on already), there could be an argument for browser-specific implementations.

    • Indeed it is!

      1,697 bytes (4 KB on disk)

      4KB must be the “minimum file size” on OS X or whatever.

    • It says 4 KB in Windows as well and, correct me if I’m wrong, but the 4 KB is the “allotted” space in the disk and not the actual file size.

      The file size IS indeed 1.697 bytes/1.65 KB

      :)

  15. Permalink to comment#

    Hi Chris, as the developer who implemented the original on uniqlo.com, I gotta say very nice work! Unfortunately Uniqlo requested that it had to work on more than just Webkit/FF.

    • Which I’m sure was a smart call! eCommerce is a classic example of where deep browser support is smart and easily justifiable.

  16. Hi, Chris. Nice tutorial! I actually never thought about something like. It looks nice a draws attention to the specific post/product.

    Thanks for the tutorial!

  17. Security alert!
    Permalink to comment#
  18. Alice Lieutier
    Permalink to comment#

    Nice trick, but I actually have a technique that is not using any other element than the image.

    It uses an inset white shadow that transition from white to transparent on hover.

    Here is a jsFiddle:

    http://jsfiddle.net/alicelieutier/RDq3a/

  19. Eric
    Permalink to comment#

    Really nice effect! Any way you could post the straight CSS instead of just SASS code? Mot everyone, especially newbies like myself are using CSS pre-processors yet…It would be much appreciated.

  20. Eric
    Permalink to comment#

    Oopps, sorry forgot to say that it’s not working when cut and pasted into an HTML file or split up into two files. sorry about the typos above too…

  21. Great tutorial chris, I would love to apply this on my product website. But i have a question, does this animation affect browser speed ?

    • This seems like spam to me, but heres’ my answer anyway.

      Anything affects browser speed, from the size of your CSS, HTML, JavaScript, images file(s), to the amount of markup, files being requested (HTTP requests), to the animations/transitions in your CSS files and images and their speeds.

      I left plenty of other things out to keep the answer short.

      But a good rule of thumb is: Use all these effects with care, remember “Is Always About the User Experience”.

    • @Ricardo Zea: Simply putting your website and a one line question, doesn’t make it spam :) As a web developer, I visit top designing websites on daily basis to learn new things and stuff.
      Thank you for your answer. I am agreed with you. User Experience always comes first.

  22. Nice tutorial! One thing: how does the repeating-linear-gradient() version in my patterns gallery “not allow the background to be white or transparent.”? Obviously you’d need to tweak the colors, but apart from that, I don’t see any issue.

    • You’re right, it’s fine. I was confused in my first look at it, because the way it’s set up it relies on a solid backgorund color and then the stripes are transparent white over that.

      background-color: gray;
      background-image: repeating-linear-gradient(45deg, transparent, transparent 35px, rgba(255,255,255,.5) 35px, rgba(255,255,255,.5) 70px);
      

      If you make the background white, nothing shows up. But as you say, you can tweak the colors to be solid colors instead of transparent. Perhaps a more simple example would be:

      background-image: repeating-linear-gradient(45deg, white, white 35px, red 35px, red 70px);
      

      http://dabblet.com/gist/5073506

      Ever so slightly less browser support for repeating gradients as well, but not enough to matter (http://caniuse.com/#search=gradient)

  23. Pretty cool effect!

  24. Really nice , I would like to have it as the market singe circling

  25. Pretty sweet!

  26. Wow, great work, love the code!

  27. Very nice, wish the CodePen was in straight CSS for those of us who haven’t decided to move to SASS/LESS/SCSS. Starting to get the feeling that us straight CSSers are getting the freeze out. :-)

    • @Chris C, as I mentioned to Eric above, if you go the example in Codepen, in the middle section, the CSS section, click on the top title where it says “CSS (SCSS)”, you will then see the Compiled CSS.

      OFFTOPIC–

      I was a ‘straight CSSer’ not too long ago and didn’t want to get left behind, so I had to jump on the CSS preprocessors wagon and today I can’t see myself writting CSS without Sass (and Compass and Bourbon and creating my own mixins and getting effin’ overwhelmed with all the stuff going on out there, oh boy).

  28. Eric
    Permalink to comment#

    This is for Ricardo,
    Thanks for the info. I’m still a vanilla CSSer and am just now learning pre-processors.

    • Chris
      Permalink to comment#

      Yes, Thanks Ricardo…didn’t realize that I could see it that way!

  29. Boris
    Permalink to comment#

    If main concern is one more HTTP request, data URI technique can be used.
    It increases the size a little bit (instead of 1.7 kb it is 2.3kb), but it is more browser compatible.

    • Permalink to comment#

      It’s not the main concern, it just becomes more of an issue than the file size. The data URI is an interesting thought that I like in theory (especially for fonts) but have yet to find practical on a large production site when you factor in browser support, maintenance, etc. Ultimately in this case, I think the way to go is Chris’ solution for the browsers that support it and the existing code for the rest. We’ll see if it makes it into the site :)

    • Boris
      Permalink to comment#

      Well it is not that hard to maintain and support all browsers when you have easy syntax.
      Here is an example with fallback to image for IE6 and IE7:

      
      .image1 { 
         background-image: url("data:image/gif;base64,[raw data here]"); 
         *background-image: url("barberpole.gif"); /* IE 6 and 7 */ 
      }
      

      Use this with SASS’s or LESS’s inline-image() function and you have the complete solution.

  30. Permalink to comment#

    Just awesome. Getting on the bandwagon!

  31. Nick
    Permalink to comment#

    Seems incredibly more intelligent to just use an animated gif.

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".