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:
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”:
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));
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;
}
100%{
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='//ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js'></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js"></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) {
$("#well").fadeOut();
}
},
stop: function(event, ui) {
if (ui.position.left < 551) {
$(this).animate({
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).
Notes
- 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
.
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. :(
But it does not work! I see but I can’t slide. Using iOS 4 on iPhone.
You should add an
scroll: false
because of dragging the button out of the box :)
#dom
Are you seeing a scrollbar get triggered?
thanks chris, I think Firefox is falling behind. it’s embarrassing…
Why? It worked in Firefox 4? =)…awesome stuff though
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.
Well done. Looks great Chris.
Cool article, Chris. you’ve been on fire recently.
For the semi-transparent text, you can use
-webkit-text-fill-color: rgba(0,0,0,.5);
That could work… and then make the gradient behind the text go from transparent to white instead, and not worry as much about the extra length for coverage.
Wooow great trick
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” ;) .
Doh!~ Sorry Marco, fixed your last name.
Uber killer ! Thanks ! Very nicely done.
Where’s the “Like” button? :)
Good job!
It should fade out as you scroll.
At least this happens on the iPhone.
This is mentioned in the article. If you can find a way to do it, I’ll add it. Seems so far like a limitation of WebKit.
I don’t see why it can’t be done if you keep the text in its own <h2> tag and adjust its opacity via $.animate. The alignment might be off though.
Awesome. That works fine. For some reason I was trying to put the text in a span and animate the opacity of the span and it wouldn’t take.
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 ^(^-^)^
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 =)
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
Awwwsome job Chris!
As a side note, css-tricks.com homepage looks weird on the bottom-right…
Keep up!
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)
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.
damn, this is sweet. and your site new look, is more than awesome.
Chris, Your site is perfect!! Only thing sucks is the header text! It hurts my eyes!
Very cool. I’m just trying to think of a practical implementation for this. Any ideas?
Similar implementation here: http://www.thebcard.com/TM96
Probably to protect against bots, no idea if it works thought…
Ah yeah I hadn’t thought of that. I saw a little while back a form where sliding a bar like this was also used as a CAPTCHA-like device for preventing spam on forms.
That is sweet! Thank you.
Chris, I don’t like the new design. At all.
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…
It’s absolutely possible to get this to work on an iPhone. The http://jailbreakme.com site (view it from your iDevice) does it fantastically.
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.
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!
This is a cool technique.Thank you very much.
AMAZING!
Also works in Android 2.2’s default browser. ;)
Does the downloadable version include to updated touch event???
Can this be done cross-browser since IE doesn’t support webkit?
Wonderful article, it could use to be before admin panel login screen as example ;-)
not able to use with jquery mobile
is there any solution ..?
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.