Grow your CSS skills. Land your dream job.

iPhone “slide to unlock” Text in WebKit/CSS3

Published by Chris Coyier

There are a couple of WebKit specific properties that make giving text a gradient background possible:

-webkit-background-clip: text;
-webkit-text-fill-color: transparent;

Those will allow the background of the parent element to become the background of the text inside. I gots to thinkin', if we made a made a horizontal gradient that faded in a gray-white-gray pattern, then animated it from left to right, we could make the iPhone/iPad's "slide to unlock" screen with no images at all!

WebKit only demo:

View Demo   Download Files

Gradient Structure

The text "slide to unlock" is an h2 tag. We'll be giving it the gradient background, which is structured like this, with 5 "color-stops":

   -webkit-gradient(linear,left top,right top,
        color-stop(0, #4d4d4d),
        color-stop(0.4, #4d4d4d),
        color-stop(0.5, white),
        color-stop(0.6, #4d4d4d),
        color-stop(1, #4d4d4d)); 

With the two properties from the beginning of this article, the text gets a highlight like this:

Notice that the width of the background is twice as wide as area. This gives us some gray to work with on either side of the highlight, so the white highlight part can slide by and the text can stay gray before and after. If we were to animate the background further left or right than what is available, the text goes black (bad).

The next step is to animate the position of that background from left to right.

The h2 tag sits within a "well" which takes care of getting us the black background behind the text (since we've stolen the background from the h2 itself). This controls the width of the h2 as well, since it defaults to 100% wide as a block-level element. The well has a fixed width. Then the h2 is double that width (200%). So our animation can start at negative the width of the well and end at positive the width of the well.

#well {
   width: 720px;

h2 {
   width: 200%;
  -webkit-animation: slidetounlock 5s infinite;

@-webkit-keyframes slidetounlock {
  0% {
    background-position: -720px 0;
    background-position: 720px 0;

Yay! Animated highlight on the text! Here it all is together:

#well {
  padding: 14px 20px 20px 20px;
  -webkit-border-radius: 30px;
  background: -webkit-gradient(linear,left top,left bottom,color-stop(0, #010101),color-stop(1, #181818));
  border: 2px solid #454545; 
  overflow: hidden; 

h2 {
  font-size: 80px;
  background: -webkit-gradient(linear,left top,right top,color-stop(0, #4d4d4d),color-stop(0.4, #4d4d4d),color-stop(0.5, white),color-stop(0.6, #4d4d4d),color-stop(1, #4d4d4d)); 
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  -webkit-animation: slidetounlock 5s infinite;
  font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
  font-weight: 300;
  padding: 0;
  width: 200%;

@-webkit-keyframes slidetounlock {
  0% {
    background-position: -720px 0;
  100% {
    background-position: 720px 0;

Bonus: The unlocky thing in jQuery

To me, this was mostly about replicating the cool text effect without any images. Done and done. But hey we might as well tackle the sliding unlock part too eh? The little slider button with the arrow on it probably could be accomplished with pure CSS (using triangles, among other things. But, let's not go there today. The slider will remain an image, and go right inside the h2 itself.

<h2><img src="images/arrow.png" alt="slider" /> slide to unlock</h2>

We'll load up jQuery, jQuery UI, and our own custom script:

<script src=''></script>
<script src=""></script>
<script src='js/slidetounlock.js'></script>

We'll use the jQuery UI draggable function on the image. We'll restrict it's movement to the X-axis (horizontal). Like all good jQuery UI functions, this has callbacks. We'll attach one to the drag event which fires repeatedly as the element is dragged. With that, we'll test if it has made it far enough to be considered "unlocked." If it has, we'll fire off an action. In this case, fading out the well. For the "stop" callback, fired when the mouse button is released, we'll test if the element is under the our completion distance and snap it back to the left if not.

$(function() {
	$("h2 img").draggable({
		axis: 'x',
		containment: 'parent',
		drag: function(event, ui) {
			if (ui.position.left > 550) {
		stop: function(event, ui) {
			if (ui.position.left < 551) {
					left: 0

I tried to make the drag event also dim the opacity of the text as you slide it, like the iPhone/iPad, but it's seeming to me like WebKit isn't allowing partial opacity on text with background clip. Didn't do a ton of research, but I do know that wrapping the text in a span and trying to adjust the opacity of that span just wouldn't take (until it was zero).


  • Marco Kuiper has tackled this before as well, but with a different approach (animated GIF).
  • The code above is for desktop web browsers only, and won't work on mobile browsers. Evan Black took this example and added JavaScript touch events to it, making it work in Mobile Safari. I snagged his code and dropped in in the live example on this site, the only alternations being a little jQuerification
  • .


  1. Alex V.
    Permalink to comment#

    Thank you for this post, Chris. The text gradient animation can be implemtented in so many different, fun ways. Too bad that, this only can be run on WebKit. :(

  2. You should add an

    scroll: false

    because of dragging the button out of the box :)


  3. Permalink to comment#

    thanks chris, I think Firefox is falling behind. it’s embarrassing…

  4. Permalink to comment#

    This is a cool technique. But on my iPhone, trying to drag the slider just moves the page around… That being said, you did say the point was to demo the animated text-gradient effect which most definitely looks cool.

    • Yeah the slide to unlock thing isn’t going to work on Mobile Safari. Mobile Safari doesn’t have click-and-drag like capabilities yet. If you wanted to use this in an iPhone app, you’d build it in interface builder.

      The real meat of this demo though is the moving highlight / gradient text, which does work in Mobile Safari.

    • You can use the DOM Touch events to do it. Unfortunately, this isn’t supported in the Draggable plugin.

    • I’ve just written an article about how to accomplish this using the DOM Touch events. Check it out in Mobile Safari(ipad, iphone or ipod touch) and let me know what you think.

  5. David Becker
    Permalink to comment#

    Well done. Looks great Chris.

  6. Permalink to comment#

    Wooow great trick

  7. Permalink to comment#

    Yet another great example of CSS, well done Chris! The name “CSS-Tricks” now truly has more CSS meaning to is ;).

    Thanks for linking to my article BTW, really appreciate it! Just one thing: It’s Marco Kuiper, not “Kupier” ;) .

  8. Permalink to comment#

    Uber killer ! Thanks ! Very nicely done.

  9. Patoche
    Permalink to comment#

    Where’s the “Like” button? :)
    Good job!

  10. Ergo
    Permalink to comment#

    It should fade out as you scroll.
    At least this happens on the iPhone.

  11. Permalink to comment#

    great work chris, now all you need is a home button, some graphics, an emulator. and we can all save a few hundred bucks when our touches and iphones break ^(^-^)^

  12. Thanks Chris but why is it disappearing when you drag the button out of the box?

    • That just signifies “some action”. You could make that part of the JavaScript do anything you want. It’s just a demo =)

  13. Astha
    Permalink to comment#

    Sweet! How do I make it load a page via AJAX or jQuery after it slides?

    • Check under the “stop” callback in the JavaScript. You’d put anything you want to fire after the unlocking in there where the current code is that fades out the #well

  14. Awwwsome job Chris!

    As a side note, homepage looks weird on the bottom-right…

    Keep up!

  15. Permalink to comment#

    Big fan of the site and the work you do, and no offense, but as a personal opinion the new site design is a step down. You are a rare talent in our field and I say that with the utmost respect. Some nice effects code-wise, but design-wise you can do better.

    • I think you are having an emotional reaction to it being “new.” Regardless, this isn’t the appropriate venue. I’ll be posting about it next week and you can give your feedback on that post if you like. Tangible evidence required (e.g. “step down” isn’t helpful)

    • Permalink to comment#

      I agree, not the right venue, but you posted the update without a setup. I would be happy to discuss about aesthetics and UI choices. I am a professional as you are, I’m not here to degrade you or your work. Like I said I have the utmost respect for the work you do and if I could accomplish half of what you have I would be content. So please don’t take that the wrong way.

  16. Permalink to comment#

    damn, this is sweet. and your site new look, is more than awesome.

  17. ssbdboy
    Permalink to comment#

    Chris, Your site is perfect!! Only thing sucks is the header text! It hurts my eyes!

  18. Very cool. I’m just trying to think of a practical implementation for this. Any ideas?

  19. Permalink to comment#

    That is sweet! Thank you.

  20. Permalink to comment#

    Chris, I don’t like the new design. At all.

  21. Permalink to comment#

    nice Chris

    why did you load 2 jQuery scripts ?
    is jquery-ui.js necessary ?

    • Yep, jQuery UI is used for the “draggable” component. If this was a production site, you’d download just only the components of jQuery UI that you need (instead of the entire package) to save bandwidth. But this is just a demo…

  22. Lenny
    Permalink to comment#

    It’s absolutely possible to get this to work on an iPhone. The site (view it from your iDevice) does it fantastically.

  23. Permalink to comment#

    Chris, it’s offtopic, but, in footer, when i move my mouse over those social buttons or “I work for…”, etc. the sidebar is blinking. It’s kinda annoying (also, those social buttons are blinking).

    Is it bug or you wanted this effect?

    Working on Safari 5, Mac.

    • alex
      Permalink to comment#

      I also get this, but it appears all of the ‘about the author’ text font-weight changes, the social buttons flicker, and the whole right sidebar flickers different colours. But I think it was designed for either Safari or Chrome, because of the excellent ‘props’ sorta cardflip effect!

      Back to topic, I think this is by far the best I’ve seen, but..
      – When slid on the iPhone, the text animation stops, as well as it steadily fading out.
      -It would be nice if that rather than ‘stopping’ and fading out the whole thing the whole thing when the slider exceeds the container, maybe it could just stop? and only fade out after you release it.

      Sorry for being fussy ;D

    • There is a new post today about Design v7, please leave notes specific to the design there!

  24. This is a cool technique.Thank you very much.

  25. Permalink to comment#


  26. Permalink to comment#

    Also works in Android 2.2’s default browser. ;)

  27. Daniel
    Permalink to comment#

    Does the downloadable version include to updated touch event???

  28. Jay Blanchard
    Permalink to comment#

    Can this be done cross-browser since IE doesn’t support webkit?

  29. Wonderful article, it could use to be before admin panel login screen as example ;-)

  30. Anantharaj
    Permalink to comment#

    not able to use with jquery mobile
    is there any solution ..?

  31. Permalink to comment#

    This is awesome. Im going to try and use it to open the login screen on our Employee Portal! The only downside I see is most of our employees use iPhones when not on a computer. I saw in a previous comment it can be tricky to use.

This comment thread is closed. If you have important information to share, you can always contact me.

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