Everything in the tutorial is exactly as it was on my site at the time of writing. However, this is no longer the case. Over the weekend I got a tweet from William Flake indicating a modification he made to the code to prevent a “jump” that occurred when you first moved the mouse into the header. I liked his alterations so much that I’ve made use of them in my code.
This week William wrote about his code alterations over at his site Unfinished Thoughts in a post entitled Of Squirrels and Men. If you enjoyed my parallax code, please take a look at what changes he made. They’re definitely worth a gander.
]]>I LOVE your header background, how on earth did you do that?
The very short answer is: with JavaScript and CSS.
Of course, that’s not a very satisfying response, so I’ll go ahead and expound a bit more. I did it in three steps. First, creating the right group of images. Secondly, with some simple CSS and HTML. Lastly, with a surprisingly short JS script.
The first step for parallax scrolling, in any application, is having multiple layers of images to scroll at different speeds, with each layer representing another part of the passing landscape. In the case of this site, I’ve got four: clouds, mountains, hills, and forest. By themselves, neither layer looks terribly interesting.




They’ll have to be stacked over each other, so in order to be seen through one another they need to have transparency. This is why I used PNGs (although depending on the type of art you use, GIFs are fine).
Next, the images will have to be stacked over each other. I made four empty divs which I put in the header/branding div as follows:
<div id="cloudLayer" > </div> <div id="mountainLayer" > </div> <div id="hillLayer" > </div> <div id="forestLayer"> </div>
Although I’m not normally a fan of non-semantic divs, for this special effect I need something to hang the imagery upon. These four divs will be what we need for the CSS:
div#cloudLayer, div#mountainLayer, div#hillLayer, div#forestLayer { height:200px; position:absolute; text-indent:-9999em; width:100%; } div#cloudLayer { background:transparent url(images/clouds.png) repeat-x scroll left top; opacity:0.6; } div#mountainLayer { background:transparent url(images/mountains.png) repeat-x scroll left top; } div#hillLayer { background:transparent url(images/hills.png) repeat-x scroll left top; } div#forestLayer { background:transparent url(images/forest.png) repeat-x scroll left top; }
So each div is set at the same height, as wide as the parent element (the header), and absolutely positioned so they all overlap. Each background image is set appropriately to repeat horizontally along the layer it is within. If nothing further was done, this would be a complicated way to create a repeating landscape background. Only one small bit is left to make it scroll.
I love jQuery. It’s a convenient, compact JS library that makes cross-browser coding easy and compact. You could probably do this script without it, but by necessity it’d be a lot larger. Here’s the part of my script that controls the scrolling:
$('#branding').mousemove(function(e) {
mouseX = e.clientX;
$('#cloudLayer').css('background-position', Math.floor(mouseX / 4) + 'px 0');
$('#mountainLayer').css('background-position', Math.floor(mouseX / 3) + 'px 0');
$('#hillLayer').css('background-position', Math.floor(mouseX / 2) + 'px 0');
$('#forestLayer').css('background-position', mouseX + 'px 0');
});
I want the scrolling to only occur when the mouse is over the header, which is a div I call branding. So I’ve bound the .mousemove() event handling function to that div. I get the x-coordinate of the mouse when that even fires (anytime the mouse moves) and then adjust the background image positioning on the layer divs accordingly.
If I moved each layer’s background image by the same amount, the image would scroll all at once, and there’d be no parallax effect. Therefore, I instead divide the x-coordinate by a different amount for three of the four layers, moving each background image an increasingly smaller amount for the “far” layers.
The finished result is visible in the header above!
As always, if you have any comments or questions, feel free to share.
]]>I’m working on a side-project that has multiple instances of the same object (or the equivalent in JS) that makes use of jQuery’s .animate function. At the end of the animate function I want to use .animate‘s callback function option to loop the function in each object (allowing each to loop through a frame-by-frame animation of its own, for example).
The problem is I’m running into an obstacle, which can be illustrated by this simplified looping example. In this particular case, when you click on the button, it creates an instance of the object, sets a value inside it, then calls an internal function which displays an alert box, then calls a (in this case pointless) jQuery .animate function which contains a callback function to loop the instance’s function. The idea would be that I can call multiple instances of the object, and have each assigned their own values and then they’ll loop happily on their own.
That’s not happening, of course.
If you examine the JS source code (linked here) you’ll see that I use function(){this:greet();} as my callback parameter. My understanding was that this would correctly relaunch the function of the instance. It does not, however, work as I desire (aka, at all).
I know that this is an odd thing, so I’m sure I’m hamfistedly trying to pound a square peg in a round hole. The trouble is that I have absolutely no clue what the round peg is.
What I really need is a Master Po to tell me where I’m going horribly wrong here. Can anyone be my blind kung fu mentor?
]]>
As plenty know, Lightbox is a convenient and quick solution to providing a slightly glossy gallery effect for a page of photos or artwork. I personally prefer jQuery Lightbox, mainly because I’m a jQuery addict, but there is a slight issue with it being used in sites that have a fixed width on the body element (which I try not to do myself, since who knows what the end-users monitor is going to be like, but for client sites I don’t always have that freedom).
The issue is illustrated in this example here: the dark-background overlay that appears to cover the page doesn’t go past the margin of the body, leaving distracting bright gutters that ruin the desired effect.
In cases where you need (for whatever reason) a fixed body width, the solution here for jQuery Lightbox is fairly straightforward, but involves a wee bit of modification to the jquery.lightbox.js file’s code.
Inside the file, find the _set_interface() function and look for this segment of code:
$('#jquery-overlay').css({
backgroundColor: settings.overlayBgColor,
opacity: settings.overlayOpacity,
width: arrPageSizes[0],
height: arrPageSizes[1]
}).fadeIn();
We need to change it to the following:
$('#jquery-overlay').css({
backgroundColor: settings.overlayBgColor,
opacity: settings.overlayOpacity,
width: $(window).width(),
height: arrPageSizes[1],
left: -(($(window).width() - $('body').width()) / 2)
}).fadeIn();
Why is this? Let’s focus on the changes.
The width has been changed to $(window).width() so it actually gets the width of the browser window, and not just the body element, across all browsers (the provided value only provides the body element width in IE, Webkit, and Opera). Without this, the overlay won’t get wide enough to cover everything up.
The new value, left, gives the css style that will position the overleft to the left side of the screen by subtracting the difference of the browser’s width and the body’s width. This will allow it to work for all browser sizes.
Lastly, we need to put overflow: visible on the body element in our CSS. With this, we can see the overlay when it goes outside the body’s borders.
With these tiny changes in effect, check out the new result here. Much better, isn’t it?
]]>What is Cufon? Cufon is a plugin-free, Javascript-powered alternative to rich font embedding. In particular, it’s a great alternative to flash-powered sIFR, which prior to Cufon was the best way to get rich font support during our long desert of poor font-embedding support that is the modern web.
By “great alternative”, I mean that it “lights sIFR on fire, kicks it into an open sewer, and laughs maniacally as sIFR rolls around in stinky, burning pain.”
Yes, it’s that much better. And if you don’t agree, I’ll punch you.
Ok, that’s not true. I’m opposed to violence. I also never learned how to throw a punch, and I’m worried that I’d break my thumb.
However, it is better. For three major reasons. 1. It doesn’t require you to own Flash to build the font file you’ll be using. 2. It doesn’t require a plugin in your browser to work (aka, it works on iPhones among other things). Lastly, 3. It’s way, way faster.
It’s things like Cufon that convince me that in the near future that Javascript will be the new Flash. (canvas and SVG make my pants tight in an embarrassing way.)
How does Cufon work? Simple.
1. Visit their site. Download the cufon script. Include that in the head of your page.
2. Get a font, and using their nifty generator, turn it into a .js file. (Supports several standards, including OTF and TTF.) Link that font script in the head of your page after the cufon script.
3. Do an air guitar riff. (Optional.)
4. In a script you add, include a command to the effect of Cufon.replace(“elem”) where elem is the element you want the font to replace. If you’re only using one font with Cufon, it’s as easy as that. If you’re using multiple fonts, you’ll need to do Cufon.replace(“elem”, “font name”), where “font name” is the name of the font you want that element to use for that element.
5. Look on in awe as the font are replaced so fast, your page will go slightly back in time.
An example of a finished result is right here. It’s simple, but it gets the point across.
Like sIFR, I can’t recommend using the font replacement on large fields of text. Selecting the text for copy/paste purposes is difficult (although not impossible), and it’s bound to have an impact on performance if you use it too widely. But selectively used it can open your projects open to a cornucopia of fonts (licenses allowing.)
What are you waiting for? Go get it now!
]]>The situation: I’ve got an empty imagemap that I want to dynamically enter area tags into with jQuery. I’ve been trying to insert them using .append() or even .html() and every time I attempt to do so nothing occurs. I can insert text or other tags, but no actual area tags.
Now, if I go oldschool and use document.getElementById(insertnamehere).innerHTML = “inserttagshere” that works. But every variation I can think of to use jQuery methods to add an area tag fails.
Can anyone think of anything obvious that I’m missing here?
]]>“I’m absolutely going to use it and recommend its use far and wide.”
Sounds pretty excited to me. What is all this enthusiasm being caused by? What is Sizzle?
I’m still catching up on the details as I write this, but in essence it’s a JavaScript project that will take advanced CSS selectors (read that, CSS3 selectors with little to no current browser support), do some work behind the mysterious veil, and then spit out the results on the browser. Any browser.
As a designer all you’d have to do is write your stylesheets with these new selectors (and possibly new properties like multiple-backgrounds, although I’m still confirming that), and let JS do the rest.
This is hot. It’s taking all the work that has been put into making JS engines these days smokingly hot, and converting that effort into some benefit for CSS, which isn’t getting the same fast-track treatment we’ve been desiring. I goofed around with a similar concept with a pseudo-class to class CSS converter called Pseudonut, but this is a whole other beast, and I’m really looking forward to it.
]]>I don’t know if this is a problem in other libraries, but I suspect it is. But I do know that it’s happened to me when using jQuery’s Ajax functions.
Why is this occurring?
I was tormenting myself with this same question on a client project, and discovered that although a bit of browser quirkiness was involved, it was actually an error on my part.
I hate it when it’s me. ;)
As it turns out, I had an extra trailing comma at the end of the last element in my array. For example, in the following array:
{“gamesImDroolingFor”:[{"developer":"Blizzard","title:"Diablo III"},{"developer":"Square Enix","title":"Final Fantasy XIII"},]}
You’ll notice that there’s a comma after the last game’s bracket (which has been turned red for emphasis).
Firefox will ignore that comma, since clearly there’s no new object after it. Internet Explorer, the special child of the web, isn’t quite so bright, so it adds an extra, blank element to the array it creates.
Go IE.
The solution is easy, of course. Remove the unneeded comma.
I hope this helps prevent other developers from driving themselves batty trying to figure out what’s going wrong with their own arrays.
]]>Then I discovered to my total shock that IE7 actually does support CSS3 attribute selectors.
Someone should tell Sitepoint this, as their reference incorrectly states that it does not.
However, IE6 doesn’t support ANY attribute selectors, so I went to the blackboard again to write a script for that.
Then I discovered that Dean Edwards’ IE7 script does give IE6 attribute support. So I stopped writing my own script and went to check that out.
A while later, I discovered that the Dean Edwards script, however, does not give full support to IE6 for css3 attribute selectors. (Most notably, *= doesn’t seem to work).
So now I’m working on that script again.
I think I’m beginning to understand what a yo-yo feels like.
]]>Fortunately for me, I spend at least a little of that time doing other things, like actually working on previously mentioned web design solutions. One area of interest that I’ve been getting more and more obsessed with is using Javascript to allow cross-browser CSS3 functionality on modern browsers, despite the fact that short of Konquerer, (which really annoys me because of the ‘cool’ spelling of a word with the letter K) browsers probably won’t be doing a lot of note with CSS3 until sometime after global warming causes the seas to rise and dolphins enslave humanity.
As much as I look forward to designing amazing tuna-oriented websites under the strict guidance of our future dolphin overlords, I’m not realy interested in waiting any longer to get my hands on all the cool features of CSS3 that have been “on the horizon” for half a decade now. I’ve talked about this lack of patience before, discussing the ability to use CSS3′s multi-column features today with Cédric Savarese’s css3-multi-column.js (which I offered a slightly altered version of here) and adding some CSS3-like pseudo-class mimicking support with Alex Bischoff‘s Offspring.js (introduce in a List Apart’s article Keeping Your Elements’ Kids in Line with Offspring, which I talk about here).
At some point, while I was sitting in Andy Clarke’s workshop at Web Directions North 2008 and dreamily drawing sketches of everyone’s favorite CSS rockstar, Andy talked about how it’s important to make use of cutting edge CSS features as often as possible to bring the browser makers’ attention to the fact that there is demand for support of these features. I think he was pushing in the right direction, but I think it’s not just enough to use modern browser support. I think people like Cédric and Alex are making strides in the right territory, which is using Javascript to implement CSS3 today.
Realizing it’d be a bunch of noise to just preach it without practicing, I’ve thrown my hat into the ring. My Javascript is a lot less practiced than my CSS, so I’m not exactly rocketing to the top with a killer script. However, they’re not nonexistent either, so I’ve put my nose to the grindstone.
The first challenge I decided to tackle was to fix an issue that I have with offspring.js. The script does a great (some might say overly thorough) job with adding classes to each element on the page so that they can be targeted with “pseudo-class”-like classes such as “.first-child”, “.last-child”, and “.nth-child” (it only currently supports the “odd”, “even”, and “#” values for nth-child). But to use these, you have to mark your CSS up with classes (such as “.last-child”) instead of pseudo-classes (such as “:last-child”). This is all great and dandy while modern browsers don’t have up-to-date CSS3 support. But as soon as they do (which, considering IE’s pace of advancement will be somewhere near 2020) you’d have to go through all your stylesheets and convert the styles to the proper pseudo-classes.
Not anymore. Let me introduce you to Pseudonut, a small script that goes through your stylesheets, checks for CSS3 pseudo-class selectors (currently only last-child, first-child, only-child, and nth-child) and then updates the stylesheets with new rules using classes instead. This means that you can drop the script into a project, use the supported CSS3 pseudo-classes, and it’ll convert them to a format for use with Offspring or any similar script you have.
Although it was my hope to use Javascript’s document.styleSheets.cssRules to read the existing selectors, strip out the pseudo-classes, and then replace them with classes, I ran into a major hurdle right away. Namely, most of the browsers wouldn’t actually read the pseudo-class marked selectors, as they’d see a style that held something they didn’t understand and therefore not add it to the list of cssRules. So instead I’m loading the stylesheets with XMLHttpRequest, splitting it into an array of strings holding the selectors and styles, making the changes from pseudo-class to class, then using javascript’s document.styleSheets.insertRule (or addRule if the viewer is using IE, since it has to be a special snowflake) to add the updated rule.
Here’s an example of it in work (I recommend checking out the stylesheets and html in Firebug). I’m using Offspring.js for adding the proper classes to the HTML, but you could use any script of your own for that feature.
Here’s the Javascript file: pseudonut.js.
Here’s the CSS file for that test: pseudonut.css.
Before I get reamed by Javascript experts for the cleanliness of the code (or lack thereof), I’d like to advise that this is what I’m calling version 0.1. It’s raw, it’s new, and it’s going to need a lot of polish. In particular I’m already thinking I should have loaded all the different pseudo-classes into an array of strings instead of checking for each separately. This is just the tip of the iceberg, though. Here’s a list of upgrades I plan for the project.
Pseudonut is filling its initial purpose, which is to allow me to keep my stylesheets “clean” while still being able to make use of the features offered by Offspring and other such scripts. Going forward, I’m definitely open to suggestions or comments regarding whether such a thing is needed, and if so, what kind of changes or direction should occur.
Oh, and for those of you who are too young to have experienced Ferris Bueller’s Day Off, go watch it, if for no other reason than to be grateful that women don’t use as much hairspray today.
]]>