Now that plain old HTML, CSS and JavaScript have made the web quite sophisticated, Flash isn't really as necessary as it once was. Nonetheless, I still see Flash being used to make things, well, flashy. Flash is often used just to add a touch of animation, like things moving around when the user moves their mouse, and other simple effects.
Well many, if not all, of these kinds of effects can be achieved with plain old CSS and JavaScript, thanks to animated GIFs. Yes, those awful animated GIFs. Just like JavaScript was until recently, animated GIFs are associated with the ugly web of the past (think dancing hamsters). However, if used carefully, animated GIFs can be used to make a web site very lively and feel more interactive in the same way Flash is used.
To demonstrate this, I've put together probably the most boring proof-of-concept ever. You'll have to use your imagination to see how this technique can be applied in much more creative and better-looking ways.
First, I created a simple animated GIF of a white bar moving left to right over a transparent background. I actually used Flash to create this. In fact, you could take a Flash interface, and publish the different pieces to animated GIFs in order to eliminate the need to use Flash. Anyway, here is my boring GIF on a black background, so that you can see what's happening:

Now, I'm going to use this together with CSS to create an animating hover effect. Here is the CSS and HTML I will use:
<style type="text/css">
/* IE 6 needs a:hover to be defined */
a:hover { width: auto }
a.shine:hover span {
/* don't take up space, and appear above the text */
position: absolute;
display: block;
/* set the background to the animated GIF */
background: url(shine.gif);
/* the width and height of the animated GIF */
width: 230px;
height: 50px;
}
</style>
<a href="/blog/cat/javascript" class="shine">
<span></span>
JavaScript
</a>
I'm using an empty span inside the link to act as a placeholder for the animated GIF. When the mouse is hovering over the link, the span comes to life by expanding to an animated GIF which appears above the text. Since the background of the GIF is transparent, and the background of the text is white, the effect is that of a "shine" washing over the text.
Click here to see the code in action.
And there you have it. Yes, I know, my demo is boring. But you have to use your imagination to think of all the amazing things you can do by combining animated GIFs with CSS and even JavaScript effects. You can do something as simple as an animated roll-over image, or as complex as an interactive game. The possibilities are only limited by your ability to design them.
Did you know you can use <a> by itself without href, name, id or any other attributes?
The W3C says this in the HTML 4 specs:
Authors may also create an A element that specifies no anchors, i.e., that doesn't specify href, name, or id. Values for these attributes may be set at a later time through scripts.
Weird, eh? How often do the HTML specs talk about putting elements in for scripting purposes? I had assumed never.
So why would you want to use an empty <a>? I don't think it's so practical for scripting purposes, because it'd be better to dynamically add a link using scripting. But it does make sense from a styling point of view.
If you are using a list of links for a navigation or tabs or something, you probably don't want the active link/tab to be clickable. This can confuse users, because they may think that this link/tab goes somewhere else, when really it just points at the current page.
Normally to approach this, I would just remove the <a> from the <li>. But my CSS relied on there being a link there in order to set a background on it. So instead I just removed the href and used an 'active' class like this:
<ul class="nav">
<li><a href="/">Home</a></li>
<li class="active"><a>Page 1</a></li>
<li><a href="/page2">Page 2</a></li>
</ul>
<style type="text/css">
.nav li {
list-style: none;
float: left;
/* put a repeated background image on the list item */
background-image: url(nav_background.gif);
}
.nav li a {
display: block;
height: 25px;
padding: 0 15px;
/* put a separator image on the right of each link */
background: url(nav_separator.gif) top right no-repeat;
}
.nav li.active {
background-image: url(nav_background_active.gif);
}
</style>
Now the separator image nav_separator.gif is still used on the empty <a>.
Most browsers will render the link differently, like removing the underline and colouring it different. They seem to treat it as if it's just a <span>.
You might argue that this uses unnecessary markup for purely display purposes. I'd argue that it's better to have a link that can't go anywhere than a link with an href that still goes nowhere.
There are probably other ways to take advantage of this. I'd love to hear any other ways that you think this might be useful.
If you're revisiting the site, then I'm sure you've noticed the new design. If you're reading over RSS, well, then you'll have to pop over and check it out.
I got bored last night, started sketching out what a logo might look like for The Future of the Web, and ended up sketching a whole new site layout to match it. Then I painted it in Paint.NET, was surprised how much I liked it, and spent the rest of the night wrestling with CSS until it came out the way I wanted.
Here are a few notes on the design:
zoom: 1, forcing things into hasLayout mode. This always fixed weird behaviour.I'm looking forward to your comments. This is the first web design I've done that I'm actually really happy with. Not bad, I think, for not being a designer.
Update: For those of you who are new to the site, or if you just want to compare, here is a screenshot of the old design.
Unobtrusive Ajax is about keeping all JavaScript and CSS out of the HTML. This is a good idea. You certainly shouldn't be using onclick or onmouseover attributes in your HTML, and you should really avoid using the style attribute. But what about putting JavaScript inside a <script> element or CSS in a <style> element directly in the HTML?
Most people would recommend that you never do this, that you keep every line of your JavaScript and CSS in an external file. I'd say, never say never. There are certainly occasions I do this, although rare, but I think these scenarios make sense. So let me outline some of these scenarios where you may want to use inline JavaScript and CSS:
You may be doing something really specific, such as some animations or ajax in a web application interface, where this code won't be reused on any other pages on your site. In this case, you won't gain any benefits of reuse in an external file.
If the page is an obscure page in your web application that users only access once, or only once every few months, then you won't gain the benefits of having the browser cache these external files. You'll actually slow things down by making the browser make two extra requests for the JavaScript and CSS.
This is a common scenario with a lot of JavaScript libraries. The instructions often involve including an external file, then putting maybe 1-3 line of JavaScript on the page that initializes some widget. It would be totally wasteful to create an external file containing only 1-3 lines of code. The time wasted downloading an extra file would counteract any benefit gained from caching the file later.
These scenarios don't happen so often. As long as you don't care about the browser caching the CSS and JavaScript separately, and you don't need to reuse the CSS and JavaScript throughout your site, or it's just a few lines of code that isn't worth caching, I see nothing inherently wrong with using inline JavaScript and CSS. Your visitors won't notice or care. It's even valid still, as long as you keep the <style> in the <head> and wrap your JavaScript in a CDATA (for XHTML). So if it makes things a bit easier for you, I say go for it.
Joe tagged me. So now I have to tell you 5 things that the blogosphere doesn't know about me.
I know, these things are totally boring, and you didn't come here to learn about my pets, so I'll try to keep them slightly interesting and on topic:
I ran a number of BBSes from 1993-1995. They were called "The Dreaming" and "Pepperland", and my handles were "Morpheus", "Zippo" and "Fone Bone".
When the Internet came out, I thought it was just another crappy network for "lamers", something like AOL or CompuServe, and hoped it would go away. After a while I gave up and jumped on the bandwagon.
The first web page I made was in 1995 (Grade 10). It was a one-page psychedelic propaganda page for a hippie cult I was trying to start called "The Mellow Revolution". It was hosted on Tripod, but it doesn't exist anymore.
My mom has one of the most successful quilt web sites on the Internet called Victoriana Quilt Designs. When I tell people this, they assume I made it for her. In fact, I only taught her how to use FrontPage one day and she did all the rest by herself (okay, I helped her integrate PayPal and add login security, but that's about it).
I've climbed up and stood on one of the pyramids in Cairo. If you don't believe me, here's proof.
Well, I hoped I didn't bore you to death. Now I'm supposed to tag 5 other bloggers and see if they actually find out, give a crap, and follow through with a list. Tag, Emil Stenström, Roger Johansson, Tara Hunt, Mike Papageorge, and Dan Webb, you're it.
I had a bit of a shock this morning. I was logged in to Google, doing a normal search thing.. you know, click a link, click back, and then WHAM:

Crazy times we're living in. Now, I don't even need to tell you how this will affect Search Engine Optimization. Now there's a whole new technique those black hat marketing people can use to make their pages rank higher: Make them more useful!
Update: It seems pretty random. It disappeared on google.com even when I was logged in, but then it showed up when I was on google.ca and wasn't signed in. I guess it'll just be a random thing like moderation on Slashdot?
I'm going to debunk another myth that might keep you from trying out Ruby on Rails (or any other new server language). MYTH: Once you start using Rails, you have to do everything in Rails.
I wanted to integrate a forum into my new Rails site. So I took a look at the Rails forums out there and found a whopping three: Beast, RForum and Opinion. Unfortunately, they all suck. Ok, to be fair, they're all rather new, and are still in development. But they still suck.
At first, I was okay with using a crappy forum. But I didn't just need a standalone forum — I needed to totally integrate the forum into my existing site, users and all. But rails apps want to run on their own server. I don't know why, they're all claustrophobic or something. When you try to get two of them to share a server, one tends to peck the other's eyes out like it's a rails-powered cockfight.
So after way too much time spent cleaning up feathers and blood, I decided to give one of the classic PHP forums a chance. I decided Vanilla was going to be my forum of choice, and I got to work.
It turned out that it took me less time to integrate Vanilla with my Rails app than all the time I spent recoding routes.rb to make Beast work. Here's some tips to get a PHP app to coexist with rails:
PHP apps are very happy to live inside a subdirectory inside another site. They love it. So what better place to drop one than inside a rails app's public directory. (Try doing that with a rails forum).
This also has the benefit of having a single domain, which makes sharing cookies slightly easier.
This isn't a requirement, but it just simplifies things slightly. Vanilla uses a table naming convention like LMU_*, and I'm sure most other (non-rails) forums do the same, so the two can coexist fairly easily. This way you can do stuff like joins across your own tables and the forum tables.
Rather than share a single 'users' table (which is pretty much the only way you'd be able to get two rails apps to coexist in a single database), just add rows to the forum's user table every time a user signs up on your rails app. And of course, don't forget to use a foreign key to relate the two.
Vanilla makes a single sign-on feature easy through a "Remember me" feature. Basically, if 2 cookies are set ('lussumocookieone' for the UserID, and 'lussumocookietwo' for the VerificationKey by default), then the user is automatically logged in. So all you have to do is look up (or write) the VerificationKey in LMU_Users and set these cookies whenever a user logs in to your rails app.
This is a really easy hack. Just erase the 'PHPSESSID' and '_session_id' cookies, and the user will be logged out from the forum. This way you can have a single sign-out too.
Okay, this post got pretty specific. But the lessons can be applied to the coexistence of any server-side apps. Communicate via the database and cookies, and you can pretty much do anything.
Normally, I try to avoid server-side programming topics. But this time, I thought I'd share my story to perhaps inspire some of you to try something new.
I switched to working in Ruby on Rails this month. Lots of people have done the switch, and even more have written about how Ruby on Rails makes coding web sites a lot more fun and easy (it's true!). But that's not what this story is about.
Until I switched, I was a PHP programmer. It's not just that I did a lot of work in PHP, it's that this is what clients expected of me, or so I thought.
Unfortunately, I was getting really bored of doing PHP programming. I've never been passionate about PHP, it's just something I know that I use to get the job done. Code Igniter had gotten me excited about coding in PHP again, but it just wasn't enough.
I've had a lustful eye on Ruby on Rails since I first heard about it a year or two ago. Yet it stayed on my long-term To Do List, never quite becoming a reality. "When I have more time, I'll figure it out and start using it," I thought. "One of these days I'll do a small project for myself in Rails so I can learn it," I told myself for months.
I felt like I was stuck. PHP was what I knew, what I had used for years, and what I was best at. I had never used Rails, so I certainly didn't feel qualified enough to sell myself as a Rails developer. On top of this, I had three major projects coming up that were all supposed to be done in PHP.
Then one day, I asked myself why I was so willing and excited to work in JavaScript but not PHP. Why is one fun and the other painful? I had always thought of the difference as just client versus server, but then I figured out it might just be the language itself. So I decided the only way to keep my sanity was to switch. There was no way I would keep doing this PHP thing.
So, I got in touch with my clients and asked if they'd be willing to build the projects with Ruby on Rails instead of PHP. They couldn't care less. All they wanted was the finished project, and it didn't matter to them how it was done. One client even said the only reason she had mentioned PHP was because it seemed like the most common, but really didn't care. They didn't even mind that I was just starting to learn, because they knew it would make the project more fun for me, and they trusted me.
So I did it. I've been coding in Rails since the start of the month, and it's been a great time. Sure, there was a learning curve. It took me some time to figure out how to do the simplest of things. But I read through the book, I experimented, I searched the web for answers, and now I'm cruising. I'm about 80% as good in Rails as I am in PHP, except with Rails everything takes half the time so in the end it's actually faster.
So what's the moral of the story? If there's something new you want to start doing, or if you're getting bored, just go change things. Today. Create your own opportunities. And stop finding excuses in those around you for your inability to change, because there's a good chance they will totally support you.
This week, I installed TredoSoft's Multiple IE package (via friendly bit). It's an installer for Internet Explorer standalone versions 3, 4.01, 5.01, 5.5 and 6. It's based on evolt's standalone versions, but packed up in a nice installer. It even fixes some problems with cookies and conditional comments.
Check it out, it's a great package to have installed, and makes it a lot easier and cleaner to get all the old IEs running on your system. (You're all testing your web sites in IE 3, aren't you???)
Here's the problem: According to the principals of Representational State Transfer (REST), GET requests shouldn't change anything on the web server. Only POST requests should. For example, you really shouldn't have an <a> link that deletes an item. When you click a link, it sends a GET request to another page, and deleting an item is definitely a change. You should have a delete button that submits a form using POST instead.
Why? Well for one, Google Accelerator speeds up your web surfing by downloading all the pages that it knows about through the links on a page. So if there are links that delete items or other horrible things, Google Accelerator will go and delete everything for you. This actually happened to some users of 37 signals.
So the real solution is to just use a submit button for all the actions that actually do something (delete, save, etc.). And this is totally fine from a technical point of view, but not so great from an asthetic point of view. Buttons can be pretty ugly, right? (I actually like how they look, but then again, I'm not a designer.)
There is also another solution. You can use JavaScript to make a hidden form, then add an onclick event to a link that submits the form when you click the link. This solution is okay, except for those who don't have JavaScript (like search engine spiders).
I came up with a solution that tackles the problem from the asthetic angle. We can style the buttons so they look like links! Seriously!
Okay, it's not so easy. And it's not perfect. But it's pretty close. Here's the code:
.link-button {
border: 0;
padding: 0;
background: inherit;
font: inherit;
cursor: pointer;
text-decoration: underline;
color: blue;
overflow: visible;
}
<input type="submit" class="link-button" value="Delete"/>
<button type="submit" class="link-button">Delete</button>
It's a bit long because buttons have a lot of default styling to them. First, we remove the border, padding, background and font. Next, we change the mouse cursor and colour, and add an underline so that it looks and acts like a link. Last, we add this overflow: visible to force Internet Explorer to get rid of that weird spacing it adds inside buttons.
You might also have to set the actual font and size of the button to make it match the text around. I don't know why, but font: inherit just doesn't always do the job like it should. If you specifically set font: 12px Arial, it will look fine.
In Safari, it won't do anything if you're using an <input type="submit"> because you can't style these. However, you can style a <button type="submit"> though. You will just have to set the background colour directly and not use inherit. So as long as you don't have some trippy background image, it will be fine.
Another thing: it's not perfect in Firefox or Safari. It will still have some weird spacing around it. Have a look at what Firefox does:

The top is a regular link, the bottom is a button. You can see it's pretty close, but not perfect. Safari has a similar effect with spacing on the bottom.
Well we can take it to the next level and use JavaScript so that it's perfect for the 90% of people who use JavaScript. The other 10% can see the extra spacing, but that's no big deal (they probably won't even notice). We can use the following function to accomplish this:
function replaceButtonWithLink(button) {
var link = document.createElement('a');
link.href = '#';
// find link text either as value of input or innerHTML of button
link.innerHTML = button.value || button.innerHTML;
link.onclick = function() {
button.form.submit();
return false;
};
button.parentNode.insertBefore(link, button);
button.parentNode.removeChild(button);
}
// here's what you do for an <input type="submit"/> or <button type="submit"/>
var button = document.getElementById("my_button");
replaceButtonWithLink(button);
Now we have a nearly perfect solution. If the spacing in Firefox isn't a problem for you, you don't even need the JavaScript portion. But it's there just in case you have some pixel-paranoid designers on your team that insist it should look perfect in their browsers (just hope they have JavaScript turned on!)
Let's say you want to have a logo on a page, but you'd really like to use an <h1> with some text for the header in the HTML. Or maybe you like to use images for all your titles, but would still like to have plain text inside header tags in your HTML.
There are a number of reasons for wanting to do this, namely accessibility and search engine optimization. I talk more about this in my post Writing Semantic HTML.
The problem is: How do you hide the text? I think the most popular technique is to wrap the text with a <span> inside the header tag, then use some CSS to 1) hide the text, and 2) use the header tag as an image. Something like this:
<style type="text/css">
h1 {
width: 500px;
height: 100px;
background: url(my_header_image.gif);
}
h1 span {
display: none;
}
</style>
<h1><span>My Great Header</span></h1>
Unfortunately, this technique makes us add an extra tag to our markup, and we all know that every time we use an unnecessary tag, a puppy dies. Either that, or we end up with ugly, unnecessarily bloated HTML.
Well here's another technique which hides the text just by using CSS. The text will still be readable by screenreaders and search engine spiders, but will disappear like magic for everyone else:
<style type="text/css">
h1 {
width: 500px;
height: 100px;
background: url(my_header_image.gif);
overflow: hidden;
line-height: 500px;
}
</style>
<h1>My Great Header</h1>
This technique works by pushing the text down inside the header with a rather large line-height (it must be at least twice the height). Then the overflow: hidden hides the text since it's overflowing.
Now isn't that better? No puppies were harmed, and we end up with slightly cleaner and shorter markup.
I had a really great time at The Ajax Experience, and got to meet a lot of really cool fellow JavaScript hackers. The sessions were all very interesting, but what really stuck with me was the difference that a good JavaScript library can really make in your development.
John Resig's talk on Choosing a JavaScript Library showed how much cleaner and faster development can be when a library offers elegant solutions to very common problems. And I assume John used some kind of Jedi mind trick because his talk made me choose his own library, jQuery. I even rewrote my talk's examples in jQuery to make them shorter. I'm sure I'll be writing a lot about jQuery on here in the future.
My "Unobtrusive Ajax" talk went pretty well, I thought. I realised afterwards that I hadn't pointed people at my examples for download. So if you attended and want to take a second look, or if you didn't attend but still want to see what it was all about, go check out the downloads below:
And please, contact me if you have any questions or comments about any of this stuff.
Unfortunately, there will be no Carnival of the Web this month. I'll be putting it on hiatus indefinitely. Now that I'm freelancing, I simply don't have the time to read through blogs and pick the best posts. Perhaps it will come back some time in the future. I apologize to everyone who had submitted articles for the fifth edition.
Do you ever try to define a function in a loop, like an event handler for example, and find that it's always the last variable in the array that is pointed at by every event handler? It can take a while to debug this stuff. Let's say you do something like this:
var links = document.getElementsByTagName('a');
for (var i=0;i < links.length;i++) {
var link = links.item(i);
link.onclick = function() {
alert(link.href);
return false;
};
}
(Stupid example, I know). Well if you run this on a page, you would expect that everytime you click a link, you will get an alert with the href of that link. Well that's wrong! You actually get the href of the last link on the page every time!
This happens because of closures in JavaScript. You would expect that the link variable has the same value inside the onclick function as it does outside. But in fact, every time the loop comes around, link gets a new value, and actually the link variable in all those other onclick functions changes. So when the loop finishes, every onclick function will alert the href of the last link.
So to avoid this, you can do a few things. You can make a separate function that attaches the event like so:
function attachLinkEvent(link) {
link.onclick = function() {
alert(link.href);
return false;
};
}
var links = document.getElementsByTagName('a');
for (var i=0;i < links.length;i++) {
var link = links.item(i);
attachLinkEvent(link);
}
This works because inside the attachLinkEvent function, the value of link points at the argument, which is a copy of the link in the loop. This way it doesn't change when the original link changes. Confusing? You bet.
Rather than use this workaround, you can just avoid using the link variable altogether in the onclick function, and replace it with this. Inside an event handler like onclick, this will point at the element that the event handler is attached to. In this case, this points at the link:
var links = document.getElementsByTagName('a');
for (var i=0;i < links.length;i++) {
var link = links.item(i);
link.onclick = function() {
alert(this.href);
return false;
};
}
Of course, real life examples are a bit more complicated. There are also different workarounds to fix the problem. But typically, one of these two solutions will fix things.
For way more information on closures than you will ever need, read Richard Cornford's essay JavaScript Closures
I'll be presenting at The Ajax Experience. This is an Ajax conference taking place in Boston from October 23-25, 2006.
My topic will be "Unobtrusive Ajax", which I've described as so:
Learn how the separation of content, presentation and behavior can not only make your web applications more accessible, but also easier to develop and maintain. See how to implement modern web interfaces so that they are enhanced by JavaScript and still work fine without JavaScript.
Jesse will walk you through lots of examples and show you solutions for some common problems in Unobtrusive Ajax development. Although some of the examples will use a bit of PHP, Jesse will focus on the JavaScript and HTML, so you'll be able to apply the lessons learned to any server platform.
I'll mostly be talking about the practical benefits of separating JavaScript, CSS and HTML, as well as why you shouldn't assume people have JavaScript, and how to design (or re-design) some common Ajax interfaces to avoid this assumption.
I'm a bit worried I'll be the party pooper at the conference.. everyone'll be so excited about using JavaScript, nobody will want to be reminded about the minority that doesn't have JavaScript. But I think the presentation will be a lot of fun and I'll hopefully show people that it's not a big deal to support non-JavaScript users, and it may even make your code more stable and easier to manage.
If you'll be attending, please, let me know. I'd love to meet some fellow Ajax hackers.
Update Oct. 26, 2006: Click here for a write-up and links to my slides and examples.
It's been two months now since I announced I would start freelancing full-time, and hardly anything has gone the way I expected. Here's a little list of some of the things I've learnt or found surprising:
Originally, when trying to figure out how many hours I'd be working per day, I just figured I'd do the same I did at my day job: 8 hours, from 9 to 5.
The first time I tried to work that long, I realised it just wasn't going to happen. I discovered that it takes me about an hour of checking email, reading news, etc. to wake up enough to start working. Then, I can only work about 2 hours straight before my mind turns mushy and I have to take a break.
I quickly realised that my prime working length was around 5 hours in a day, spread out over a period of 7 or 8 hours. But when you're billing by the hour, you really should only charge for the time worked, not the time eating lunch or surfing the web. This is a major difference between freelancing and a regular job.
Scheduling is a juggling act based on a few difficult tasks: estimating how long it takes to do something, and figuring out when you'll have time to do that work. Multiply these simple looking problems by the fact that you'll occasionally be stuck waiting for something from clients. This can create these weird bubbles in time where you have nothing to do, but know that a few days from now you'll have way too many things to do.
With web development, the size of projects can vary from an hour or less to over 400 hours of work. It's especially hard to deal with very large projects. You can say it'll take 100 hours, and that it'll take a month to work those hours. What do you do while you wait for the client to get back to you - tell everyone else who asks for work that you're all booked up? Then what happens if the project never happens? You get screwed!
I'm starting to figure out I have to just explain my situation to my clients, tell them I don't know exactly when I'll have time, but that I should be able to finish within the next month or two. I'm also being careful not to commit more than maybe a third of my time to any one project, because anything can happen. The more flexibility I can work in, the better.
Probably the best part of freelancing is the freedom to work when and whereever you want. While this is true in theory, when you schedule work for yourself, you have to make the commitment to actually work those hours. If you don't, well, you'll either have to work extra hours later or else deliver things late. These are the only stresses that really force you to work, but I'm glad that they're there, or else I would probably be taking off way too many days.
Freedom also gives you the opportunity to find your own rhythm. I'm starting to think that I may work better in the evenings, though my girlfriend isn't so excited about that idea. It's actually not so easy to figure these things out, something you don't have to think about when you're told exactly which hours you have to work at.
When I had a day job, and I wanted to take a little break, I just loaded up Bloglines and tried to catch up on the 200 or so feeds I subscribe to. Now, I can say I haven't read any of them since I went completely full-time. You may also have noticed that I've hardly blogged at all during this time, either.
The reason is, now that the computer at home is where I work, when I take breaks or stop working, I want to get as far away from the computer as possible. It's like blogging and even reading blogs is a part of work that I need to schedule in or make time for, except it seems like the least important thing I have to do, so I never end up with time for it.
I once told a guy who worked at a web development company that I was about to start freelancing. He said, "That won't work. When will you have time to find clients?" I haven't had that problem at all.
Okay, I do have the advantage of having this blog. Nearly all of my clients come from my Hire Me page. But I'm not scared that this will stop. I know that I can easily find more work through sites like Rent A Coder or Guru, even if it pays a bit less than I prefer. I could also step up my marketing efforts at any time (which means doing any, since right now I'm doing practically none).
Okay, it's true, I don't have a lot of time to go find clients. But if I ever ran out of work, I'd certainly have the time to find new clients. It should balance itself out quite well.
So there's some of the things I've learned. Do any other freelancers out there have anything to add to this list?
Welcome to the fourth Carnival of the Web.
First off, Jonathan Snook explains how to maintain an ideal source order while still displaying web site elements in the appropriate positions with Stackable CSS Columns.
Next, Joe Kissell at Interesting Thing of the Day explains just what is so unconventional about text-based ads.
Violeta of All Tips and Tricks shares her results of A personal experiment on internet traffic sources, trying to understand how social software fits in to web site marketing.
Dave Gooden wonders Am I missing something?, giving a skeptical look at the use of map mash-ups for real estate web sites.
Renata Vincoletto at A geek Family wonders what effects the internationalization of companies has on the freedom of nations to enforce their own laws, when Google has bad moments in Brazil.
Dominic Foster shares a simple checklist outlining how he set up WordPress.
And finally, Benjamin Yoskovitz helps non-designers understand the importance of choosing a look and feel of a web site, explaining How To Pick the Best Theme in WordPress For You.
Even though I'm a web developer for hire, I'm not really interested in making really simple web sites. I believe most people could do it themselves, if they just learn a few things. I'd rather spend my time coding web communities or Ajax enhancements or whatever.
So your aunt or some of your clients are bugging you for a free web site (and you don't want anything to do with it), then think about passing these tips along.
There are a bunch of sites out there with free web designs available to the public. The Internet is so big, it really doesn't matter if you have a one-of-a-kind unique web design. Check out Open Source Web Design, Free Site Templates, or just search Google for free web design.
There's a bunch of places that offer free web hosting, but a lot of them won't let you get your own domain name, or they might put a banner on your site or whatever. Plus, you'll want to have hosted email, and the only way to get that is by paying for it. Web hosting is the only thing you really have to pay for.
The good news is, web hosting is pretty cheap. DreamHost, only charges $9.95/month ($7.95 if you pay for 2 years in advance). Plus, you get to register your domain name for free. There are other companies out there that are even cheaper and offer different things as well, so if you shop around you can find a good deal.
Get a copy of Dreamweaver or Microsoft Expression or something similar. This way you can put in your content yourself. You can even learn a bit of HTML and CSS and get your hands dirty. HTML is really easy to learn, and there are thousands of books and free web sites that can get you started.
Ten years ago, the only web sites out there were ones people made for themselves. Nowadays, with so many web companies out there, most people think they have to pay big bucks to get a web site. There is so much free information on the Internet that really anyone can learn how to make a web site, and it only takes a few hours for people to learn how to do it themselves.
When the first beta of Internet Explorer 7 came out, the biggest complaint was that there was no easy way to have it run as a standalone browser. You're pretty much forced to upgrade your whole system to use it.
I took the plunge anyway, deciding I'd rather run IE7, but I ran into all sorts of situations where I really needed IE6 for debugging.
There are a lot of hacks and instructions for taking apart the IE7 beta so that you can run it standalone. I've decided that the extremely easier solution is to just install IE7, then download the standalone of IE6.
Now that the Release Candidate is out, you probably don't want IE6 to be your main browser anymore, right? So why not just have it around for the few times when you really need it?
Search Engine Optimization (SEO) has grown into an entire industry. There are tons of companies who do nothing except help web sites rank high on Google or get lots of search engine traffic. Most of these companies charge a lot for their services. I'm going to outline a few simple things you can do to your own site for free. This isn't a complete list of things you can do, but you can do very well on search engines by following all of these.
Probably the most important place on the page for search engines is the <title>. Rather than cram a thousand keywords in your titles, try to keep them simple and to the point. Describe the contents of the page in plain language. For example, I titled this page "5 Basic Search Engine Optimization Tips" rather than "SEO For Dummies" or something else tricky.
The worst URLs for search engines are like "http://site.com/index.php?c=34&d=43". It's much better to use "http://site.com/my-web-page-title". Do everything you can to get the same keywords into the actual URL of your page. Also, make sure you separate the words by a dash "-" instead of an underscore "_". Google sees a dash as a space but sees words attached with an underscore as one big word.
Use <h1>, <h2>, etc. whenever you can. Don't use them to increase the font size, use them to mark your titles. Doing so tells search engines that these words describe the page or section of the page. So be sure to put good descriptive keywords into these tags. This will increase the page's relevance to those keywords.
A lot of sites have titles and navigation made up of image buttons and links. It's better to just use plain text with a background image. If you really want to put words into images, make sure you at least use the alt attribute. Also, try to put the same words in the HTML, hidden by CSS if necessary.
This is an obvious one, yet usually forgotten. Good content will have a lot of keywords relating to the topic. By using lots of synonyms and clear descriptions, you'll give more words and phrase for the search engines to find. Even having user-generated content such as comments or reviews will give more opporunities for searchers finding the page.
Hopefully following these simple tips will help you get some more traffic. There are a hundred tips and tricks out there, but the best tip of all is to just write lots of great content and make good web pages which are useful and easy to read. The rest should come naturally.
As you may likely be aware, the latest versions of Internet Explorer and Opera have decided not to give Eolas any money for their patent. Instead, users are forced to click on plugins (movies, sound, Flash and Java applets). In other words, anything inside object, embed or applet tags.
Thankfully, there is a way around this. Microsoft has documented some workarounds. I've put together a solution here that works in Opera as well:
// only execute code if 'getElementsByTagName' and 'outerHTML' are supported
if (document.getElementsByTagName && document.body.outerHTML) {
// repeat code for each affected tag
var tags = ['object','embed','applet'];
for (var i in tags) {
// get all elements with tag
var objs = document.getElementsByTagName(tags[i]);
for (var j=0;j < objs.length;j++) {
var obj = objs.item(j);
// find param tags within object
var params = obj.getElementsByTagName('param');
var inner = '';
// if there are params, but param tags can't be found within innerHTML
if (params.length && !/<param/i.test(obj.innerHTML))
// add all param tags to 'inner' string
for (var x=0;x < params.length;x++)
inner += params.item(x).outerHTML;
// put 'inner' string with param tags in the middle of the outerHTML
obj.outerHTML = obj.outerHTML.replace('>', '>' + inner);
}
}
}
The code only executes on browsers which support getElementsByTagName and outerHTML (Internet Explorer, Opera and Safari - but not Firefox). It gets around the patent by dynamically "altering" the outerHTML (even though nothing is changed from the original HTML). But beware: you need to put it in an external JavaScript file to work.
To do this, simply put the code into a file. Let's say it's called eolas.js. Then put this line anywhere after all the object, embed or applet tags:
<script type="text/javascript" src="eolas.js"></script>
Alternatively, you can keep the script tags out of the body by wrapping the code in eolas.js in a function, then use my addDOMLoadEvent function to run the Eolas script once the page has loaded. So if you change eolas.js like so:
function fixEolas() {
// same code above
}
then just put this in the <head> of the page:
<script type="text/javascript" src="eolas.js"></script> <script type="text/javascript" src="adddomloadevent.js"></script> <script type="text/javascript"> addDOMLoadEvent(fixEolas); </script>
Unfortunately, the JavaScript file will be downloaded unnecessarily for users who don't use Internet Explorer or Opera. But if Safari or other browsers implement the same thing, this JavaScript code will already be in place to fix it.
And there you have it. Three cheers for horrible software patents!
Update: The code I posted before breaks objects with <param> tags in Internet Explorer. It turns out that outerHTML doesn't contain <param> tags, so extra work needs to be done to make sure they stay intact. I've updated the script accordingly.
So everyone knows MySpace has gotten big. Really big. There are start-ups appearing every minute destined to become the next MySpace. This has attracted it a lot of attention.
Bands quickly realised the marketing power of MySpace. You can find MySpace pages for bands like Beck, Eminem, and of course millions of small bands.
If you have a MySpace page, you know that bands caught on to using MySpace as a way to do marketing thanks to the 'Add a friend' feature. They seem to constantly search on MySpace for potential fans, then ask those people to be their friends.
Now, the spammers have caught on. There are MySpace pages for the most mundane of commercial interests. How about this one which is just selling shoes, or this one which shallowly markets another web site. These aren't real people. Who wants to be friends with a shoe reseller?
I know this is just the beginning. Soon, MySpace spam will end up on every marketer's to-do list (along with "viral" movies on YouTube). And when that happens, when every MySpace member has to deny a handful of "friends" every day, then I think MySpace will fall. People are excited about the "MySpace generation", but I'm not sure they understand them. The more something is cool today, the more it will suck tomorrow. MySpace is about to become as uncool as the Backstreet Boys.
Last night, I added gravatars to the comments on this site. The best blog post to see them is Blog Tipping.
Gravatars are globally recognized avatars. It's a clever way to let people upload a little picture that goes beside their comments. This way, people only have to add them once (at the Gravatar website) and they automatically work across all web sites implementing them. They use the MD5 hash of your email address as an id, so you only need to put in the same email address when you write comments, and your gravatar will come.
Implementation is very easy. You don't need to make any HTTP request on the server or anything. You only need to add an image that points at the gravatar URL, with some optional parameters, and the browsers of people visiting your site will download the images from gravatar.com.
The only required parameter is gravatar_id, the md5 hash of the email address. Every programming language has a way of finding an MD5 hash. PHP probably has the most simple example:
<img src="http://www.gravatar.com/avatar.php?gravatar_id== md5($email) ?>"/>
There are also optional parameters you can use. rating lets you make sure there are no pornographic or mature images on your site. size lets you set the width/height to something other than 80px. default lets you set the URL of a default image, in case you want to display something for people without a gravatar (a 1x1 invisible image is the default). border is supposed to let you set the colour of a 1px border on the image, though I wasn't able to get this working. So the output of a complex example might look like this:
<img src="http://www.gravatar.com/avatar.php?size=50&border=000&gravatar_id=eb22390416c3b62025dc9ad2120a8ade"/>
It's worth noting that adding gravatars can be a css and design challenge. You don't know whether the image will be a real gravatar or just a 1x1 invisible image. If you add margins or padding to the gravatar, they will end up on the invisible pixel as well, and this can look weird. I solved it by indenting all comments 60px to allow space for a 50px image. If the image isn't there, the comment is just indented anyway. You can also solve this by setting a default image to a "No gravatar" image.
Gravatars can really be implemented anywhere you know an email address and may want to show an image. There is a Thunderbird add-on that lets you see Gravatars while you're reading emails.
For more details, or to see how to implement gravatars in other languages and blog publishing software, the Gravatar web site has a detailed implementation guide. If you just want to upload your own gravatar, go sign up.
I've become convinced the ultimate benefit of the Internet is and will always be the ability to connect people. Lots of people know this already. You can see evidence of it by the rapid pace of new Social Networking web sites being made. But I'm not interested in these billions of MySpace rip-offs.
There have always been people-matching sites on the web. Dating and Friend-finding sites (connecting individuals to meet in real life) and sites for finding jobs (connecting employers with employees) are some of the most common examples. We can also see people connecting through the uses of forums, blogs, online groups and other communities. But I think there is a lot of potential for specialized sites that solve a very specific problem for a potentially large group of people.
Take a look at BookMooch. This is a new site which lets people trade used books. No money is exchanged. Instead you get points for mailing books to people, and you can use those points to get books mailed to you. It is a perfect example of the potential of connecting people. It's not just connecting me to you so that we can chat about our shared interests. It's about connecting anyone who wants to trade books, and allowing the most complex of trades to happen very easily. "I'll give this book to her, and she'll give that other book to him, then he'll give some book to you, and finally you give this book to me."
Web professionals should check out Programmer Meet Designer. It's a place for finding freelancing partners who can help out each other in any number of ways, from a few hours on a single project to a permanent professional partnership. Most notably, it's geared to a specific yet large problem of matching programmers and designers, and it solves the problem well.
The possibilities are rather endless, and I think the room for competition or co-existence between these sites are quite large. For example, there are a large number of job searching sites which co-exist in harmony. As I outlined earlier this week, there are job searching sites which specialize in jobs for web professionals. There are also dating sites which specialize in every conceivable niche. People can use more than one of these sites at a time, and many do.
If you're trying to come up with a new web business, try to find a way to connect people who can benefit from each other. These sites will always be in demand, simply because everybody benefits.
Hello and welcome to the third edition of the Carnival of the Web! Despite this being the middle of the summer, it's obviously not everyone has been on holiday. This month we have some more great blog posts I hope you'll enjoy. For more information on this carnival, or to submit an article, check out the carnival info page.
First off, Dustin Diaz shows how JavaScript can be a bit more object-oriented by showing us How to achieve private, public, and privileged members in JavaScript.
Next, Simon Willison gives a detailed review with the ups and downs of Sticking with Opera 9.
Justin Palmer insists we should worry more about code readability than length by exploring Why Chef Boyardee Doesn't Write Javascript.
If you're hungry for some Bite Size Standards, why not learn how to Clean up code with semantic anchors.
Dean Edwards brings the for-loop into the 21st century in Enumerating JavaScript Objects.
Jeremy Keith explains why the only way web developers are going to be able to work with JavaScript is by Learning JavaScript.
James Bennett gives some perspective on what security really means with Let’s talk about frameworks, security edition.
Clay Mabbitt over at Web Design Business Best Practices walks us through a useful but often overlooked aspect of database design, showing how to leave an audit trail in your database.
Joe Kissell brings us the next Interesting Thing of the Day, a look at the million dollar homepage and how to make a fortune with paperclips and pixels.
D Kai Wilson of Mechanical Regurgitation brings us through an often necessary sanity check by asking the question: Are YOU listed on spam blacklists?
Sérgio Rebelo at twodotfive weighs the pros and cons of using a fixed layout with Blog Widths.
And to finish things off with a laugh, Avant News brings us news all the way from the year 2008, letting us know that Social Networking Site Digg.com to Replace Traditional Voting.
If you want to put a map on your web site using Google Maps, the easiest way to do that is by going to WikiMapia, finding the place you want, then going to the menu and selected "Map on your page". You'll be presented with a box that lets you pick the size and exact starting location of your map, and you'll be given a very simple HTML snippet (an iframe) you can put anywhere.
For example, I found my home in Berlin and was given the following snippet:
<iframe src=http://wikimapia.org/s/#y=52506879&x=13318394&z=19&l=0&m=a width=400 height=208 frameborder=0></iframe>
I had to change the HTML to XHTML myself by adding quotes around the attribute values and escaping the ampersands in the URL:
<iframe src="http://wikimapia.org/s/#y=52506879&x=13318394&z=19&l=0&m=a" width="400" height="208" frameborder="0"></iframe>
Unfortunately, iframe is deprecated in XHTML Strict, so this would make my page invalid. The way to embed a frame on a page in XHTML Strict is to use an object tag instead like so:
<object type="text/html" data="http://wikimapia.org/s/#y=52506879&x=13318394&z=19&l=0&m=a" width="400" height="208" style="border:0"></object>
It seems WikiMapia doesn't support the object tag when used with Internet Explorer. Well, as long as you're not using IE, you can see where I live in Berlin! The rest of you can click here instead.
If you're a web professional looking for a job, or looking to find a better job, there are some really great job boards to keep an eye on:
This is a great site to find some of the best jobs out there. Many of them are looking for Rails developers, but there are other development, design and management jobs. Plus, I think it's a good sign when a company knows about 37signals.
Certainly the best place to find a Ruby On Rails job. There's new postings nearly every day.
There's a nice variety of web professional jobs posted here, though mostly centred around development.
If you're passionate about web standards and semantic markup, there's probably a good job for you on here. I bet it would be nice to work in a company where you don't have to convince anyone about the benefits of web standards.
If you know the city you want to work in, Craigslist is a great place to look for a job. It doesn't have every job, but in my experience the companies that post on there tend to be at least a little hip. The squares probably haven't even heard of craigslist.
When looking for a job, it helps if you either live in a great location like California, New York or London, or you're willing to relocate. Who knows, though, maybe your dream job is just around the corner.
I think all of these job boards have RSS available, so you can just subscribe now and keep an eye on the results while you mull over quitting your current job.
Originally I explained this on the Code Igniter forum, and since others are blogging it, I thought I should bring it here.
I guess I was nervous about sharing my anti-spam techniques on my own blog in case any spam bots are smart enough to read this article and somehow mutate and adapt. We'll see.
For a while, I had no problems with comment spam. Then I started to get a couple. Then one day I got like 50 at once, so I did something "extreme" - I made it so users have to have JavaScript to submit comments. I have a randomly generated spam key in PHP, and then use something like this on the page:
<form id="cform" style="display:none">
<input id="txtauthor" name="<?= $spam ?>a"/>
<input id="txtemail" name="<?= $spam ?>e"/>
<input id="txturl" name="<?= $spam ?>u"/>
<textarea id="txtbody" name="<?= $spam ?>b" rows="10" cols="40"></textarea>
<input type="hidden" id="antispam" name="antispam"/>
</form>
<script type="text/javascript">
document.getElementById('cform').style.display = 'block';
document.getElementById('antispam').value = '<?= $spam ?>';
</script>
<noscript>Sorry, you need JavaScript to post comments.</noscript>
So if the spam key is 'xxxx' the author field is 'xxxxa', email 'xxxxe', etc. The spam key is filled using JavaScript. Then on the server side I do this:
if (isset($_POST['antispam'])) {
$antispam = $_POST['antispam'];
$cauthor = $_POST[$antispam . 'a'];
$cbody = $_POST[$antispam . 'b'];
$cemail = $_POST[$antispam . 'e'];
$curl = $_POST[$antispam . 'u'];
if ($cbody && $cauthor)
addComment($id, $cemail, $cauthor, $cbody, $curl);
}
This has majorly cut down on the number of comment spam I get. I still get the occasional one here and there, but they must all be done by hand instead of with some automated bot.
Unfortunately, this method means that users without JavaScript can't post comments on here. I regret that, but since nobody posts comments on here anyways, I figure it's not such a loss. :) One day, I would like to add some kind of captcha or approval system to allow posting of comments without JavaScript.
That dynamic duo Tara Hunt and her PiC Chris Messina have got me thinking. They've been talking about web applications starting to move to the desktop. Okay, that doesn't seem so interesting, desktop applications are like the oldest things there are. But we've learnt some lessons from web apps that we can try to bring back to the desktop.
I sync my iPhoto with Flickr and Riya - but why couldn't I store all of that data on my desktop?
Chris sees web apps coming to the desktop more literally:
I'm seeing a third generation stack emerging that holds a great deal of promise for sewing up the future of offline-sync-online experiences.
That stack looks a bit more like Rails, SQL Lite (which the next rev of the Firefox bookmarks will be based on), Microformats, some blend of JSON/AMASS/jQuery/behaviour.js/scriptaculous/prototype and, yes, WebKit. What do they have in common? Well, enough inter-woven stickiness to make the heart of a true web geek start to murmur.
This got me thinking about something nobody really talks or cares about anymore: peer-to-peer.
Why doesn't every computer on the web run it's own web server? If you want to share something with the world (photos, music, a blog, etc.), you put it on your personal web server and people come to you.
Try to do this today. I ran a web server off my own computer for a few years in University.. that is, until the assholes at Rogers Cable told me to block port 80 or they would cut off my Internet service.
Okay, I understand the logistical problems here. Even our high-speed Internet connections couldn't handle the bandwidth issues of a busy web site, let alone a dial-up connection. And we would have to leave our computers running all the time. We would also need a static IP or heavily use dyndns.com, plus I can't picture average Internet users configuring their router to port forward to their personal web servers, nor configuring Apache. Not to mention the security implications.
Okay, it sounds like a bad idea for 2006. But I'm talking about the future of the web here.
Eventually, I hope, our current bandwidth will be as funny as 2400-baud modems are to us now. Eventually, perhaps, IPv6 will let every device have a static IP so we won't have to hide behind our routers. Eventually, when a web server becomes as easy to set up as a web browser, we will find them in every household. Eventually.
I just heard about Swift (via Chris Messina). Swift is a port of WebKit for Windows. WebKit is the rendering engine behind Safari (in the same way Gecko is behind Firefox and Mozilla). So I figure, sweet! Safari for Windows!
I had some problems though. On one of my PCs, WebKit.dll couldn't be registered so the installation failed. Weird.
On my other PC, I got Swift installed no problem. I ran it and.. well.. let's just say it's clearly Alpha software. Not only is the user interface extremely bare minimum (you're not going to make this your default browser any time soon), the functionality is a bit iffy. For example, it crashed when I clicked a normal link.
Perhaps it will help you see how WebKit will render your page.. but I wouldn't rely on it. I had a password field go missing, and buttons are styled with CSS whereas I'm pretty sure they aren't in Safari.
It seems there is also a problem with JavaScript. JavaScript executes, sometimes, but I had a problem getting popups to launch, or to load my new Google ads. Okay, maybe you won't miss popups and ads, but what else will break?
I give massive kudos to WebKit and Chris Fuenty for putting this together. It's not there yet, but I can't wait until it is. Having a port of WebKit on Windows will help web developers without Macs immensely. Maybe one day Swift will even become a major player in the browser market.
As I warned yesterday, I've put ads back on the site. Currently, I only have them on the individual blog post pages (the pages that have comments on them). If you only read from the home page, or if you read via RSS, you won't see them.
I also walked my own talk by letting people turn off the ads if they wish. I did it entirely with JavaScript, so I thought I'd share my methodology with you.
The HTML just looks like this:
<div class="ads">
<script type="text/javascript" src="banner-ad.js"></script>
</div>
And the JavaScript in banner-ad.js looks like this:
/* Customized Google Adsense codes */ google_ad_client = "pub-3809601305027895"; google_ad_width = 468; google_ad_height = 60; google_ad_format = "468x60_as"; google_ad_type = "text"; google_ad_channel ="8087340205"; google_color_border = "99bbee"; google_color_bg = "99bbee"; google_color_link = "000000"; google_color_url = "000000"; google_color_text = "000000"; /* cookie functions from QuirksMode */ function setCookie (name,value,days) { if (days) { var date = new Date(); date.setTime(date.getTime()+(days*24*60*60*1000)); var expires = "; expires="+date.toGMTString(); } else var expires = ""; document.cookie = name+"="+value+expires+"; path=/"; } function getCookie (name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null; } /* onclick function to remove ads */ function removeAds() { /* set a cookie for 10 years to stop showing ads */ setCookie('hideads', '1', 365*10); /* hide every div on the page with the class name 'ads' */ var ads = document.getElementsByTagName('div'); for (var i=0;i < ads.length;i++) { if (ads[i].className == 'ads') { ads[i].style.display = 'none'; } } return false; } /* don't show the ads if the cookie is there */ if (getCookie('hideads') != '1') { /* write out the link to hide the ads */ document.write('<a href="#" onclick="return removeAds()">Remove Ads</a>'); /* write out the regular Adsense script tag */ document.write('<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>'); }
When the 'Remove Ads' link is clicked, the ads are instantly hidden using CSS and a cookie is set. Next time this script is loaded, as long as the cookie is set, the ads won't be written to the page anymore.
Pretty much the only comment/form spam I get is of the variety that ends with:
Best site in bleep! My thnx to webmasters.
The rest of the message is usually different. Two recent examples are "Excellent site you have! Awesome content. Thank you." and "Thanks for nice and actual info' Be the Best!". These examples don't have any URLs in them, but many often do. I suspect the ones without URLs are a sort of ping/robot system that is going around testing for new places to submit.
The "From:" address is fairly consistent as well. It's nearly always from a mail.com address, though there are exceptions such as a recent one that came from Bush@yandex.com.
What is this spam?? A search on Google only comes up with fellow blogger John Bokma's site, plus 37,800 other pages probably containing actual comment spam. John has logged a ton of different URLs and IP addresses of this spammer (nicknamed "Bleep"), and has concluded Bleep is actually comprised of a small botnet. He also describes Google's apparent inaction towards stopping this spammer on Blogspot.
I have a theory that Bleep isn't just a single spammer, but perhaps the default output of some kind of comment spam software used by hundreds of different spammers.
I'm rather interested to get my hands on some comment spam software - not to actually spam but just to see how the thing works to get some ideas of how to fight comment spam - but it seems impossible to find it. Searching on "comment spam" just brings up web pages against spam. Plus, I'm pretty sure whoever writes the software wouldn't name it "Comment Spam 2000" or something. It probably has a name like "Web Advertiser 2000" that makes it sound not-so-evil.
Does anyone have any info on this Bleep bot? Or any ideas of where I can find comment-spamming software?
I mentioned in my review of dict.cc that I loved the ability to turn off ads. Unfortunately, now that ability is gone. There used to be is a large Adsense banner across the top of the page with a link to "Remove Ad". When you clicked the link, the ad would disappear. I guess it used a cookie to remember your preference so that the next time you went to the site, the ads would be gone. Now, there are just ads on the side with no way to hide them. Update: the banner and Remove Ad link is still there, just not on the home page!
The ability to disable ads is great from a visitors perspective. People already use adblock software to block ads that they don't want to see and will never click on. Allowing visitors to customize a web site is not only helpful but generous as well. This also solves the dilema of sites which want to make a bit of money but don't want to ruin the experience of their loyal visitors.
On a related note, I'm thinking of bringing back the Adsense ads (with a Remove Ads link) to see how they peform. I had taken them off back in December when I was only making a few cents per week, but my traffic situation has since changed. If anybody has any objections, speak now or forever hold your peace. :)
Update: I've put back the ads with a 'Remove Ads' link, and wrote a follow-up explaining how.
I was just reading on the Ajaxian a quote from an article Why XHR should become opt-in cross-domain, so I started thinking, isn't there a way around this already?
A quick explanation of what I'm talking about: XMLHttpRequest (the function behind Ajax) will only let you connect to URLs on the same domain as the page you're on. This means the Ajax happening on xyz.com can only connect to URLs on xyz.com. Even if XYZ wanted to use Ajax to pull some data from foobar.com, they wouldn't be able to.
Now there is already one popular way around this. You can make a proxy page that gets the data for you. Using the same example, XYZ could make a URL like xyz.com/json_proxy that pulled data over from foobar.com behind the scenes, thus making the foobar.com data available on xyz.com. The problem with this is, XYZ would have to handle double the bandwidth of this data unnecessarily. This can be a big problem for smaller companies.
I have an alternative solution to this problem. Instead of using XMLHttpRequest to load the data, we can just use <script> tags instead. These don't have the same cross-server restrictions as XMLHttpRequest. In fact, this is how Adsense works. You stick a <script> tag on the page which executes JavaScript coming from Google's server, and this writes out the ads on the page.
To add a <script> tag to our page, we only need to call this function:
function addScript(url) {
var script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
}
If we have a URL that returns some JSON data, we just pass that URL to this function and the page will load that data. Well, not entirely. There's a few things we need to do different. With JSON, you have some data like:
{
"firstname": "Jesse",
"lastname": "Skinner"
}
and then use XMLHttpRequest with eval() to assign it to a variable. If you just stuck a script tag on the page to load this, nothing would happen. It would just load and the JavaScript parser would say "Great, nice little piece of data." But it's not going to assign it to a variable, so you'll have no way to access it.
There's actually no way around this unless you change what is returned by the JSON data URL. This is the special trick. We would need the JavaScript to execute some function or assign the data to a variable. It would need to look like this:
json_callback({
"firstname": "Jesse",
"lastname": "Skinner"
});
Now, we just need to make a simple function called json_callback() that takes the data and does something with it. Voila! Cross-server JSON.
Rather than hardcode some callback function name, it would probably be better to add an optional "callback" parameter that would specify the function name. If the callback parameter is missing, the server can return standard ol' JSON.
Let's say our simple JSON example above came from "foobar.com/data?format=json". If example.com was kind enough to provide this flexibility, they could add the parameter so that "foobar.com/data?format=json&callback=my_json_callback" formats the data as a function call, passing the data object to my_json_callback().
Now, we just need to wait for web APIs with JSON to start supporting this parameter.
Update: I've since discovered that Yahoo!'s JSON API already provides a 'callback' parameter exactly as I've described above, and I suspect that other APIs out there may support this as well. Either I'm psychic or there are time travellers working at Yahoo! ;) Here are the details from Yahoo!
I've come across two JavaScript games in the past couple of days that have really impressed me:
Just a few fun examples to demonstrate the potential of JavaScript and CSS beyond Ajax, drag-and-drop and yellow-fade techniques - though of course nothing beats Buzzword Hellfire ;). Anyone have any more?
Big news: I'm quitting my job, moving back to Canada (with Svea of course) and taking the plunge into fulltime web development freelancing. This is something I've wanted to do for a long, long time (like seriously 10 years).
I'll be available to do any sized projects, from debugging CSS to adding Ajax functionality to full-blown database-driven web applications in PHP or Ruby on Rails. I love doing it all, and I love the variety. I think that's why freelancing is going to be very fun for me. I also plan to have more time to work on my own projects and get some very interesting things started. Stay tuned for more on that.
You can probably expect the content of this blog will start to include stuff about freelancing and self-employment. Hopefully I can help someone out by passing along any painful lessons learned. I'd also love to hear your stories and advice about going it alone.
Anyway, if you'd like me to help you out with JavaScript, Ajax, CSS or whatever else, drop me a line.
Until now, I've just considered JSON to be the equivalent to regular JavaScript object literal notation. Jonathan Snook has now explained the difference. It turns out JSON is a bit more picky than regular object literals. Key names must be quoted, and you can only use double-quotes around keys and values. Also, functions are not allowed as values.
I gave an example of JSON some time ago that turns out to be wrong. I used single-quotes in my JSON example. I'll leave them there since the example works, but I just can't call it JSON.
If you're doing JSON-style coding by hand for your Ajax communications, you can get away with using any object literals. So why care if it fits the JSON standard? Well, there are parsers and tools out there which can work with the JSON format, and if you don't fit the standard, they might not work.
I have no idea why the designers of JSON didn't just make the standard flexible enough to handle single quotes and unquoted keys. It's also confusing that JSON stands for JavaScript Object Notation, and that Object Notation somehow means something different from the object literal notation in JavaScript. Great.
Moral of the story: it probably doesn't matter if you use the JSON standard until you have to interoperate with JSON tools or feel the need to offer your JSON data to the public. You should probably stop calling it JSON if you use single-quotes, though.
Usually when assigning class names, it's most natural to assign a different class name to each uniquely styled area of the page. Often, there are common words you'll want to use as class names in more than one spot on the page such as 'date', 'section', 'title', etc.
At first, it seems the solution is to make up unique class names like 'header-date' and 'comment-date' or 'side-section' and 'main-section.
Instead of doing this, you can just stick to using your simple 'date' and 'section' class names but refer to them in their context. For example, if your mark-up looks something like this:
<div class="side">
<h2 class="title">Side Title</h2>
</div>
<div class="main">
<h2 class="title">Main Title</h2>
</div>
Then you could define your CSS like so:
.side .title { font-size: 1.2em }
.main .title { font-size: 2em }
Even better, you can get rid of the unnecessary class names and just define styles onto elements within different sections of the page:
.side h2 { font-size: 1.2em }
.main h2 { font-size: 2em }
You also have the option of doing element-sensitive definitions. Perhaps an <h2> tag with a 'date' class can mean something different than an <h3> tag. Then, just do this:
h2.date { color: blue; background: white }
h3.date { color: green; background: red; }
This is pretty simple stuff, but it opens up all sorts of possibilities for keeping your HTML as clean as possible. Just be careful not to get confused (or confuse others) by using the same class name for more than one purpose.
Welcome to the second edition of the Carnival of the Web.
To start things off, Emil Stenström at Friendly Bit brings up some good points with Current issues with Microformats.
John Oxton makes us web developers all feel a little bit better about ourselves with No I am not bloody sorry.
Rob Cherney follows up on John Oxton's post (and makes us feel even better) with A Bloody Good Developer.
Justin Palmer at EncyteMedia gives a different way of looking at design issues with Unconscious Interface Design.
Clay Mabbitt of Web Design Businesses Best Practices gives a nice guide to Pricing your web design service.
Joe Kissell at Interesting Thing of the Day gives us an introduction to Wikis.
Ohad's Internet News referees the battle of the giants with Google VS Microsoft.
Gerard at Interweb World wants to help you Perfect Your WordPress Title Tags.
George Papp at the Website Auction Hub answers the question How can I monetize my forum and start making money with it?.
Daniel Scocco of Innovation Zen outlines the top 5 trends of Marketing Under the Information Age.
And finally, Daniel Swiecki wonders what comes after Web 2.0 by asking How Much Rounder Can Corners Get?.
I hate to do posts like "Sorry I haven't posted in so long" or "I won't be posting for the next while" but... I won't be posting for the next while. I'm leaving tomorrow morning to go back to visit Canada for three weeks, and chances are I'll be pretty busy. But don't worry—I'll be back just in time to do Carnival of the Web #2. See ya!
There seems to be a trend towards using floating layers instead of popup windows. Floating layers (sometimes called "Div Popups" or "Floating Divs") are just HTML elements, such as a divs, styled to sit on top of the rest of the page. It's basically like a real window, and usually they are designed with an X in the top-right corner to let the user close the "window" (i.e. hide the layer).
There are some things to consider when deciding to use floating layers:
If you think about it, each of these points could be a positive or negative. If you're displaying advertising, you'll be glad to sneak around popup blockers and force people to look at the thing. If you're designing a user interface, you might want to let people minimize, move and resize the popup window so they can see what is behind it.
From a usability perspective, floating layers are a bad idea. You have to design a way to close them, maybe even to move them around. But however you design them, they won't match everybody's desktop. Sure, you can design them to match the default Windows XP theme, but they will stick out like a sore thumb on Mac OSX. By using floating layers, you make people have to stop and think and figure out how to close the thing, whereas they would automatically know how to close a regular popup window without thinking.
There is already a very easy way to make a window that fits in with the rest of the operating system that can easily be moved, resized, minimized, maximized. Unless you have a strong need to use a floating layer, you might as well stick with window.open.
This happened a few days ago, but I didn't think to blog about it until now for some reason: Opera 9 has been released. There are a lot of changes to it, the most notable (to me anyway) is the presence of Rich Text Editing, otherwise known as contentEditable or designMode. Click here for a demo and documentation. I've had a chance to play around with it and it works very well using existing code from Firefox and Internet Explorer. It seems there are some minor differences for really specific things, but overall I was suprised at how compatible it was right out of the box.
Now if only Safari's rich text editing could get this sophisticated...
There are other big changes that look great, but I won't bother listing them all here. Go take a look at the release notes for that.
There has been a problem with using window.onload in JavaScript. This event handler waits until all the images and other files load before executing. If you need some JavaScript to execute when the page loads, you usually only need the HTML to be downloaded, not all the images.
The event to use for this is "DOMContentLoaded", but only Firefox (and recently, Opera 9) support this. There are different ways to do this in every other browser, and people have been working on finding a complete solution to this for some time.
Very recently, this problem has been solved by Dean Edwards, Matthias Miller and John Resig. There is a unique solution for Internet Explorer, Safari, and for W3C-compatible browsers (Firefox and Opera 9).
Very soon after, Dan Webb adapted the solution to prototype. Unlike the original solution, this code allows you to add more than one function to be executed when the DOM loads.
Inspired by Simon Willison's addLoadEvent function, I wanted to create a standalone generic solution that anyone could use without needing a specific framework.
So here's the js file: adddomloadevent.js, and here's the actual code:
/*
* (c)2006 Jesse Skinner/Dean Edwards/Matthias Miller/John Resig
* Special thanks to Dan Webb's domready.js Prototype extension
* and Simon Willison's addLoadEvent
*
* For more info, see:
* http://www.thefutureoftheweb.com/blog/adddomloadevent
* http://dean.edwards.name/weblog/2006/06/again/
* http://www.vivabit.com/bollocks/2006/06/21/a-dom-ready-extension-for-prototype
* http://simon.incutio.com/archive/2004/05/26/addLoadEvent
*
*
* To use: call addDOMLoadEvent one or more times with functions, ie:
*
* function something() {
* // do something
* }
* addDOMLoadEvent(something);
*
* addDOMLoadEvent(function() {
* // do other stuff
* });
*
*/
addDOMLoadEvent = (function(){
// create event function stack
var load_events = [],
load_timer,
script,
done,
exec,
old_onload,
init = function () {
done = true;
// kill the timer
clearInterval(load_timer);
// execute each function in the stack in the order they were added
while (exec = load_events.shift())
exec();
if (script) script.onreadystatechange = '';
};
return function (func) {
// if the init function was already ran, just run this function now and stop
if (done) return func();
if (!load_events[0]) {
// for Mozilla/Opera9
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", init, false);
// for Internet Explorer
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=__ie_onload defer src=//0><\/scr"+"ipt>");
script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
if (this.readyState == "complete")
init(); // call the onload handler
};
/*@end @*/
// for Safari
if (/WebKit/i.test(navigator.userAgent)) { // sniff
load_timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState))
init(); // call the onload handler
}, 10);
}
// for other browsers set the window.onload, but also execute the old window.onload
old_onload = window.onload;
window.onload = function() {
init();
if (old_onload) old_onload();
};
}
load_events.push(func);
}
})();
Update: I added a demo page, as well as a compressed version (only 876 bytes).
Update: Thanks to Adam Schlag's suggestion, I fixed the memory leak in IE.
Update: Thanks again to Rob Cherny and Alistair Potts, I've updated the solution so that it works over HTTPS without any security issues. I also decreased the compressed size to 761 bytes. Now it's perfect! (I hope!)
Update: I've gone back and reworked the code to get rid of the global variables, and I've managed to reduce the compressed size to 563 bytes!
Update [Aug. 19, 2007]: Now the script preserves any existing window.onload function, and also executes functions instantly when called after the page has already loaded. But now the compressed version is a hefty 617 bytes.
I just did some interesting reading that made me rethink the purpose of the different versions of HTML.
One of the first things I did when I launched this site was work to convert it to valid XHTML 1.1. I was excited about the potential of HTML served as XML, and I saw the doctype of my site as a vote towards moving forward. The more sites that start serving XHTML, the faster browsers will support it, right?
Well that might be true, but the fact is, we're not there yet. As I've mentioned before, this is required for delivering XML applications, even XHTML. The problem is, Internet Explorer just doesn't support the application/xhtml+xml mime type.
Previously, I used a workaround to send XHTML 1.1 to browsers that could support it (ie. Firefox), and XHTML 1.0 to browsers that couldn't. This is what I've done for the past year.
Today, I read on the Mozilla website, in the Web Developer FAQ:
... if you are using the usual HTML features (no MathML) and are serving your content as text/html to other browsers, there is no need to serve application/xhtml+xml to Mozilla. In fact, doing so would deprive the Mozilla users of incremental display, because incremental loading of XML documents has not been implemented yet. Serving valid HTML 4.01 as text/html ensures the widest browser and search engine support.
Geez, I thought, what have I done? I tried to make things better for Firefox users, but really I just made things slower.
There are lots of benefits to serving HTML as XML. The thing is, the browsers do a better job just working with HTML at the moment, so if you don't require the benefits of XML, you're better off sticking with HTML.
I read another article, Sending XHTML as text/html Considered Harmful. So let's get this straight: it's harmful to send XHTML as either text/html or application/xhtml+xml. Since these are our only two choices, this means it's harmful to use XHTML! Since the browsers don't properly support XHTML, there's no tangible benefit yet to using XHTML instead of just HTML 4.01 strict.
One day there will be a reason to move forward and start using XHTML in all its glory. Many of us have been trying to make this a reality as soon as possible. Okay, it's a nice idea to start using XHTML 1.0 so that the transition in the future will be as smooth as possible. But beyond that, beyond looking into the future, there's no sense in changing what we're doing today. If a version of Internet Explorer ever comes out (8? 9? 15?) that really supports XHTML, then things might change.
Anyway, long story short, this web site is now XHTML 1.0, and I'm considering just going back to HTML 4.01 strict.
After reading Tantek write about file formats, I've been thinking about what will happen to file formats in decades or centuries from now. Tantek says,
"I feel quite confident storing files in the following formats: ASCII / "plain text" / .txt / (UTF8 only if necessary), mbox, (X)HTML, JPEG, PNG, WAV, MP3, MPEG"
I agree, for the short term. But will JPEG be around in a hundred years? What about MP3?
I think we can make some assumptions about the future. For example, disk space will continue to grow and get cheaper, and bandwidth will get faster and cheaper as well. This leads me to think that compressed lossy formats will disappear. Why store in a JPEG when a PNG or even RAW format will do? Why store in MP3 when a WAV will do?
Okay, I don't think we will necessarily store in the least compressed format. I think we will use a format which uses lossless compression, so that the sound/image doesn't change at all. It won't make sense to lose quality to gain disk space anymore.
What about HTML? Oh, I don't know. This is a big question. The web is very new and it's not clear the direction it's moving in. We are using HTML, CSS and JavaScript in ways it was never intended to create desktop-style applications. I think application markup languages like XUL, XAML or even HTML 5 will take off where HTML leaves off, and we'll have no reason to continue abusing HTML the way we have been.
For hyperlinked documents, I believe (X)HTML will stay around for a very, very long time. CSS can grow and change and add display functionality on top of HTML. Put does HTML need to change? Do we need anything more than headers and paragraphs, with span or div tags together with classes to accomplish anything not built into HTML? I don't believe so.
It will be interesting to watch formats and standards evolve over the coming years and decades. I think one day, people will look back at these times with a smile on their faces, enjoying our naivety in these early years as we try to figure everything out.
Welcome to the first monthly Carnival of the Web. Below you'll find some of the best posts from the past month in the web professional blogosphere.
The next Carnival of the Web will be posted on Sunday, July 23rd. If you write about web design or development and want to contribute something over the next month, feel free to submit your blog posts.
The infamous Roger Johansson of 456 Berea Street reminds us to Use Ajax scripting responsibly. Be sure to check out the comments to discover just how intense (and long) comments can get.
Mike Papageorge of the ever popular Fiftyfoureleven suggests some very clever and not-so-obvious ways to optimize the load time of a web site in Reducing HTTP Requests.
Andy Hume at Bite Size Standards knows that Understanding "Any order columns" is difficult. In this wonderful tutorial, he explains why the order of columns in HTML can be different from their order on the screen using CSS.
Emil Stenström, web developer extraordinaire at Friendly Bit helps us remember where we've come from, the mistakes we've made and why it's taken us so long to start using standards again. See why Real hackers don't use CSS.
Dustin Diaz takes a different side in the ongoing debate and answers the question Why inline styles with strict doctypes?
Joe Kissell of Interesting Thing of the Day explains just what is so interesting about Cascading Style Sheets in the first place, with Cascading Style Sheets / Bringing sanity back to Web design.
At RotorBlog, Maris does a side-by-side user interface comparison of two similar personal web portals in Netvibes vs. Pageflakes - design and basic functions.
Artem points us over to Solution Watch to check out a review of something that should keep you distracted from work Up for Ajax Battleship? Play Sink My Ship.
Ohad of Ohad's Internet News offers a new way of writing blog posts that is an ongoing process reacting to user feedback in Evolutionary posts.
Craig at gridbuzz goes below the headlines on the Net Neutrality issue to explain What Net Neutrality is really all about.
Jon Swift takes a look at his recent Google Searches and realises that if the government is watching him, they're going to be in for a surprise.
And last but not least, Chris Quimby shares a humorous tale of helping his mother onto the information superhighway with Throwing Mom on the Highway.
Dan Webb at The Web's Bollocks has posted a great article, Cleaner Callbacks With Partial Application. It describes ways to use JavaScript closures to keep your code cleaner and more reusable, especially when creating XMLHTTPRequest callbacks. If you understand the basics of closures but want to see some practical applications, go check it out.
If you're new to closures or have been struggling to understand how they work, I recommend reading Mark Wubben's introduction, Getting Funky With Scopes and Closures. For a more detailed and thorough analysis, be sure to read Richard Cornford's JavaScript Closures.
In November, I put some tools written in JavaScript on here. These are mostly conversion tools, things like pounds to kilograms, kilometers to miles, etc.
I had the idea of coding and hosting some random JavaScript things on here, but since then I haven't added anything.
Then I forgot about them.
Now, I get most of my traffic on these conversion tools. As of recently, if you search millimeters to inches on Yahoo!, my site is #1. Because of this, I've gotten a whack of traffic just on this one page.
I wonder what it is about that page that Yahoo! considers so special. There aren't even any sites that link to it. It's really some kind of SEO marvel.
This is a last call for submissions to the first monthly Carnival of the Web. Saturday, June 17th is the deadline, as the carnival will be posted here on Sunday.
So if you have a blog that web professionals would be interested in, or if you've read something really great on another blog in the past month, please make a submission.
When early versions of Internet Explorer 7 were released, it was clear that IE would now have a search toolbar like Firefox. It was also clear that this would default to use MSN, rather than the Firefox default of Google. Google freaked out and tried to sue Microsoft, but the Justice Department said it was OK and prevented Google from doing anything about it. Google's strategy was to continue to promote Firefox, as well as give instructions to IE 7 users on how to change their default search engine.
Now, Yahoo! has released a customized version of IE 7 beta which presets the homepage and search bar to Yahoo!. Rather than fight the beast, they've embraced it and made things even easier for people who still prefer Internet Explorer. Good move, Yahoo!.
Disclaimer: I only use Internet Explorer for testing. Firefox is definitely the way to go for day-to-day surfing.
Did you ever own a directory of the web? Like this big yellow pages book with every known web page on the Internet? I did. I never used it. I guess I skimmed through it, but it was very soon out of date. Not only were half the links gone, but there were so many new sites that just weren't included. The thing is like an antique now. It'll probably be in a museum one day.
A few years later, the web got bigger and bigger. Soon it was too big to be navigated by a book, and of course search engines took over. The web was filled with many new web pages, most "Under Construction", and we were told to "Check back soon". Still, it felt like we could conceivably read the whole Internet if just given enough time. What we didn't consider was that the growth of the Internet would never stop.
Now look at where we're at. It's impossible to stay up to date on the 10 or 100 or 1000 web sites we visit without using RSS feeds. Thanks to technorati, we can see what others are saying about a topic in nearly real time. We've been forced to give up trying to "surf" the whole web, and have mostly settled down into our niches with barely enough time to do even this.
With so much information to choose from, only the very newest is often paid attention to. When you arrive at a new site, or subscribe to a new blog, do you take the time to read all the old posts? Or do you just sign up and look forward to the next posts, the newest stuff. I know I rarely have time to go back and read older stuff.
The Internet is indeed a giant repository of information, but the way many of us are using the Internet is changing along with the web itself. The blogosphere isn't just a sign of the personal web, it's also a sign of the timely web. We're less interested with what others have said about a topic, now we want to know what they've said about it lately.
A beautiful look at the web, with a reality check on just what the web is supposed to be: a collection of hyperlinked things.
Jeremy Keith's In Praise of the Hyperlink
You may not even notice right away, but I added shading to the boxes on this site. This is the final product of over three hours of working on my design.
No, I didn't struggle with making shading images for three hours. I tried to redesign my whole site from scratch. I'm getting a bit bored with seeing the same thing for over a year, and I've been told at least once that my design needs an overhaul.
I messed around with some different layouts and different looks, and some of the changes seemed good. One of my strategies was to put the side boxes with links to the bottom of the page. Although it did look a bit better and cleaner, I didn't want to lose the navigation "above the fold". I think when visitors come for the first time, these links may be the only reason they stick around.
Of all the experimenting I did, one thing was clear: I need to introduce images to add another dimension to this design. I decided that I could do this to the current design. So I did. And that's why I made the shaded boxes.
I think that rather than redesign the whole site, I'll continue to make minor improvements, move things slightly, add images, change the colours, rework the header or footer, etc. It's just too much to redo the thing from scratch, and then I'd lose all the work I've done so far.
Let me say it again in case it's not brutally obvious: I'm not a designer. I don't consider myself a designer. I have always been interested in art, and I like to draw and paint. I also know CSS inside and out. I think I know good design when I see it. But I'm no photoshop ninja. I have ideas in my head, but by the time I'm "finished" I'm looking at an ugly cheap pile of crap. This is an area I'd like to improve, but for now it's just a bit of a hobby.
Many people don't get the difference between a web developer and a web designer.. "Wait, we still have to pay someone to draw the thing? So what do you do exactly??" So maybe it would be in my best interest to tackle some web design.
If any designers out there want to pass on some tips on how to improve or which sites can teach me the tricks, I'd be very grateful.
I just wanted to give a quick congratulations to Peter-Paul Koch of QuirksBlog. He just finished a JavaScript book, ppk on JavaScript. Way to go! If you're interested in learning more about JavaScript, or, as ppk said,
if you want to congratulate me, buy the book.
Update: You can pre-order the book at Amazon.
Seth Godin gives another example of the Internet leveling the playing field. This time it's a girl named Emily finding success selling her artwork online. Seth says:
[This] should be proof to you that the whole thing is raveling (which means the same as unraveling, in case you were curious). That all the systems that kept all the processes in place and leveraged mature industries and experienced players are slowly (or quickly) filtering to the masses. Faster than you thought it would happen.
Just the other day, I saw on the CBC National a piece about a Canadian comedian, Russell Peters, who struggled to find an audience. Thanks to Google Video, his popularity has had an enormous boost. When asked about the effect of the Internet, he just said something like "that Internet thing.. I don't understand it but.. it's crazy."
Indeed, the Internet is already a place where individuals can reach wide markets and find success on their own, without the need for traditional media, Hollywood, television producers or other people in suits. The old system was great at producing one-hit-wonders that everyone liked and nobody loved. Now, there is room for everyone to find their own market, their own audience, their own place in the world.
You might have heard of unobtrusive JavaScript, but what the hell is it? Well, it's the separation of all your JavaScript from your HTML. That means putting all your JavaScript either in a <script> block, or even better, in an external file.
Why bother? Yes, sometimes it's easier to put JavaScript into onclick or onload attributes. But it's better to separate your content (HTML) from your presentation (CSS) from your behaviour (JavaScript). It keeps your HTML clean. It also makes things easier to maintain.
It's not just about the physical separation of JavaScript from HTML. It's the absolute separation. Your HTML should work without JavaScript. For example, if you have an empty <body> tag, and then attach use Ajax to pull content from the server and stick it into the body, that sucks. If somebody comes to your site without JavaScript (ie. the Google spider), they will get an empty page.
It's important that your whole site works without JavaScript. This way, your content can be used by people without JavaScript. Google's spider doesn't support JavaScript (to my knowledge). So, if you want your content to be indexed, make sure your HTML content can stand alone without JavaScript.
Unobtrusive JavaScript means adding JavaScript functionality on top of an already functional HTML site. This improves things for those with JavaScript without taking anything away from those without. Let's look at some simple examples.
The onload attribute on the <body> tag is popular. Instead of doing this:
<script>
function myLoadScript() {
// do fancy stuff
}
</script>
<body onload="myLoadScript()">
you can just do this:
<script>
window.onload = function () {
// do fancy stuff
}
</script>
<body>
There's no difference in functionality, but it does let you put your script in another file and have less stuff in the HTML. This way, you can change or remove your onload function without changing the HTML.
Here's another example. Let's say you have some JavaScript in a link to launch a popup window:
<script>
function showPopup() {
window.open('myPopupPage.html',null,"width=600,height=400,toolbar=no");
}
</script>
<a href="javascript:showPopup()">I love popups!</a>
If somebody doesn't have JavaScript, this won't work. That sucks. You can do this instead:
<script>
function showPopup() {
window.open('myPopupPage.html',null,"width=600,height=400,toolbar=no");
return false;
}
window.onload = function () {
document.getElementById('popupLink').onclick = showPopup;
}
</script>
<a id="popupLink" href="myPopupPage.html" target="_blank">I love popups!</a>
If somebody doesn't have JavaScript, they'll still get the normal link popup from the HTML alone. You won't be able to customize the size, toolbars, etc. but at least it will still partially work.
Notice that the showPopup() function now returns false. This will stop the page from doing what it normally does when you click the link. In other words, you'll only get the JavaScript popup, not two popups.
This technique can be applied to more complex JavaScript including Ajax techniques. If you have a form that is submitted in the background, and uses JavaScript to redraw the page without refreshing, great. Just add this functionality using JavaScript alone. Make sure that without JavaScript, the form just submits and the page refreshes the old-fashioned Web 1.0 way.
I will quickly mention something to silence those who are screaming at their monitors. document.getElementById doesn't work in every browser (like Internet Explorer 4 or Netscape 4), so you may want to use object detection to make sure it's supported. My policy is that if someone is using an older browser, they get the same thing as if they had JavaScript turned off.
I hope these techniques will help you to create wonderful, clean, sexy and modern unobtrusive JavaScript. Have fun!
Joe at the Working at Home on the Internet blog just blog-tipped me, so I thought I'd pass on the Link Love. The idea of Blog Tipping is that on the first of the month, you pick three blogs you read and offer 3 compliments and 1 tip. So here goes.
tip: Perhaps it's a result of your busy schedule, but I'd like to see more longer posts with more of your thoughts and less links now and then.
tip: This is hard. I'd love it if you posted more often, but not if this degrades the quality of your post. Otherwise, just keep doin' what you're doin'.
tip: Start posting again! Two in the past three months?! You used to be almost daily!
Okay, now you all have to pass the link love on.
Tantek Çelik has just announced the release of Technorati's Microformats Search! Tantek has been the pioneer and mastermind behind microformats. So far, the use of microformats was forward looking, like "One day there will be tools that search the web for microformats, and then all the hCards and hCalendars we're implementing will be useful." Well that day has finally come! Now you can search all the hCards, hEvents and hCalendar objects scattered around the web.
Also significant is the announcement of Pingerati, a ping service to announce the existance of microformats on pages Technorati isn't already indexing with rss (ie. an About page). Yet another useful tool in the microformats toolbelt.
Congratulations, Tantek, and thanks for such a great tool!
Update: Tantek has given a list of acknowledgments and thanks to all the other microformat searches and utilities that others have created thus far.
Now and then, I hear concerns about Ajax security holes. Everytime this happens, I have to stop and think for a second. What security holes? Have I missed something? Can my visitors drag-and-drop their way into my database, or use Yellow Fade Techniques to gain root on my web server?
Here's what XMLHTTPRequest does: it's a JavaScript command to load a URL from a server and do something with the response. As long as you have security on all the URLs on your web system, you have a secure web system. Ajax isn't going to find a back door that wasn't already available to anyone with a web browser.
There is no security threat to your web server from people using Ajax. In fact, the only new security threat comes from the other direction: web sites using Ajax to spy on people.
First, let's be clear about one thing: XMLHTTPRequest isn't allowed to load code from a different server. In Firefox, this is called the same-origin policy. Other browsers have similar policies. This means that the only web page that can be spying on you is the only you're looking at and using. And the only thing that can be spyed is the way you use that web page.
So how can Ajax be used against you? Well, every time you move your mouse, a message can be sent to the web server to record your X and Y position! Or the text you're typing into a text box can be sent before you're finished spell checking! Or maybe, if the web site is evil enough, the server will record every time you click on a link! Of course, these are hardly security holes. A mild invasion of privacy perhaps, but how many web sites already have outgoing links forward through a URL-tracking service? And this is even already implemented in Firefox 2.0 as a ping attribute to the a tag!
Web sites still have no way to look at your hard drive, upload files without your knowledge, or do anything else outside of the actual web page. Ajax won't be able to spy on your after you've left the evil web site. And actually, all of this evil behaviour was possible before XMLHTTPRequest came along, using hidden iframes or document.write('<script>') or many other techniques.
So yes, with any client-server interaction there is a potential for security problems. This is nothing new to Ajax or even JavaScript. If you are especially paranoid and want to keep your mouse position secret, you can still disable JavaScript. Otherwise, the web is still a safe place to be.
If you haven't yet, go get the Firebug 0.4 extension for Firefox from Joe Hewitt. Roger Johansson mentioned it, and Justin Palmer posted an in-depth walk through of the many really great features in Firebug.
The days of using alert() for debugging are over (except, perhaps, in other browsers. You can log messages and objects to the console (at info, warn, debug and error levels), trace execution, and even fire up a breakpoint with the keyword 'debugger'! Not to mention all the typical error reporting stuff and DOM walkthrough features you'd expect. Go check it out!
I just tripped across a slideshow from a talk by Mozilla's Brendan Eich at XTech 2006 titled JavaScript 2 and the Future Of The Web. Yes, I found it when I was ego searching. Regardless, it's a great talk outlining the future of JavaScript and all the new, great changes we can expect to see come out over the next two years.
I'm curious to see how quickly JavaScript 2 will be adopted by the other browsers, and how quickly web developers will start using it. I'm a bit worried that the web will be 'broken' while we wait for people to upgrade their browsers. Apparently there will be offline tools to convert JavaScript 2 code to work in older browsers. Still, I'm not looking forward to an era of having to test things across an even wider range of browsers.
The new syntax will allow for Object-Oriented coding, closures, iterators and generators to be a lot cleaner and easier, but there's nothing that isn't possible in the current JavaScript using different syntax. Even though I'm looking forward to using this new syntax, I think I'll stick with using the current state of JavaScript for the next few years even if it makes my code a bit longer and messier.
Ajax, by which I mean XMLHTTPRequest, is almost always used with some sort of server platform, such as PHP or Java, usually to retrieve data from a database. This might scare off some people from using XMLHTTPRequest, especially those who don't have the ability or knowledge to do server-side scripting. This is fine. You can actually do some things without it. I'll do a simple example with populating select boxes.
First off, we need some HTML to work with. For this example, we'll have two select boxes. When the first one changes, we want the second one to fill up with data from the server.
<form>
<select id="one">
<option value="">Please choose one...</option>
<option value="colours">Colours</option>
<option value="numbers">Numbers</option>
<option value="letters">Letters</option>
</select>
<select id="two">
</select>
</form>
Now we need some data files. Before I begin, I'll just mention that there are several ways to get back data from the server. Some people use XML, others use something called JSON which stands for JavaScript Object Notation, you can also get back raw HTML or JavaScript, and then there are other ways as well. For this example, I'm going to use JSON because it's pretty simple. You can do really advanced stuff with JSON, but I'm just going to use a JavaScript array. I'm going to create a file for each select option in select box 'one'. Each file will have an array of values to put into select box 'two'.
Update: technically this isn't JSON, even though it works. More information here.
select_colours.js: ['red','orange','black','purple','yellow','forest green'] select_numbers.js: ['3242','84930','12','5433344','8837845','1980'] select_letters.js: ['G','f','s','j','P','m']
This example isn't using a lot of data, but chances are in real life, you wouldn't use Ajax unless you had a lot of extra data to get back from the server. Otherwise, it wouldn't be worth going to the server to get the data, and you might as well just put the data directly into the page.
Any usage of XMLHTTPRequest starts with a function similar to this. It finds the XMLHTTPRequest object in a way that works across all browsers, then it sets up a callback function to do the dirty work, and sends the request to a url:
function httpRequest(url, callback) {
var httpObj = false;
if (typeof XMLHttpRequest != 'undefined') {
httpObj = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try{
httpObj = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try{
httpObj = new ActiveXObject('iMicrosoft.XMLHTTP');
} catch(e) {}
}
}
if (!httpObj) return;
httpObj.onreadystatechange = function() {
if (httpObj.readyState == 4) { // when request is complete
callback(httpObj.responseText);
}
};
httpObj.open('GET', url, true);
httpObj.send(null);
}
Now, we'll add three more JavaScript functions. First, we'll add a callback function to take our JSON data and put it into the select box:
function fillSelect(JSON) {
var selectTwo = document.getElementById('two');
// clear out existing options
while (selectTwo.options.length) {
selectTwo.options[0] = null;
}
// fill with new options from JSON array
var data = eval(JSON);
for (var i=0;i < data.length;i++) {
selectTwo.options[selectTwo.options.length] = new Option(data[i]);
}
}
Notice we use the eval() function to turn our JSON text string into a real JavaScript object.
Next, we'll add an event handler function to react when the first select box changes. This will send off the actual XMLHTTPRequest:
function onSelectChange() {
// get the value of the selected option in select box 'one'
var selectOne = document.getElementById('one');
var selectedOption = selectOne.options[selectOne.selectedIndex].value;
if (selectedOption != "") {
// find the appropriate javascript file
httpRequest('select_' + selectedOption + '.js', fillSelect);
} else {
// empty the options from select box two
fillSelect('[]');
}
}
Lastly, we need to assign the onSelectChange() event handler to the select box. We'll do this in a window.onload function:
window.onload = function() {
var selectOne = document.getElementById('one');
selectOne.onchange = onSelectChange;
}
There you have it! If you want to see it in action, click on the files listed below:
One thing that was big at JAX were these toolkits that allow Java developers to program user interfaces the way they're used to, by using libraries similar to SWT or Swing.
Two big ones I saw were Rich AJAX Platform (RAP), based on SWT, and wingS, based on Swing.
Now, Google has released the Google Web Toolkit (GWT). Not tightly based on a previous Java UI framework, GWT seems to be another good option for developing complex web user interfaces in Java.
These toolkits make things a lot easier for Java developers to make web user interfaces without having to master CSS and JavaScript. Java developers can stay in Java and have web interfaces generated for them. The result will be more rich web-based applications, something we will all benefit from.
Personally, I still have a lot of fun working with JavaScript and CSS by hand. I don't know if I'll ever start using one of these code-generating frameworks. I suspect those of us who have the patience and passion to put up with this stuff are in the minority.
I'd like to announce The Carnival of the Web. This will be a monthly blog carnival showcasing the best posts in the wide world of web professionalism. The first carnival will take place on Sunday, June 18th, 2006.
This carnival will be aimed entirely at web professionals. These include web designers, web developers, web masters, search engine optimizers, or anyone else who works with or creates web sites. The posts can be about any topic of interest to web professionals. This includes web design, HTML, CSS, JavaScript, Ajax, SEO, usability, accessibility, web standards. General topics relating to the past, present or future state of the web will also be very welcome.
If you have a blog and would like to participate, please send in your submission!
If you want Ajax on your web site, I'm your man.
Although I'm already available to do all types of web freelancing, I want to emphasize that I specialize as an advanced JavaScript, CSS and Ajax freelancer. I've been doing Ajax and other advanced JavaScript for over two years now, and it's really my favourite thing to do.
If you're not really sure what is possible, I can also offer suggestions on ways to improve the usability of your site while still following best practices, web standards and accessibility guidelines.
So if you want to use some animation, auto-complete, XMLHttpRequest or any of that other Ajax stuff on your web site, or if you are a web developer or designer who needs help with JavaScript, please contact me.
There is a new online peer-to-peer loan concept that is growing, and I think it's a great idea. (Via slashdot). Two new companies, Prosper and Zopa, are allowing people to ask the public to lend them money. Anyone can bid on lending the money, stating their own interest rate. Whoever offers the lowest interest rate gets to lend the money (and make the interest).
The result? A pure capitalist financial system that doesn't involve banks. Anyone can get a loan, and anyone can make money by lending money. Everyone benefits.
This also reminds me of Kiva, a web site that lets people lend money to those in developing countries. I think this is a great alternative to just donating money since it helps build up the economy in these countries. It's very cool to see the idea being extended to the rest of the world.
Update: Only people in the US can use Prosper, and only people in the UK can use Zopa. I hope they (or others) make this available to the rest of us (specifically, Canadians living in Germany)!
I'm absolutely in love. While I bored was at JAX, I searched around for a PHP framework like Ruby on Rails. I already knew about CakePHP, but I wasn't convinced. I looked at a few others, but nothing caught my eye. Then I discovered Code Igniter.
Code Igniter comes from the people who make Expression Engine. I had already heard great things about that, and I had even considered purchasing a license. Code Igniter, however, is free and open source. It's quite new (first beta was released in February) but it is incredibly professional and already very stable.
Code Igniter does absolutely everything I want it to, and nothing I don't want it to. It's incredibly simple and clean, so there are no surprises or weird tricks. It forces you to organize your code using an MVC structure (actually, a VC structure — using a model is optional). This keeps your code cleaner and easier to maintain. It also comes with a number of libraries that help with common web development things like email and uploaded files.
This weekend, I rewrote my whole custom-made blog code for this site. It only took about 4 or 5 hours, and it was actually fun to do. It also reduced the amount of code I had, and makes it much, much easier to maintain and change in the future. For example, until now I was too lazy to add contact pages properly, so I just added blog articles for Contact Me, etc. and pointed links at these. Now, I've changed the pages to use /contact/me and /contact/hire, and I could easily reuse my blog template. This change took about 10 minutes.
By default, URLs are of the form /class/function/parameters. But if you want to do something different (I use /blog/2006/5/article-name), you can set up routing rules for anything you want. Actually, Code Igniter is totally flexible to let you do whatever you want. Anytime I got stuck, I poked around in the documentation and found that there was something in place specifically for my problem.
Also wonderful: only the minimal amount of PHP is loaded to create each page. You can load classes globally, if you need them, but by default, you only load what you need when you need it. This keeps every page as fast as possible, something I was worried about with other frameworks like CakePHP.
Okay, that's enough ranting. If you use PHP, check out Code Igniter. There are some videos you can watch to see just how easy Code Igniter really is. The user guide is also a pleasant read and explains everything really well.
I had a really nice time in Wiesbaden, Germany at JAX 2006. Apart from being in a gorgeous city, the conference had some interesting content. Most of it was about Java technologies and I won't bore you (and myself) with too much of that, but I also attended sessions on Ruby on Rails, Groovy and AJAX.
It was interesting to get a sense of where the industry is moving. Dynamic languages are becoming much more important, although I find "real" developers are hesitant to move in that direction. Personally, I love the concepts behind Groovy and Ruby. They speed up development and take away much of the painful grunt work involved in regular programming. They might be slower, but in the future as servers get faster, I don't think this will be such a problem.
Another striking trend was an overwhelming buzz and a sense of confusion and mystery around AJAX. Remember, this was a Java conference so many of the participants don't work directly on the web. Some only heard of AJAX for their first time at JAX. There seems to be a big divide between programmers and designers, and neither seems to understand advanced JavaScript programming. Programmers have avoided JavaScript, considering it a simple scripting language. Designers have avoided it for being a programming language. Now that some really sophisticated user interfaces are possible on the web, both sides are starting to get really excited.
Until now, I've totally hated the term AJAX. It's just a buzzword slapped on to something that JavaScript developers have been doing for years, and you know how much I hate buzzwords. Now, I see that it has helped to create awareness and get people excited about the possibilities in the browser. I don't think we will be using the term AJAX for many years, but at the moment it has gotten many people to take web applications more seriously and to start thinking about how they can improve the web. This is always a good thing.
From Tuesday (May 9th) until Thursday (May 11th), I'll be attending JAX 2006, a Java conference in Wiesbaden, Germany. Not only will I learn all about what's new in the Java world, I'll be able to really test out my knowledge of German. (Eek!)
If any of you are going to be there by some freak chance, let me know so we can meet up. For the rest of you, I'll be sure to write about anything that relates to web development and the future of the web.
There is a new charity drive web site Flip Cancer The Bird that will donate $0.50 for each picture sent in. The catch: the picture must have you giving the finger to Cancer.
I think this is a fun idea. I'll have to send in my photo next. :)
I just submitted my first article to EzineArticles.com. I just heard about this site a couple of days ago so I thought I'd try it out. Basically, it's a way to get articles read by a new audience. I won't get paid for it or anything, but ideally people will discover this blog and my writing if my articles get republished in various e-zines or newsletters, etc.
If you do some writing and want to try spreading your articles a bit further, it might be worth looking in to. I'll post again on here if anything incredible comes out of it (though I don't except much yet).
I really hate phishing emails for two reasons. First, they're just more annoying spam in my inbox. Second, I know that some innocent people out there are going to be frauded because of these emails.
Thanks to the Anti-Phishing Working Group, there's something we can do to help stop phishing. And it's really easy too.
The next time you get an email asking you to log in to a banking or credit card site, even if it's from a bank you've never heard of, please report it. You only need to:
Even if you forget all this, at least remember that you can always search "report phishing" on Google to find the Anti-Phishing Working Group — right now it's the first result.
Phishing will never go away completely, but the more people that report it, the less victims there will be.
I was worried at first when I started my personal blog. I knew that all my friends and family would be reading it. How would I write a blog post so that it would be suitable for both my grandmother and my long time friends?
I was even more worried when I started this blog. I was going to have some kind of professional persona on top of my personal persona. Now my friends and family could read this site, and strangers and colleagues could read my personal site. How could I possibly express myself consistently to such a wide range of people?!
Well, it turned out to be not a big deal at all. It forced me to do something pretty great: it forced me to be myself. It forced me to be honest and transparent. I can't pretend to be something I'm not, because anybody can call me on it. Not on this site, nor on my personal site.
It took some time to get used to it, I suppose. I shared some things on my personal site I wouldn't normally share with everyone, but afterwards it was totally normal. I've also expressed ideas on here I wouldn't normally talk about with friends and family and I'm glad I've done it.
So when people tell you to "find your voice" when writing, they're not suggesting you try to create a brand new voice. Instead, you need to find your voice, the one true voice inside you, and share it with the world.
Maybe this is common knowledge to some, but I just figured it out today, so I thought I'd share it.
Before, if I wanted to find the maximum or minimum number in a list of 3 or more numbers, I'd do something like:
max = Math.max(Math.max(Math.max(a, b), c), d); min = Math.min(Math.min(Math.min(a, b), c), d);
But Math.max and Math.min take as many arguments as you need, so you can do this instead:
max = Math.max(a, b, c, d); min = Math.min(a, b, c, d);
Productivity is a hot topic these days, so I thought I'd contribute to the ever-growing mountain of hints and tips with a few things you can do to Get Things Done:
Write down a list of all the things you have to do. When you figure out more things to do, just add them to the list. I just use notepad for my list.
You don't actually have to write down the priorities somewhere. It's probably pretty obvious, so you just need to keep it in mind. The key is to do higher priority things first. For example: Finish the project your boss keeps asking about - high priority. Catch up on 2035 unread blog posts - low priority.
Seriously. Right now. Go do them. Don't even read the rest of this article. Go. Now. Do the dishes, or go back to work, or write that blog post or whatever it is you have to do. I'm not kidding. Close your browser.
Think of all the things you could get done with the time you spend trying to figure out how to get all these things done. Actually, nevermind, don't think about it.
I hope these tips are useful to you. Actually, if you're reading this far they obviously haven't been. So, seriously, either go back to work or just give up on being productive altogether. Whichever one is fine with me.
I wrote an article for the Working at Home on the Internet blog, about just that - working at home on the Internet. Go check it out.
As a Canadian living in Berlin, I'm constantly learning German, and the best resource is a good dictionary. Paul Hemetsberger's dict.cc is not only the best online English-German dictionary I've found, it's one of the best examples of how an online resource should act. Even if you have no interest in learning German, it's worth having a look just to see what makes a great site.
This site is optimized for people who will be using it regularly. You can click on 'Remove Ads' which will hide all the ads until you close the browser. You can also click on some section titles to hide the sections you don't need, which cleans up the interface, and these preferences are remembered using cookies.
There are simple features that make the site even easier. Alt+S will put the cursor into the search box, which is very handy when you need to do multiple searches. You can simply enter the URL dict.cc/word to automatically search a word (I wish Google would do this!). There is even a slimmed down "pocket" version at pocket.dict.cc, which has become the only web site I actually use on my cell phone.
Everything in the results is clickable. You can click on a single word to look up that word, double-click a table cell to look up the whole phrase, or click on a drop-down menu beside each result to reveal a number of options. You can hear a spoken sample of the word or phrase, which doesn't launch a popup or make you save an mp3 - it just plays instantly using Flash. There are also links to the word in the other popular online dictionaries, in case you aren't satisfied with the results or want more details.
Although some of the extra features require JavaScript, JavaScript isn't required to use the site. The JavaScript is completely unobtrusive - even the Flash is added to the page using JavaScript.
The site is built on contributions from users. This means that the dictionary is as up-to-date and complete as possible. For me, this is very important - I want as many alternative translations as possible to understand the different ways German words can be used. Anyone can suggest a translation or correct an existing translation, and all changes go through user-based moderation. And since the data is user-contributed, the author Paul doesn't claim ownership to the word list. It is available for download as a text file.
There are tons of other cool little features all over the site, too many to go into here. You'll have to play around with it yourself.
There is very little I would do to improve the site. Well, the HTML and CSS don't validate. And it would be better if there was a way to access the extra functionality (like the voice output) without JavaScript. But from a usability and functionality standpoint, it's totally perfect. Thanks, Paul!
What's the point of this site? Well, the Big Picture is an outlet for me to write about my greatest passion: the Internet, the direction it's moving in, and the way it is changing the world. But at the same time, I work as a web developer, so this is also my forum for sharing different problems and tricks I come across, as well as touting the benefits of web standards and best practices.
The result is, I have articles like Setting a form field to null or undefined and Let's get personal on the same site. This means that people who don't do any JavaScript coding have to put up with my technical articles. And people who just want my tips and tricks have to put up with my, let's say, fluff articles.
Luckily, these both roughly fall under "The Future of the Web". If I started posting pictures of cats, or investing advice, or whatever, I might get more complaints. But even under the blanket of "The Future of the Web" I have some thinking to do about my target audience.
I don't really write the techie articles for regular readers so much, they're more geared at people searching the web on, say, "setting form field null javascript". Nor do I write the fluff stuff geared at search engines; they're mostly for the regulars.
So how do I solve this apparent dilema? I could create multiple RSS feeds for categories. I could spin off a second blog. I could drop one of the topics altogether. Or, I could just ignore the problem and let people skim over the topics they have no interest in.
Well anyway, I haven't solved the problem yet. I've thought about these options, but I haven't decided what I'll do. But I'm aware there is an apparent identity crisis looming.
How do you deal with identity and branding, and evolution over time? Do you put much thought into this before creating a site or blog, or do you just let it evolve over time and define itself? Where would you like to see this blog go?
I was reading Tara Hunt's blog, in which she talks about how communism relates to cluetrain, the "new" web, and all the great stuff we're seeing happen on the Internet. I think she was absolutely right to suggest the distributed nature of the Internet will let the common people take power away from the ruling class.
She's had to fight off a lot of criticism though, since communism has such a negative connotation, especially in America. But communism, ie. The Communist Manifesto, has nothing to do with killing people or Hilter or whatever. It's just about bringing power to the people. Well, it seems like it's an argument that's impossible to win so she's had to focus closely on marketing, with Pinko Marketing.
I think there's a lot of value in this comparison though, outside of marketing. So, I'd like to suggest another -ism that doesn't have the same negative connotation, but nicely captures the same spirit of Power to the People: Distributism.
The idea behind Distributism is (from Wikipedia): "the ownership of the means of production should be spread as widely as possible among the populace, rather than being centralized under the control of a few state bureaucrats (some forms of socialism) or a minority of resource-commanding individuals (capitalism)".
This relates to a ton of things happening these days. Think of "the means of production" in terms of music recording technology, self-publishing, video technology, etc. and the "minority of resource-commanding individuals" as the music, book, magazine and movie industries.
Like I was talking about recently, the Internet is bringing power to the average person in many ways, including in business. More and more people are becoming entrepreneurs. Some people even quit their job, go independant, then turn their old job into their first client, fulfilling the same role they did before. Yes, someone can switch from being employed by a company to being independant and still working for the company, and hardly anything changes. Why doesn't everybody do this?
Well that's kind of the concept of Distributism (or what I gather from it anyway). Ideally, everybody would have their own business. People would get together to form partnerships or co-operatives to share some resources and achieve common goals. People who have their own business, entrepreneurs, artists, or whatever independant people are just that: independant. This is really Power to the People.
This is the future of the web. Individuals doing whatever they want, making a living from it, starting their own microbrands and picobusinesses. People coming together from across the world to work together. No longer does one need a lot of money to create a successful business. No longer does one even need to leave the house to do something big in the world.
This isn't just the future of the web. It's the future of the world.
Thoughts? Agreements? Arguments?
I came across another browser difference while debugging some JavaScript. Let's say you were trying to set the value of a form field the following way:
document.getElementById('formField').value = someFunction();
But, it just so happens that someFunction() returns null. What happens when you set a form field value to null? Well, in Firefox and Safari, the value will be set to the empty string, "". Internet Explorer and Opera will set the field to the string "null".
Similarly, if the function forgot to return a value, the form field would get set to "undefined" (this is the same in every browser).
The moral of the story is, be careful not to let a form field value get set to null. You could avoid both these situations by doing something like:
document.getElementById('formField').value = someFunction() || "";
Note: This would actually replace undefined and null as well as 0 and false with "".
I think personal homepages are going to be the next big thing on the Internet. Seriously, hear me out.
When the web was new, pretty much everyone got themselves a Geocities or Tripod account and set up some kind of web site. That's what's so new and special about the Internet: anyone can have a web site. Not everyone can have a TV show or a Radio show or a Magazine column. Plus, web pages can reach even more people than any TV show or Magazine can.
Then, all these companies figured out they need web sites. All you heard about was eBusiness and dot-coms and how the Internet was changing business (though nobody knew how, exactly). So the Internet started to get all corporate.
Now, "suddenly", personal web sites are big again. I'm mostly talking about blogs. But what's really special about blogs? The fact that one person can easily get a site and start writing, and build an audience, even more readers than some newspapers out there. That's pretty crazy.
The whole nature of the web makes this possible. It's totally leveled the playing field. Anyone can do good on Google without spending a cent. Good content thrives on the Internet. You just have to contribute something valuable and people will find it.
Okay, so web sites with pictures of cats aren't so interesting or revolutionary. But personal doesn't have to be boring. This site is a personal web site. It's about web development, but it's just my take on it. Stuff I've figured out, thought about, and so on. It's my personal contribution to the web development world.
So when I say personal, I mean individual. I mean that one person by themself can do bigger things on the Internet than they can in real life. They can publish a book. They can sell (or give away) their music. They can make movies. They can create a popular comic strip. They can start groups. They can start businesses. They can run a huge business just by hiring and outsourcing to other people on the web. And these other people can just be individuals too, doing the same outsourcing themselves.
There are a LOT of people who don't have web sites yet. And all of these people have special interests, passions, talents and things to say that are just hiding away. Soon, these people will make pages (whether on MySpace, blogger, LivePages, or something else). They will start to open up and share their hidden talents with the rest of us.
Everyone benefits from this. The more information and entertainment on the web, the better. The Good Stuff will rise to the top, and the more available, the better the Good Stuff gets. And, of course, the people making the Good Stuff will benefit too. This will just make more incentive to make Good Stuff, and you can see where this is going.
So what can you do? Get out there and contribute. Don't be shy. Get your drawings, pictures, movies, stories and rants on the web. Help your friends and family to do the same. Do what you love, do your best, and do it in public. Your audience will find you.
Joseph Hauckes from the Working at Home on the Internet blog has asked me to review his other site, the Working at Home on the Internet Web Page. I've been reading his blog since the beginning, and it's become one of the few blogs I read daily. He posts very regularly every day (he's only missed one day in the past six months), and it's a pleasure to watch his story evolve over time. I look forward to seeing where it goes.
The website is a collection of resources and advice for people starting their own Internet-based businesses. At first, the site looks like a blog. It takes some time to find the resources pages including Scams, Forums and Blogging Services. The links to these pages blend in to the side of the site. The site could use some clear navigation, ideally at the top of the page. This would help make the site easier to use and explore.
The design is nothing spectacular, but it doesn't distract from the content either. On the homepage, the left navigation takes up most of my screen, and I have to scroll to the right to read the content. The rest of the pages don't have this problem, but it's the first impression that counts.
This site was designed and built using Microsoft Frontpage. As a result, the HTML doesn't come close to validating. There's scattered inline CSS and even font tags. It's just not easy to produce valid code with WYSIWYG tools without being strong in HTML and CSS. I hear Microsoft's new HTML editor Expression is supposed to help with this.
The most important thing about any website is its content. However, it's important to make sure this information is easy to find. Joe's site may not win design awards, but it has a number of great articles to help people getting started with their own sites, and that's what counts.
I'm going to start doing the occasional Website Review. Consider yourself warned. I figure it's worth taking a look at the good and bad parts of other sites so we can all learn from their successes and mistakes.
I'll mostly be focusing on design and usability, usage of web technologies (ie. HTML, JavaScript and CSS) and whatever else strikes me as interesting and unique.
If you have a site you'd like me to review, let me know.
I didn't want to put my email address on the site, purely for spam reasons. I thought I could avoid spam by putting a contact form on the site instead. Now, I get more spam than I used to from comment spam bots using my contact form!
There is no escape, and I will have to accept this as a part of my destiny...
The golden rule of URLs: They never change.
This certainly isn't a new topic. In fact, it's as old as the web itself. It seems like it's been long forgotten, brushed off and ignored. It is still highly relevant and can't be stressed enough.
When designing URLs, assume they will be still be used 1000 years from now. Why? People already assume they won't change. They bookmark the page, search engines index the page, other sites link to the page. It's your responsibility to keep the page there.
Web applications, search engines, online shopping and sadly even simple web sites have designed URLs to be disposable, full of variables including session IDs and other junk. How often have you sent or received a URL that didn't work because the "session has timed out" or some other reason?
You can improve the permanence of a URL by making it as simple as possible. Try not to include a file extension (.html, .php, etc.) Try to split things up into a logical hierarchy. Using dates in the URL like /2006/3/ can help a site grow over time, but so can using a unique ID such as a number or title.
Sometimes URLs just have to change. Perhaps the original URL was one of those temporary, junk-filled ones and you are migrating to a permanent URL system. When this happens, make sure you put something in place to send the visitor to the new location.
There is already a great document written on this topic, so rather than repeat everything, I will include it here. I highly suggest you read it if you haven't yet:
Lately, I've been thinking a lot about Flash. My girlfriend wants to set up a web site. She wants it to act like a lot of her favourite web sites: Flash sites. At first, I wanted to explain to her why this is such an awful idea.. but I couldn't. I couldn't because I realised a Flash web site can be perfectly accessible if done properly.
Then, I saw the video player from YouTube and realised, it's perfect. It's perfect because users don't have to choose from Windows Media Player, Quicktime or Real. They just need Flash (and everybody has Flash). This made me rethink what Flash really offers. Here is a single plugin that opens up Video and Audio capabilities, even streaming and bi-directional. This alone is reason enough to welcome Flash with open arms.
If we use Unobtrusive Flash Objects (UFO), or some other JavaScript-based Flash deployment method, nobody can complain. We can deliver alternative content for those without Flash, the disabled and search engine spiders.
Flash can be a wonderful, powerful tool when used properly. It's important to treat flash the same way we do images. They can improve the experience for many of our visitors. For all others, including search engines and those with disabilities, we need to make an alternative available.
So what's next with the web? Will we see the next big thing come when CSS3 gets adopted? Will there be a revolution on the Internet when browsers support XHTML 2? No, of course not. These things might make life easier for us, but they aren't going to change what we can do right now. We already have all the tools we need.
Even XUL or XAML will just make things easier. They're not going to change what is possible. We can do anything right now using JavaScript, CSS, HTML and (for the really tricky stuff) Flash. We can communicate to the server in real time with XMLHTTPRequest or Flash Remoting. We can make complex interfaces that update themselves. Nearly anything that is possible in a desktop application, and so much more, is possible on the web.
So what does this mean? It means we're not waiting for anything except new ideas. Whatever the coolest, greatest new thing will be in 2010 will probably have been possible right now, if only we could have thought of it.
It's only our perception that changes over time. For example, Google Maps used technology that was there for years to do something very useful, and it pushed the limits of what we thought were possible in a web page. And it didn't take long for Microsoft and Yahoo to roll out their imitations. We could have had maps like this years before, if only someone would have thought of it.
It'll take some time to explore what other possibilities exist in the technology we have available. But there's no need to wait around. Let's see what's possible today.
Okay, some time ago I posted onAfterPaste, a way to run some code after pasting. You can actually do the same thing with any event. Let's say you want to put an onclick handler on a submit button, but you don't want the function to execute until after the form is submitted. You may want to close the window after launching a new window or submitting a form, but putting window.close() in the onclick would prevent the form from being submitted. Then, do this:
function onAfterClick (e) {
window.close();
}
var submit= document.getElementById('submit');
submit.onclick = function(e) {
setTimeout(function() {
onAfterClick(e);
}, 1);
}
That's it. It's like the browser processes the click handler, then goes and does it's default click behaviour, then executes the timeout function. So it's almost a kind of magic.. but not really. Anyway, setTimeout is a great tool for making things happen at the right time.
The U.S. has granted a patent (via) to a design company, Balthaser Online, for Rich Internet Applications, including AJAX, Flash and Java.
Reading the abstract in the actual patent closely, it seems to me they've only patented the creation of rich applications from over the Internet. Their main product, Balthaser:fx, is used to create Flash movies over the web. This seems to fit my interpretation. However, the news article I linked to suggests the patent might include all rich internet applications.
What does this mean for the web? Who knows. It'll be up to this company, and the U.S. courts, to decide what this patent includes and doesn't. Nonetheless, I think this is another great example of why software patents are total bullshit.
That's right, Google's Toolbar PageRank seems to be updating today. It seems really uneven though. Some pages are updated, others aren't. Perhaps it'll take some time to finish updating. Currently this site is still sitting at a PR2. Let's see what happens by the end. :)
By the way, you can see the different PageRank values with this Live PageRank tool. It'll give you an idea of how your pages are doing across different data centres, and compare Toolbar PageRank to "Live" PageRank. Good luck!
Update: Live PageRank is now a thing of the past. It is reporting 0 for every domain, and Matt Cutts doubts this will ever change. Well it was fun while it lasted.
Semantic HTML means using HTML tags for their implied meaning, rather than just using (meaningless) div and span tags for absolutely everything. Why would you want to do this? Depending on the tag, the content in the tag can be interpreted in a certain way. Here are some examples.
If you use <h1> instead of <div class="header">, and <h2> instead of <div class="subheader">, et cetera, Google and other search engines will interpret your headers as being important titles in your page. This way, when people search on the words in your headers and sub-headers, your page will be considered more relevant (and rank higher). Plus, it's much shorter and cleaner.
This works both ways: don't use header tags for anything except headers, especially not increasing your font size or outlining your search engine keywords. This way, your page can be parsed for structure (you can do this with the W3C HTML Validator). This structure can then be used by screen readers or other tools to build a table of contents for your page.
The <label> tag is so sadly forgotten. It's not immediately clear what the point of using it is, so very few web pages take advantage of it. The label tag is used to identify a label for an input field, for example "E-mail Address". It can either be used be wrapping it around the text and input field like: <label>First Name: <input name="fname"/></label>, or it can be used with the for attribute like so: <label for="fname">First Name:</label> <input id="fname" name="fname"/>.
Why use the label tag instead of <div class="label">? Well, it's shorter and cleaner. But it also let's screen readers and other tools identify the text associated with an input field. Without using the label tag, it can be very difficult for some people to know what is supposed to go into your form fields.
These days, everyone's moving away from using tables. This is great because tables aren't intended for structuring the way your web page looks. But tables still have a very important purpose. Any time you need to display data that would go in a spreadsheet, tables are here to help.
When using tables, there are a number of tags and attributes that aren't widely used, but are very important for accessibility. Use the summary attribute to give a longer summary of the data in the table. Use the <caption> tag to give a brief title to the data. Use <th> tags to identify the column and row headers in your table. Then, you may want to use the headers attribute on the <td> tags to identify which headers apply to that cell. For more examples and details on accessibility with tables, see the W3C's Accessibility Guidelines.
Lists are the new tables. Whereas tables are intended for grids of data, lists are intended for lists of content. This is great for us, because most web pages are essentially lists of different things. For example, look at this site. On the front page, I have a list of blog entries in the centre. On the sides, I have lists of links (archive, categories, et cetera), and the sides themselves are lists of lists. If I had used tables, I would've been saying "this stuff on the left has something to do with the stuff in the middle", but it doesn't, really. By using lists, I'm simply saying "this stuff is a list of items that have something to do with each other", which they do.
You have three types of lists to choose from, but choose wisely. There are Ordered Lists (<ol>), Unordered Lists (<ul>), and Definition Lists (<dl>). Only use Ordered Lists when the entries have some kind of order. Only use Definition Lists for definitions (eg. for a glossary). Use Definition Lists any time you need name/value pairs, or when you need to break your list up into sections. The rest of the time, Unordered Lists are a safe bet.
Lists not only give structure to your page, they're incredible handy for styling. You can just put an id or class on the outer tag (eg. <ul>), then style both the outer tag, and the inner <li> tags.
Try to use the full variety of HTML tags whenever possible. Sometimes you'll be stuck with using <div> tags, but try to limit them to whenever you can't find a suitable HTML equivalent. At the same time, try to avoid using HTML tags for anything except their intended purpose. By doing this, your HTML will be cleaner, and its structure will be more readable and understandable -- not just to people but to screen readers, search engines, and other programs and tools.
As I've said before, and I'll say again, the last thing the web needs is Buzzword Hell. All buzzwords do is distract from the real tangible ways we can improve the web. So now, I introduce a way you can help save the world from Web 2.0 buzzwords!
I just had a look at the WayBack machine for thefutureoftheweb.com. Turns out someone else had it before. Creepy.
Have you ever wanted to prevent a JavaScript event from firing when it has been bubbled up from a child element? For example, let's say you have an onMouseOver event for a parent element. Anytime the mouse moves over any of the children elements, the parent's onMouseOver event will keep firing. Or, let's say you have an onMouseDown event on a parent and another on its child. Both onMouseDown events will fire when someone clicks the child. Sometimes this can be a real pain.
Anyway, enough examples, let's look at a way to avoid this. We need a way to fire an event only when the element with the event handler is the target element of the event. Here's the solution event handler:
function eventHandler(e) {
e = e || window.event;
var target = e.srcElement || e.target;
if (target != this) return;
// the rest of the function
}
Simple enough, once we have the code. Let's look at what it does.
First, we find the event object. In Firefox and Safari, it's a parameter to the function. In Internet Explorer, it's in window.event.
Having that, we need to find the target in the event object. This is the first element the event fires on, the inner-most or top-most element. In Safari and Firefox, it's target, but in Internet Explorer it's srcElement.
Finally, we will compare against the element the event is attached to. The element the event handler is attached to can be accessed easily with the this variable.
For more information on event handlers, I highly recommend the excellent resources at QuirksMode:
Update: you need to do a little bit more if you are dealing with mouseout events. If you move the mouse into a child, this triggers the mouseout event on the parent. In this case, the target will match the parent. So, you'll also have to get the 'related' element (the child) and make sure the target isn't one of the ancestors. Here is the updated function for mouseout events:
function mouseOutEventHandler(e) {
e = e || window.event;
var target = e.srcElement || e.target;
if (target != this) return;
var related = e.relatedTarget || e.toElement;
while (related != this && related.nodeName != 'BODY')
related = related.parentNode;
if (related == this) return;
// the rest of the function
}
Special thanks to QuirksMode's Mouse Events page for helping me figure out that one!
I know, this question has been answered thousands of times. Even still, nobody can agree on what it is exactly. Here's my take.
Web 2.0 obviously implies the "next version" of the web. Ask Tim O'Reilly (who coined the term to promote a conference), and he won't really be able to summarize it either. He'd rather define it by example. DoubleClick is Web 1.0, Google Adsense is Web 2.0. Personal websites are Web 1.0, blogs are Web 2.0. Content Management Systems were Web 1.0, wikis are Web 2.0.
Web 2.0 is said to include everything from tagging, Ruby on Rails, AJAX, peer-to-peer, RSS, the perpetual Beta, and user-contributed data. Let me propose this: Web 2.0 includes anything that was done successfully on the web in 2005. There, I've said it. Now, I'd like to propose something else: Let's focus on the different ways the web has improved, and let's never use the term Web 2.0 again. Seriously, starting right now. Who's with me?
Having said all this, the many different definitions can finally be read without that nauseous feeling. Don't worry any longer that your website is running the wrong version of the Internet, just relax and take a look at how far we've come. It's not worth much to say "This website follows the new trends in web sites, this one doesn't". There's certainly no need to start a new industry over it. Instead, let's just see what works and what doesn't.
If we spend all our time defining such a vague marketing term, we're going to severely miss the point. There is no Web 3.0, and there needn't be a Bubble 2.0. We have a lot of really great examples to follow, and there's still a lot that hasn't been done. So let's just keep doing what we do best.
So let's see what we can do with Folksonomies, let's find things every web site can learn from blogs, and let's see what new directions we can go in in the future of the web.
Over the last few posts, I've been trying to redefine "Web Standards", or rather, expand the definition to include things outside the validation of HTML and CSS. I wanted to talk about the larger picture of doing things the Right Way. Then, Jim left this comment:
Please, do yourself a favour and stop treating "web standards" as a meaningless buzzword that you use as a synonym for "code I like". [...] It means one thing and one thing only: to comply with rules described in "the" standards (in reality there's many standards to choose from).I have to admit, he's absolutely right. "Web Standards" refer to the actual specifications for web technologies, notably HTML and CSS. Indeed, the Web Standards Project are only advocating adherance to the W3C Standards for XHTML, XML, CSS, etc.
I asked Jim for a better term, and citing this blog post he suggested "Best Practices". This really expresses the intention here, that we should be doing things a certain way because it's the best way.
I've been thinking about this a lot since, and went back to Molly's infamous post where she coined the term "New Web Professionalism" to describe this Right Way Of Doing Things. This is just expressing the same concept in different words, and it's never the words that matter. It's what the words represent. As an industry, we need to encourage a certain level of quality, a certain, shall we say, standard.
So, Web Development Best Practices? Web Professionalism? Web Professional Standards? I hate buzzwords as much as anyone, but it seems like we need one here, some piece of jargon that lets everyone else understand what it is we're talking about. Don't we?
Then again, a buzzword is the last thing we need here. It would only distract from the underlying point. We can still refer to Accessibility, Web Standards (that is, valid HTML and CSS), Semantic Markup and Unobtrusive Javascript. And by doing so, we won't forget what it is we're talking about. We won't end up with some empty marketing speak promising something as vague as "Best Practices" when they have completely ignored Accessibility.
I won't go so far to rename my last posts, but for now on I will be much more clear when I talk about these and other Best Practices, and will forever hestitate to throw around the term Web Standards to mean anything except valid code (which, to be honest, is the least interesting topic amongst Best Practices).
Right now, A List Apart is asking its readers what they love or hate about the web. I just sent off mine, but I thought I'd put it here so it doesn't go to waste if they don't include it in their next issue:
What do I love about the web? Anybody can have a voice. It just takes one person with something to say to make a huge difference. The whole world is having a discussion at a round table. Everybody is an expert. Education, social status, location, race, gender, etcetera are completely irrelevant. All that matters are thoughts and ideas.
Not merely an ideological utopian vision, we are already living this reality. Blogs are not simply a new trend in marketing and journalism, but the beginning of a fundamental shift in the way the world interacts. We, the people, run the world. We are growing less reliant on government and big business to get things done and are doing things ourselves. Together, we can do anything, and nobody can stop us.
If you want to submit yours, they say:
Send yours to valentines06@alistapart.com and include your full name, e-mail address, and occupation, and a statement giving us permission to publish your remarks. We reserve the right to edit responses for length and to correct spelling errors.Update: Indeed, mine was included. I even got to have little AJAX and DOM sweethearts beside mine :)
Why do web standards matter? It's easy to say that web developers who ignore standards are unprofessional, but it's not so easy to explain why.
(If you haven't yet, read my last post to see what I mean by 'web standards'.)
Web standards are fun, cool, exciting. Right? This might be reason enough to use them on your own web sites, but you won't be able to convince your clients to use them just because they're cool (that is, unless your clients really wants to impress their web developer friends).
What do your clients care about? Visitors, of course. The people actually using the web site. If they don't notice a difference, what's the point, really? Sure, your visitors might judge your web site with the W3C Validator, but face it, only other web developers are ever going to view source. On this web site, my visitors ARE web developers. But what about the 300 billion other web sites?
Now, hold on a sec, I didn't just say we should go back to designing with nested tables and invisible GIFs! I'm just saying we need to focus on the goal here: benefiting our visitors. So how do web standards benefit our visitors?
The site will download faster because the HTML will be smaller. If there is a single external CSS file for the entire web site, visitors can download it once and cache it, making the whole site download faster. Also, browsers can draw borders and background colours using CSS a lot faster than downloading border and background images.
If you've separated design from content, users without CSS can still get the content and use the website. If you've separated the site's behaviour from the content, users without JavaScript will still be able to use the site without a problem. If you addressed accessibility, you allow visitors with disabilities to access the site. The last thing we want to do is turn visitors away just because of how they choose to surf the web.
How can people benefit from your web site if they can't even find it? (That is, unless your web site doesn't benefit them at all, in which case web standards aren't going to make any difference.) The search engines don't award points for design. All the extra tags and attributes will just distract away from the content. Using text instead of images and using semantic HTML (especially h1 tags) lets the search engines better index the content and interpret the structure, and this will help the page rank higher in search results.
These should be reasons enough to stick with web standards when creating web sites, and certainly enough to convince sceptical clients that web standards are the best choice. Next, I'll list some ways using web standards benefit web designers and developers.
Update: When I say 'web standards', I really mean 'Best Practices'. Read more here.
I'd like to talk about web standards in the future, but I realised I need to first define what it is I'm talking about. So, this is what I mean by using 'web standards':
The point is simple: if you're using a standard format, use it correctly. However, just because your page is valid doesn't mean it's perfect. For this, the W3C's HTML Validator and CSS Validator are your best friends.
Use CSS to describe how things should look (fonts, colours, widths and heights, borders, etc.) Also, take as many images as you can out of the HTML. Don't use images to display text. Ideally, put all the CSS in an external file, but it's up to you how you organise your code. Just be aware of the tradeoffs.
Don't use event attributes (onLoad, onMouseOver, etc.) Ideally, put the JavaScript in an external file. Like with CSS, this isn't so important and is up to you. However, it is important that your web site works without JavaScript, if possible. Again, just do your best.
By this I'm talking about using HTML semantically. Don't use tables unless you're showing spreadsheet data. Use h1-h6 tags for the headers on your page. Use blockquote only when you're quoting, not for the indentation. Just try to use the full range of HTML tags when appropriate. Sometimes you simply need to use divs and spans, but avoid catching Divitis.
Accessibility is a very important standard, in some places it's actually the law. If you've already taken care of the last four points, chances are your site is already very accessible. Grab an accessibility checklist, and take look at your web site through the eyes and ears of all potential visitors. What does the site sound like with a screen reader? What happens when you increase the font size? Are you using any terminology without giving definitions? This is a big topic, but it often gets forgotten.
This is what I mean by 'web standards'. These are all just guidelines, and there are obvious exceptions to every rule. Next, I'll go into the benefits of following these rules.
Update: I've chosen to go with the term 'Best Practices' to describe what I've discussed here, of which 'web standards' are only a subset. Read my discussion here.
Continuing my discussion of microformats, let's take a look at the hCard. The hCard microformat is a way of identifying contact information in HTML. People can use tools to look into the HTML and extract this information as a vCard. vCard is a standard for an electronic business card. There are a number of values you'd expect (name, phone number, organisation, etc.). hCard takes these labels and uses them as class names around data in HTML.
Here are the more common values you can use in hCard (for the complete list, see the wiki:
Every hCard starts inside a block that has class="vcard". So, a very simple hCard might look like this:
<div class="vcard"> <span class="fn">Jesse Skinner</span> <a class="url" href="http://www.thefutureoftheweb.com">http://www.thefutureoftheweb.com/</a> </div>
Some of these types have subproperties. For example, the 'tel' value contains 'type' and 'value'. This way you can specify separate home and business phone numbers. The 'adr' type has a lot of subproperties (post-office-box, extended-address, street-address, locality, region, postal-code, country-name, type, value). An address might look something like this:
<div class="vcard">
<div class="fn">Jesse Skinner</div>
<div class="adr">
<span class="locality">Berlin</span>,
<span class="country-name">Germany</span>
</div>
</div>
The class names don't have to mean anything within your page. However, you can always take advantage of them to style your contact information. You could also style them in your browser's User Style Sheet, so that you can find them while you surf the web.
The hCard standard is very flexible. It doesn't matter which tags you put the classes on. It certainly doesn't have to be in nested div tags. You could just mark up your contact information any way you like, and then wrap the data in span tags to tie the data together. For example, it can be within regular text in a paragraph:
<p class="vcard"> My name is <span class="fn">Jesse Skinner</span>. I live in <span class="adr"><span class="locality">Berlin</span>, <span class="country-name">Germany</span></span>. I work for <span class="org">Strato AG</span>. I have a web development blog at <a class="url" href="http://www.thefutureoftheweb.com/">http://www.thefutureoftheweb.com/</a>. </p>
There's lots of tools already, and more on the way. If you don't want to install a browser plugin, or if you want to give all visitors to your site a way to download your hCard as a vCard, X2V is a service that does just this. Just link to:
http://suda.co.uk/projects/X2V/get-vcard.php?uri=[URL with an hCard]For example, click here to download a vCard of this simple hCard:
My name is Jesse Skinner. I live in Berlin, Germany. I work for Strato AG. I have a web development blog at http://www.thefutureoftheweb.com/.
hCard, like other microformats, is wonderfully simple yet incredibly powerful. You can begin using it right away with very little work, without waiting for the standard to be widely used. As more people start looking for hCards (and your contact information), your web site will already make things easier for them.
Jonathan Snook just posted a nice example of why you should stick with what's predictable. When designing, there's a lot of temptation to go against the grain, to do something a little different than everybody else does it. Except, it makes your interface less predictable. And predictability is key for user friendliness. Whether it's underlines on hyperlinks, or simple navigation titles, you'll usually end up winning more points for usability than you ever will for creativity.
Peter-Paul Koch just announced that he's put up a new test page comparing the JavaScript dimension and positioning variables (offsetWidth, scrollHeight, etc.) across multiple browsers.
As a quick side note, QuirksMode is my favourite JavaScript and CSS reference, when it comes to figuring out browser support and differences. His examples are so clean and to the point. Thanks, Peter-Paul!
Microformats are a way of defining new data formats using existing standards and languages (ie. HTML and XML). It's a very exciting area of web development. The concept is relatively new, so there are really only a few formats out there (currently nine formats plus ten draft formats). There's also a lot of room for new formats to be created and used.
The idea is to use simple, easy, and predictable ways of defining new standards, rather than defining some complex impossible new standard. This way, the standard is something people can start using and benefitting from very easily and quickly. There's no need to go and change existing structures. Rather, microformats tend to be subtle adjustments to the way people tend to do things anyway.
The ultimate source of everything microformat-related is currently the the Microformats Wiki, and if it's your first time looking at microformats, I suggest you read the microformats entry. Since it's a Wiki, anybody can add new microformats, or contribute to existing ones.
I can't mention microformats without mentioning Tantek Çelik. He can be credited with the concept, and he still plays a very active role in defining and promoting new standards. He's the editor on the Wiki, and from what I can tell, he's co-created most if not all of the current microformats.
You may be familiar with the rel-nofollow standard. Google came up with the idea of adding rel="nofollow" to links in blog comments. This tells the Googlebot to ignore these links when calculating PageRank. This is intented to prevent comment spam, because spammers won't gain a higher PageRank by sticking their URL in comments.
The idea is perfectly simple. It uses an attribute built into HTML, the rel attribute, in a way that is consistent with its intended purpose. The HTML 4.01 spec says:
They give a list of link types, but afterwards they state:
Authors may wish to define additional link types not described in this specification.As a result, the rel-attribute is a common method of implementing link-related microformats. Another example of a rel-attribute microformat is the Technorati rel-tag format. Technorati scans blog posts looking for links with rel="tag". The word or phrase within that link is used as a tag to describe the post. This blog uses such tags, and you can see them at the end of this post.
In the future, I'd like to discuss some more of these microformats and show more examples. Until then, I suggest you check out the Microformats Wiki and see if there's any microformats you can start using today.
I recently discovered the power of using multiple classes. That is, using more than one class on a single element. The class attribute simply accepts multiple classes separated by a space. For example, you can do something like this:
<style>
.box { border: 1px solid black; }
.small { width: 400px; }
.large { width: 800px; }
</style>
<div class="small box">
<div class="large box">
This is a great way to organize your CSS. For example, you can have a set of classes to define font styles and another set of classes to define box sizes. Then you can use them together in different combinations.
The class names "small" and "large" aren't totally clear, since they refer specifically to small and large box sizes. It'd be great if I could write "large title" and have it affect the font size instead of the width. So, I tried to change the definition by combining multiple classes in a single selector:
.box { border: 1px solid black; }
.box.small { width: 400px; }
.box.large { width: 800px; }
.title { color: blue; font-family: Arial; }
.title.small { font-size: 10px; }
.title.large { font-size: 20px; }
When I tried this in Firefox, everything worked great. Unfortunately, Internet Explorer doesn't support this. In fact, Internet Explorer will just look at the last class in the list. So, it will interpret the last example as if we had written this:
.box { border: 1px solid black; }
.small { width: 400px; }
.large { width: 800px; }
.title { color: blue; font-family: Arial; }
.small { font-size: 10px; }
.large { font-size: 20px; }
Small boxes will have small fonts, large boxes will have large fonts, small titles will be 400px wide, large titles will be 800px wide. Very unfortunate.
Once again, Internet Explorer ruins all the fun. Well, there's an up side to this. When we use "small" to affect the width in one place, and the font size in another place, we make it harder to understand and maintain the CSS. And isn't that supposed to be the point of using CSS?
Besides, not all is lost. We just have to come up with better names. We can still do this:
.border { border: 1px solid black; }
.small-box { width: 400px; }
.large-box { width: 800px; }
.title { color: blue; font-family: Arial; }
.small-text { font-size: 10px; }
.large-text { font-size: 20px; }
It sure isn't as pretty to write something like class="border small-box". But at least then we can use our "small-box" class in places that don't have borders, or use the "border" class to give a border to something without a fixed width.
In conclusion, avoid the .class1.class2 syntax altogether. It's not supported by Internet Explorer, and it makes code harder to read and manage. However, using multiple classes is completely supported and will make your CSS cleaner and more reusable.
Blogs are here to stay. However, I don't believe every web site needs to have a blog to benefit from the way blogs have changed the Internet. Here are five things blogs have taught us that we can use to improve all web sites:
Update regularly
Many web pages have some kind of "News" or "What's New" section. Most of them never seem to change. Blogs essentially took this section and made it the centre of the entire web site. Things are always changing and events are happening. The best part of the web is how up-to-date it can be. If something important is happening, and there is nothing about it on your web site, your visitors won't trust your web site as a source of information.
Let visitors subscribe
Blogs didn't invent subscriptions, but they've certainly proven they work. Long outdated are the phrases "Bookmark this site", "Under Construction" and "Check back soon". Every web site is changing and being updated. Visitors don't have the time to check back. You need to offer a way for them to subscribe. RSS feeds are certainly the new standard for subscriptions, though E-mail updates are still relevant for those who don't use RSS.
Speak with a human voice
Blogs aren't written in buzzword-filled meaningless marketing speak. They're written in the same language people use to talk to each other. The kind of language that people actually want to read. By changing the language of web sites, you not only make your web site more friendly, you make it easier to understand. If you really have something worth saying, be direct and clear about it. If not, why would you bother writing anything at all?
Get personal
Blogs don't hide the people behind the web site. In fact, that may be their strongest attraction. The Internet is changing the voice of companies whether they embrace it or not. For example, Robert Scoble's blog has become the voice of Microsoft. His blog is honest, admitting where Microsoft fails, where it needs to improve, and what its true motives are. It's time for the people behind web sites to come out and tell their stories.
Let visitors discuss
People need a chance to respond and add to things they read on the Internet. Most blogs give visitors a chance to discuss in comments and trackbacks. Where comments and trackbacks aren't appropriate, wikis and forums fill in the void. If your web site doesn't give a chance for visitors to contribute and share feedback (whether it's positive or negative), they will do this on their own blogs. Offering a place for the visitors of your site to come together and share feedback builds community, trust, and lets your site evolve in response to what people want.