Why I Switched to WordPress

The Web is ever changing, and this article is relatively ancient having been published 11 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

I’m pro-intensive-customization, anti-bloat, pro-knowing-what-your-code-does. For over a year, my site ran on a code-base authored at least 90% by me. Don’t get me wrong, I know when to say “hmm, that’s not my strong point, let me use someone else’s code,” but I wanted to have total control over every aspect of my site’s backend. Then, last night I went live with WordPress.

I was resistant to using an out-of-the-box CMS for my own site for a long time. Some of those reasons were tenable, but most were at best me being stubborn and at worst illogical.

Frankly, as often as I get stuck doing backend work at well, work, why do I want to be doing it in my free time as well? There are so many features I want to develop on my site that I just haven’t gotten around to, because at the end of the day, I don’t want to touch that kind of code. Using WP, I can just enable those features, add a plug-in or tweak a little code and quickly have that functionality. It saves me time and headaches.

But wait, why are you using WordPress?

…instead of <ANY OTHER CMS>.

WP isn’t necessarily my favorite CMS out there. I even tweeted an anti-WP haiku once:

A haiku inspired by bad advice. “Wordpress: blog system. / Bloated, not secure, real slow. / Not true CMS. ” (My opinion only)

But I promise I’m not being as hypocritical as it may seem.

  • First and foremost, my site is a blog. Or four blogs, depending on how you look at it. It’s not some gigantic commercial site. A blog needs blogging software. WP is a pretty solid blogging software.
  • My anti-WP tweet was focusing on advice someone gave a client that their 1000+ page absolutely had to be in WP because that’s the only CMS in existence that is any good. Uhh, no.
  • More and more often, I’m finding myself using it for client sites (where the decision to use WP was already made or where it seems like the best solution). In order to be the successful, efficient developer I like to be, I need to become more intimately familiar with the system, and what better way to do that than to use it on my own site?

That last bullet has about 70% of the weight in this decision. Maybe when I start inheriting a bunch of Joomla sites, I’ll develop a different personal project on it. Although I probably won’t port this one to anything else again. That bit was painful.

Great, I’m going to switch to WP too!

…just because of this article.

Hold up there. WP isn’t necessarily the right fit for every site.

If you want to start a blog, sure, go for it. It’s simple, has a ton of themes, and mostly uses pretty good, standards-compliant code.

If you already have a blog using another CMS, stop. Evaluate. Why do you need to switch? Are you unhappy with your current system? Is there some very important feature you want that doesn’t exist in the current system? Why WP? Those are all questions to consider.

If you don’t blog (or your site is separate from your blogs), but have heard that your business absolutely has to have a site built on WordPress, stop. You need to talk to a developer. And I’m not talking about your wife’s niece that took a few design classes at the community college and is now a “Web designer.” WP very likely might not by the right CMS for you. But don’t fret, there’s something out there that will help you meet your goals, and the right developer can help you decide what that is and how to get it going.

What’s your CMS of choice? Are you happy with what you’re using? Think I’m totally bonkers? Everyone has their preferences. When porting the site over, I found quite a few things I’m not 100% happy about with WP, but that’s what custom themes and plug-ins are for, right? So, as I learn more, you’ll surely start seeing some changes around here. And probably some WP-centric posts as well.

Dictionary Lists: Child Elements and How to Use

One thing I see far more often than is excusable in code that I inherit is improperly used and structured dictionary lists. Certain elements in HTML are limited to having only a few specific children, and dictionary lists are no exception. Putting incorrect elements as direct children can cause display issues, parsing issues, compatibility issues and headaches for future development (whether it’s a new developer or your own updates). When developing, it should be a priority to use the correct—and only the correct—children in parent elements. Here’s how to properly use dictionary lists.

Dictionary Lists (<dl>)

The dictionary list element is meant to be used for a list of items containing terms and their definitions. That doesn’t mean you’re restricted to using this element only for word lists. For instance, the structure of the element is perfect for frequenty asked questions (FAQs): the question is a term, the answer is a definition. Dialog is another option: the speaker is the term, the words spoken are the definition.

So, let’s repeat: dictionary lists are lists of items containing terms (<dt>) and their definitions (<dd>).

A dictionary list can only have two types of child elements: dictionary term (<dt>) and dictionary definition (<dd>). Semantically, each definition can have multiple terms, and each term can have multiple definitions. That said, the first child should always be a term and the last child should always be a definition.

But <dt> and <dd>—that’s it. No other immediate children are allowed. Of course, you can put other elements inside of those two child elements. But even they have restrictions.

Dictionary Terms (<dt>)

Dictionary term elements can only contain inline elements. That means you can use things like <a>, <strong>, <em> or <span>. You can not use <hn>, <p>, <div>, etc.

Dictionary Definitions (<dd>)

Dictionary definition elements can contain any flow elements— inline or block. That means you can use things like <a>, <strong>, <em> or <span> and <hn>, <p>, <div>, etc. You can have a dictionary list inside of a dictionary definition. You can have a form inside of a dictionary definition. You can basically have anything that is allowed inside the <body> element inside of a dictionary definition.

Valid vs. invalid

The following is an invalid list (with shorthand code showing only elements, not required attributes). Don’t do it.


Here’s a valid list.

<dd>Both are words that mean “enormous,” but sound way cooler.</dd>

Get it? Good. Go forth and dev.

What tips do you have for using dictionary lists?

Creating Right Triangles in Adobe Illustrator

Here’s a quick way to draw a right triangle in Adobe Illustrator. It involves using just two tools: the rectangle tool and the pen tool. Don’t worry if you don’t have much experience with the pen tool—we’re using it very simply. The method: draw a rectangle or square and then use the pen to delete a corner, instantly creating a right triangle.

These instructions will work in Adobe Illustrator from CS–CS5. The same strategy should work in any vector drawing program that allows you to use a pen-type tool to delete anchor points from a shape.

How to create a right triangle in Illustrator

  1.  Select the rectangle tool. (Keyboard shortcut m)
  2. Use the rectangle tool to draw either a rectangle or square, depending on the type of right triangle you want.For a 45°-45°-90° triangle (half-square triangle) draw a square

    For all other right angles draw a rectangle

    A. Freehand method
    Square: Hold down the shift key on your keyboard, click and drag to draw a square of the desired size.
    Rectangle: Click and drag to draw a rectangle of the desired size.

    screencap of freehand method
    B. Exact-size method
    Click once anywhere on your artboard to open the rectangle dialog.

    screencap of dialog

    Type in your desired dimensions for the legs of your triangle (not the hyptenuse).

    Click ok.

  3.  Select the pen tool. (Keyboard shortcut p)
  4. Point your cursor in pen tool mode over the anchor (small square in shape outline) in one corner of your shape. The cursor will change into the delete anchor point tool.
    screencap of delete anchor point tool

    Click on that anchor to delete it.

  5. Success. You should now have a right triangle.
    screencap of right triangle

If something happens so that your shape is deselected before you try to delete the anchor, use the  select tool (black arrow tool, keyboard shortcut v), to click on your new shape so that it is selected, then try from step 3 again.

This entry is part of the Keyword Answer Quest series. The series focuses on answering queries presented by long tail keywords that bring searchers to other pages on my site. Sometimes, these keywords don’t lead readers to a very relevant page, but when my expertise can meet their needs, Keyword Answer Quest comes in. This entry was inspired by searches including:

  • cut right square into right triangle illustrator
  • how to make half square in illustrator

Online Retailers: Help Your Customers Find Your Products

The Web is ever changing, and this article is relatively ancient having been published 11 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

Aisle of products One of my favorite (only because it has the best, low-price selection) sources of quality fabrics has horrible UX on their store site. Horrible to the point that I’m only able to do rudimentary filtering because I understand the GET variables they use to display their catalog. In fact, I wrote a post to help non-developer users figure out how to filter the catalog by changing the URL. The fact that I had to do either of those things really bothers me as a front-end developer; your users should never have to resort to manipulating the URL in order to filter or find products.

If a user can’t easily figure out that you carry a certain product, you just lost a sale. Think about that and what it means to your business.

Say a customer walks into your brick-and-mortar store wanting a specific type of whatchamacallit with a budget of $5. They see that there is a whatchamacallit aisle, but it’s just overwhelming: you have have 200 different colors of that specific type of whatchamacallit. There are different sizes, weights, and patterns. The customer’s not too picky about some of the finer points, or maybe they are, but it doesn’t matter because they only have $5 that they want to spend. So, they want to quickly narrow it down to all whatchamacallits under $5. They could go down the aisle looking at every one, but it’s easier for them to find a store employee and ask, “can you show me the whatchamacallits that are under $5?”

Being a store that cares about making a sale, your employee says yes, helps the customer, maybe even upsells them, and the customer makes a purchase. Money in the bank for the store.

Now stop. Why should this interaction be any different in your online store? That’s right, it shouldn’t be. Sure, it’s a bit difficult to have a person there, so to speak (you could have a live chat function). But there are alternatives:

  • An obvious search box that accepts queries like “whatchamacallits under $5” and returns useful, intuitive results.
  • Obvious, intuitive filtering and sorting options for search results with obvious, intuitive controls.
  • Obvious, intuitive filtering and sorting options within categories with obvious, intuitive controls.
  • An obvious, intuitive way to change the number of items shown on a page.

Notice the similarities up there: obvious and intuitive. It’s not simply adequate to provide those controls; people need to be able to find them and use them easily—just like they’d need to be able to easily find a knowledgeable employee. Good online store software will have all of those things out of the box or your developer will set it up as a standard part of your store creation. All of these filters should persist until the user says to remove it, as well: if a user filters to blue whatchamacallits then applies a $5 filter, they should be shown blue, $5 whatchamacallits not just $5 ones in any color. Sounds like common sense, right? Too many online stores don’t seem to get it.

Now, back to the earlier example. What if your employee said to the customer, “no, find it yourself.” Maybe the customer would spend time looking, but more likely they’d realize that you don’t care about their patronage and they’d go somewhere else to find the whatchamacallit. You just lost the sale. You’d probably fire an employee that did that consistently.

That’s exactly what’s happening at the fabric store. And many other online stores with outdated store software that has no filtering. There’s no provided way to easily narrow the products down to a specific one you’re searching for. There’s a search function, but it’s not that great, and there’s no way to narrow down the results. There’s absolutely no way to sort of filter the category item listings at all. They need to fire their store software.

Keep in mind that simple categorization is not sufficient criteria browsing or searching. Just because I want a whatchamacallit doesn’t mean I’m interested any whatchamacallit you carry. Shoppers, whether they’re just browsing or are looking for a very specific item, are more likely to buy from you if they can find what they are looking for. If they can’t find it, they can’t buy it. If they’re browsing a sales listing hoping to find something they think they need, you’ll have more success on a conversion if they can narrow down that sales list to items they are interested in. Sure, they can start at the top—viewing everything—but maybe they see a coolthing that intrigues them, but it’s not the perfect coolthing they want to buy. If they can easily narrow that listing to all coolthings, your ability to sell them something just increased. They know you carry the type of item, and are easily able to drill down to all items of that type. If they can’t, then maybe they keep looking, or maybe they get bored after going through another 2 pages with no more coolthings because all the other coolthings are 12 pages into the sales. A bored visitor leaves, and so does their money.

What do you expect from online shopping user interfaces? What makes you go to another store? Stay at the current store? Feel free to share good or bad experiences and examples in the comments.

How Bad Does it Hurt? Closing Your Oldest Credit Card

I came home a few weeks ago to an ominously large envelope from 1st Financial Bank, USA, the guarantor of my oldest credit card—too large to be the statement or those deplorable fee-heavy cash advance checks they send me. You may remember from my grousing a while back that 1FB was guilty of pretty much every shady tactic outlawed by the CARD Act that recently went into effect, and how happy I was to finally pay the card off. Well, know that they’ve been forced to stop double-cycle billing, roving due dates, and other money-making tactics, they have a new way of making money: annual fees.

The new annual fees? $25, $45 for limits over $1000. Although based on their wording, there’s no guarentee that they’ll charge you. In fact, when I called up to cancel, I was told You know, your annual fee can be waived on a yearly basis, upon request. So, it sounds like they’re planning on making most of their money on the inattentive that never bother to call in.

I have no intentions of potentially paying $45 annually for a card to sit in my wallet virtually unused, nor bother with calling in yearly. The only reason I still have the card is that it is my oldest (by a year), and has the highest credit limit. Those two factors supposedly help my credit score out quite a bit. Especially the high limit, which accounts for over half of my available credit. I’ve seen first hand how a high debt-credit ratio can bring down your score, so I don’t relish the thought of halving my available credit (and doubling my current debt-credit ratio). But does the fact that it is my oldest card count? After all, even closed, it will remain on my record as a closed account for the next few years. And should I even be worrying about my credit score? After all, I’m working on getting out of debt, not taking more on. I have a newish car (2007), and with a paltry 20k miles on it to date, I’m sure I won’t be needing another one for quite a while. We decided that a mortgage isn’t in the cards any time soon—it’s cheaper to rent here in Utica, and we’re not sure we want to stay long-term anyhow. So, why do I even need an excellent score? The answer? I probably don’t.

So, I “rejected the change to my account,” which is their euphemism for “you won’t play our profit game, so we force you to tell us to close the account.” And then I waited anxiously for them to report to the credit bureaus to see how much my score was affected.

The Score Hit

I started out with a 769 TransUnion score, which is considered an excellent score by Credit Karma. That’s actually quite a change since this time last year, mostly due to paying off the 1FB account and bringing down my debt-credit ratio quite a bit. Since that ratio is what is going to take the biggest hit with this cancellation, it did have me a bit worried.

The resulting score: 761.

So, not much of a hit at all. But, despite my worry before closing, I’m now at peace: I have one fewer card to worry about losing/having stolen, and will have to spend that much less time reviewing and filing statements (1FB jumped on the paperless bandwagon a mere month before I closed the account). And, by the time I’m ready to apply for a mortgage, my debt-credit ratio will be ~0, so the score will be back up.

The moral of the story? In my situation, at least, the myth that closing your oldest credit card will severely effect your credit rating doesn’t seem to hold true. What does cause issues is the drop in debt-credit ratio from losing the available credit on the card. If you’re young, and have a pretty good history, there’s no good reason to not consider dropping your oldest card if the bank gives you reason. A slightly lower score is still better than paying a high annual fee for no rewards and no features.

I know 1FB USA isn’t the only bank out there that has started charging annual fees. Have you had any surprise changes to your accounts since the CARD Act went into effect?

Losing Values When Cloning Forms

The Web is ever changing, and this article is relatively ancient having been published 12 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

I’ve finally started development of a book recommendation widget for the musings and reviews on books I read section of my site. The general functionality is pretty simple: visitors have a few fields to complete with info about the book; upon submission, their recommendation is saved to a database; the new recommendation is shown to all and sundry in a “last recommendation” section; rinse & repeat. The whole no-JS needed, server-side scripting processing involved is simple, straight-forward and was quickly completed. Being a front-end developer, however, I want to make sure this can all be done in a smooth JS-enhanced way as well (for some nifty UX). That’s where I encountered yet another annoying JavaScript problem.

Each browser interprets “clone” differently

Due to differences in how each browser implemented cloneNode() in their JavaScript engines, there is an issue with values for form elements not persisting to the copy of an element. Inconsistencies like this are many of the reasons why I’m a fan of using a JavaScript library for most projects. In this case, because the library has usually worked out the issues and can handle copying without losing important data. Unfortunately, jQuery still has some issues to work out; it loses select and textarea values on clone(). Other inputs types don’t seem to have any issues, including hidden fields.

How this affected my widget

In order to display the submitted form data in the “last recommendation” section, I decided the best approach would be to copy the form, then replace each form element with an inline element containing the value based on type of element. It might not be the most elegant solution, but it seemed better than specifying each individual element by name and manipulating it that way.

So, step one: use clone() to copy the form (no need for cloning events and the like). Step two: do the replacement. Step three: realize that regardless of selection, the last recommendation always displays the first option in a select box. And an empty string for any text area.


Honestly, my current solution is just a dirty hack. I only have two affected fields, so I explicitly copy the original values to where they need to go. I’m more concerned about getting this up and running, knowing that there won’t be much in the way of extension in the future. I am about 99% positive I won’t be adding any additional fields, at least.

For other projects though, this could be a major issue for scalability and ongoing maintenance, especially if there are multiple affected elements. A quick search around the Internet shows a lot of inelegant solutions. One that approaches a decent solution for jQuery is this solution at, although it only attacks the select issue (and later inputs as well with a bit overkill [see the comments], but no textarea). That approach could work with some modifications.

Have you seen this before? How’d you solve it/work around it?

Trigger AJAX Error Event

The Web is ever changing, and this article is relatively ancient having been published 12 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

When I was new to working with AJAX functions—especially in the realm of form submission—one hurdle I often encountered was how to handle processing errors in my back-end script and give meaningful feedback to my users. I didn’t understand how to designate a response as an error instead of successful processing. Early on, I sometimes employed a dirty hack of prepending any error with the string ERROR: and then adding in some quick checking to see if that substring existed in my response text. While that may get the job done, it’s not good form. It causes convoluted code usage, thumbs its nose at existing error handling functionality and makes future maintenance a headache. But there is a better way by simply utilizing your processing language’s inherent header and error handling functionality.

N.B. From a JavaScript standpoint, I’m showing code based on the jQuery library, because I use it on a regular basis. The concept of triggering the XMLHttpRequest object error handling with proper headings is applicable to any type of JavaScript coding. Likewise, my server-side processing examples in this article are coded in PHP, but that is not the only applicable language. You can produce similar results with other languages as well, so long as that language allows you to send header information. If you’re willing to translate my examples into another language or non-libraried JavaScript, please do so in the comments or e-mail me (, and I’ll add it into this article (and give you credit, of course).

The information in this article refers to AJAX requests with return dataTypes of html or text. JSON and XML dataTypes are for another day.

The client side of things

Let’s say we’re working with a bare-bones comment form: your users add a name, e-mail address and their comment. Three fields, all required, easy-peasy. For the purposes of this article, we’re going to ignore all of the validation you would want to do on the form and focus solely on the process of sending it via AJAX to your PHP processing script. The resulting AJAX call with jQuery might look something like:

//[warning: most of this is pseudo-code, not code you can copy+paste and expect to immediately work]
    type: "get",
    url: "/processing/process_comment.php",
    data: $("#commentForm").serialize(),
    dataType: "html",
    async: true,
    beforeSend: function(obj) {
        //give user feedback that something is happening
    success: function(msg) {
        //add a success notice
    error: function(obj,text,error) {
       //show error
    complete: function(obj,text) {
        //remove whatever user feedback was shown in beforeSend

Essentially, the above JS expects the server-side processing script to return a message to show the user. We’ll set up such a script next.

The server side of things

Processing our simple comment form is close to trivial. We’d want to do some basic validation, make sure the submitter hasn’t been blacklisted for spamming or other reasons (in this example based on IP address), and then add the comment to a DB. The interesting part, however is how to tell the server that an error occurred during the processing and have that error propagate back to the AJAX properly. This is where the header and exit functions come in handy. Look at this example:

<?php //[warning: the "processing" is pseduo-code functions, however the error throwing parts are valid]
    // perform validation
    if (validValues($_GET)) {
        if (blacklisted()) {
            header('HTTP/1.1 403 Forbidden');
            exit("Uh, hi. Your IP address has been blacklisted for too many spammy attempts. Back away from the keyboard slowly. And go away.");
        if (addComment($_GET)) {
            // We have success!
            print("Your comment has been successfully added.");
        // if the code reaches this point, something went wrong with saving the comment to the db, so we should show an error
        header('HTTP/1.1 500 Internal Server Error');
        exit("Something went wrong when we tried to save your comment. Please try again later. Sorry for any inconvenience");
    } else {
        header('HTTP/1.1 400 Bad Request');
        exit("This is a message about your invalid fields. Please correct before resubmitting.");

In PHP, the header function allows you to send headers to the client. In the syntax used above, it is allowing us to specify error status. For more info on the header function, head to the PHP manual on header. exit is a handy construct that ends script execution while allowing you to print an error. Upon successful completion of the processing, we make sure to call exit(0), which signifies successful completion of the script. Any non-0 value indicates that an error occurred. Learn more at the PHP manual on exit. For errors, you can also use the die construct, which is equivalent to exit.

Putting it all together: View a Demo

Let’s get advanced

The above examples for the error function are pretty simple, but you can create very elegant error handling solutions with it by utilizing other properties of the XMLHttpRequest object. One possibility is to take unique actions based on status code returned. By using the status property of the object, you can customize your error handling based on the status returned. For instance, this error function script would alert a user to modify form information if needed, but completely remove the form if they found the user is a blacklisted IP (using the same server-side script from above).

    error: function(obj,text,error) {
        if (obj.status == "403") {

Have you utilized this method in your AJAX programming before? Let us know how it worked for you.

A Bad Webmaster is Bad Marketing

A month or two ago, a Twitter friend retweeted @berniebay saying Funny how the contemporary webmaster is really a marketing person… I retweeted that, adding At least, if they’re good ones. But—my poor grammar aside—my reply has been bugging me ever since, though I was unable to pinpoint why. I finally figured it out: I was wrong. A bad webmaster is still a marketing person, just a bad one. One that markets you poorly. @berniebay was right on the money. Read on as I examine why he’s right, and why that should influence who you hire to do your Web projects.

Welcome to 2010.

A Web presence is no longer optional for most businesses. Additionally, the page your husband’s co-worker’s nephew hacked together for you in 2000 is not sufficient. Neither is the Geocities-era (R.I.P.) or Homestead-built, ugly, unnavigable site of days past. It’s no longer adequate to simply have a Web site; we’ve moved beyond that as a society. To grow your business, your site needs to look professional and be one step ahead of the marking efforts of your competitors. That means having content that is easy to find, easy to read, and pertinent to both the customers you have and the ones you want to attract, all wrapped in a pleasing design.

The first step in working toward that is hiring a person or firm to relaunch your Web site for the modern Web. Before you sign on the dotted line (the right person to hire will have a contract for you both to sign—both for your protection and theirs), ask your future webmaster “how will the work you do for me market my business?” Go ahead, ask. You might throw them off for a second, but they should be able to answer that question without problem—if they’re good. If they’re bad, the following are just a few of the things they might do that will hurt your Web site in the long run.

Pages, pages everywhere

Your homepage is no longer the entry point of your Web site. When a visitor comes to your site from a search engine, he or she could end up on any page in the site. If you expect the visitor to explore other pages, they need to know where they are in the site and have a way to get to other locations. Menus should be well-organized but not overwhelming. A bad webmaster doesn’t care about this information architecture. Information architecture refers to the structure or content in terms of intra-site linking, menu structure, folder structure, and content organization. A bad webmaster will not have a consistent linking scheme, will not provide any visual or contextual clues as to a visitors location in the site, will have outdated menus that link to broken pages, and a variety of other things that make your vistor’s experience bad.

I’ve even seen cases where poorly developed sites will have two or more versions of an important page that are linked from various other pages. There are a couple reasons why this is bad. The first has to do with maintenance: a simple change to that content has to be made in multiple locations. That takes time, and introduces a greater possibility of errors. The second has to do with duplicate content. Search engines do not like finding duplicate content on Web sites. In the long run, this can mean a reduced ranking for your entire site, which means less exposure and less traffic.

No redirects

When a page is moved or renamed, even a bad webmaster will hopefully change the links to it on your own Web site. But links to that content may exist in other places on the Web as well, which means users will see an error when they reach your site. A bad webmaster doesn’t care, or doesn’t know how to get around that, but a good webmaster will set up redirects for those pages. Redirects are a way of telling the server that the old page still exists, and forwards the visitor or search engine crawler to the correct new location. Setting up redirects is of the utmost importance whenever a site is reorganized. Especially if you have someone creating a new Web site for you, you’ll want them to redirect all of the old URLs to the corresponding new ones so that anyone coming through a search engine, bookmark, or link from another site will still be able to find the information they were looking for.

Worthless error pages

Sometimes, a user will end up looking for a page that does not exist on your Web site. Either it was removed on purpose or the URL was typed incorrectly in the address bar or in a link on another site. A bad webmaster thinks that the server’s basic 404 error page is sufficient. But in reality, that page is utterly worthless to your marketing efforts. Chances are that the visitor will see that, go back to their search and not give your Web site another glance.

A good webmaster will set up custom error pages for your site. These pages will have your branding, and will have helpful links for a visitor. These custom pages commonly have links to the site map, or a search functionality so that users can try to find what they were looking for on your site. These pages may entice users to stay on your site rather than going away quickly.

Unclear page names

I recently worked on some changes to an old site where every file was named some permutation of “pageXX.html.” This is absolutely terrible structure. It’s bad for the webmaster because who knows if the About page is page2.html or page5.html, allowing for a higher change of errors and broken links in their code. It is bad for the visitor, because it not only creates confusion as to what page they’re looking at, but it also shows that you have a lazy webmaster. Pages should always have relevant filenames. Naming your about page “about-us.html” has much more semantic meaning to all parties—the webmaster, the visitor and the search engine.

This idea also extends to dynamic content. You’ll often see something like “/products/prod_type=23532&id=234982342.” That has no meaning to the visitor. Instead, a good webmaster will set up the server so that the URL is more like “/products/doodads/whatchamacallits.html.” This way, visitors know what they’re looking at, and can easily move back to an index page of all doodads, or back up to the Products page.

No site map

While having a page on the site called a site map that lets your visitor quickly see the structure of the site is useful, in this case I’m talking about a different type of site map: one generated based on a standard adopted by the major search engines. This file, usually named sitemap.xml is a very important addition to your site, even if your visitors never actually see it. It essentially lists every single page in your site and lets the search engine know how often (approximately) that page is modified and how important it is compared to other pages on your Web site. A bad webmaster may not bother generating this file, but a good one will both generate it and submit it to the major search engines, which increases the likelihood of your Web site being crawled and fully indexed on a regular basis.

The marketing side of it all

You may have noticed a theme here. The above list is composed mainly of approaches that affect your Web site’s ability to be found in search engines. It’s great if you get traffic from people who know your Web address, but there’s no way to grow your business if that is the only traffic you receive. In that paradigm, if you want to grow, you have to find a way to inform people of your Web address, which may mean spending money in traditional media. That’s wasted money—and more money on top of the cost of your Web presence. Why would you pay extra money to do your webmaster’s job? If your Web site is done right and managed properly, traffic will come to you because people will find your Web site when they search for keywords relevant to your site. This traffic is how you grow your business in 2010.

Webmasters, do you have anything to add? Clients, what do you look for in a webmaster?

CSS Shorthand: an Introduction

One of the things I see most often in beginners’ CSS is an utter lack of shorthand for style declarations. The cause may be that their existence is never mentioned in basic CSS tutorials, or that they’re never discussed in-depth enough for new developers to feel comfortable using them. Or, in some cases, simple ones are used without understanding exactly what is going on. I honestly don’t know why, but hopefully I can clear up some of their mystique so that these handy bits of code can be useful to all and sundry.

Attributes that can use shorthand

This is not an entirely comprehensive list of attributes that can be shortened, merely an overview of the most common. As more and more CSS2 and CSS3 properties are supported by modern browsers, the list of shorthand-capable attributes grows (border-radius and CSS columns come to mind). This should get you started, however. If you find yourself using a set of attributes that you think might have shorthand, I’m sure a quick Web search will pull up more information.

N.B. in most cases, if you leave out a value, the browser will use the default value for that attribute. I’ll let you know if that’s not true.

Hex RGB colors

This isn’t exactly a shorthand attribute, but did you know you can shorten hex colors if their RGB pairs match? So, instead of typing out #FFFFFF, you can shorten it to #FFF (or #fff—it’s case insensitive). It also works for something like #990000=#900, etc. Basically, anything formed as #xxyyzz. #499223 or something like it cannot be shortened.


I’ve combined these all into a single heading because they work in the same way: each one takes between 1-4 size specifications and applies that measurement to the appropriate side. For declarations with multiple specifications, they order clockwise from the top So, how does it work?

  1. margin: 10px; (all)

    All sides are given the measurement.

  2. padding: 1em .5em; (top/bottom right/left)

    Measurements are assigned in top/bottom, right/left pairs. The top and bottom measure 1em while the right and left measure .5em.

  3. border-width: 1px 0 3px; (top right/left bottom)

    Three measurements are defined, with the right/left sharing. The top measures 1px, the right and left have no visible border and the bottom measures 3px.

  4. margin: 10px 5px 0 30px; (top right bottom left)

    Each side has a different measurement. The top measures 10px, the right measures 5px, the bottom has no margin and the left measures 30px.

That definitely saves time and bytes over:

margin-top: 10px;
margin-right: 5px;
margin-bottom: 0;
margin-left: 30px;

padding-top: 1em;
padding-right: .5em;
padding-bottom: 1em;
padding-left: .5em;

border-top-width: 1px;
border-right-width: 0;
border-bottom-width: 3px;
border-left-width: 0;

N.B. This is one case where leaving off a value doesn’t go to a default; it changes the functionality.


The border property is one of the better-known shorthands. I often see border: none; used, which is a very comprehensive bit of shorthand. We discussed the shorthand way to declare border-width above, but we can go even further with shorthand:

border: #00f dotted 2px; (color style width)

In the above case, we end up with a dotted 2px blue border all the way around. But what if you want to have only a top and bottom border, like in the border-width example? You can combine the two:

border: #00f dotted;
border-width: 2px 0;

Remember that leaving off a value will generally result in the browser using the default. In this case, after the first declaration, the border-width is set to a default size, which the second line overrides by giving it an explicit width for the top and bottom.

The border properties have a sort of medium-level shorthand as well, which you see with border-width. You can further expand by declaring border-top-width, etc. border-color and border-style can be used in the same clock-wise manner as border-width, allowing you to provide 1-4 specifications. For instance:

border-color: red blue yellow;
border-style: dotted dashed solid double;

The above follows the same ordering principles as border-width: top right bottom left.

Without the various levels of shorthand, for even just a simple 1px solid red border you would have to declare the following:

border-top-color: red;
border-top-style: solid;
border-top-width: 1px;
border-right-color: red;
border-right-style: solid;
border-right-width: 1px;
border-bottom-color: red;
border-bottom-style: solid;
border-bottom-width: 1px;
border-left-color: red;
border-left-style: solid;
border-left-width: 1px;

N.B. Despite the fact that they begin with border-, border-spacing and border-collapse are not part of the border shorthand, as they pertain solely to tables, not other elements.


The font shorthand allows you to set some of the font-related properties of an object. In fact, one of the first lines of CSS on any site I develop looks something like:

font: 90%/1.5 Arial;

That is font shorthand at its most usefully condensed state (you could remove line-height—a font-size of 90% (percentage of the parent), a line-height of 1.5 (1.5x the font-size, so ~135%), and a font-family of Arial. Note the slash between font-size and line-height. It’s an important part of the syntax.

You can further enhance your shorthand by adding font-style, font-variant and/or font-weight to the beginning of your declaration. An extremely styled declaration might then look like:

font: italic small-caps bold 110%/2  "Adobe Garamond Pro", Garamond, "Apple Garamond",
                "Palatino Linotype", Palatino, Georgia, serif;

In addition to setting the font-family the font shorthand allows you to set the font using system settings—something that isn’t possible with font-family. The available system settings are:

  • caption
  • icon
  • menu
  • message-box
  • small-caption
  • status-bar

I don’t have much experience using these settings, so your mileage may vary. If you have experience, tell us more about it in the comments, if you don’t mind.

N.B. using the font shorthand will reset any earlier or inherited declarations, rather than using the inherited property it will reset things to normal or the system font.

All other properties relating to text, such as color, must be set long-hand, but regardless, font is still faster than typing out:

font-family: Arial;
font-size: 90%;
line-height: 1.5;
font-style: italic;
font-variant: normal;
font-weight: bold;


There’s a lot more to setting a background than just color or image, but the background property makes it easy. Rather than typing out all of this:

background-color: #000;
background-image: url(/images/background.png);
background-repeat: no-repeat;
background-attachment: fixed;
background-position: top center;

We’re able to shorten it into a single statement that looks like:

background: #000 url(/images/background.png) top center no-repeat fixed;

Easy-peasy. Note that you don’t need quotes around your image url. (Unless you have a space in the image. Which you shouldn’t do online; remove the space instead of adding quotes.)

This shorthand goes even further in CSS3. With the new ability to have multiple backgrounds (very little support to-date), you can throw them all on a single background statement separated by commas like this:

background: url(/images/background-top.png) top center no-repeat, #000 url(/images/background-bottom.png) bottom center no-repeat;

The background shorthand is also further expanded to accommodate more new background attributes in CSS3, but because of the limited support I won’t cover them here now.

Shorthand declarations and cascading

Now that you have a grasp on which attributes can be shortened and how to do it, let’s get a little advanced here and talk about how using a mixture of shorthand and longhand declarations saves much time with cascading styles. See the following two style declarations. The first declares a generic box with a 10px margin on all sides and a 10px padding on the top/bottom paired with 15px padding on the right/left. To top it off, we have a reddish border of 2px all the way around. The second builds on that idea, but mixes things up a little; the designer decided that the left side should always have a margin of 20px; and a blue colored border. {
    margin: 10px;
    padding: 10px 15px;
    border: #900 solid 2px;
div.callout {
    margin-left: 20px;
    border-color: #009;

So, if we have a box constructed as such: <div class="box callout">, you will see the following:

Voilà, we have a box with 10px margin on all but the left side, with a solid 2px border that is blue instead of red. And the padding stays as was declared for

This is only one simple example of many possible uses. But imagine the time you save not only authoring the CSS but maintaining it. In this case, if you want to change the margin-bottom for all boxes, you only have to change the code in one spot, instead of for every single box. The more you code, the more you understand how simple things like that make your life much easier.

Did you find this useful? Have more questions about it? Comment and let me know what other CSS stuff you want to learn more about.

Q: Where Does JavaScript Go?

The Web is ever changing, and this article is relatively ancient having been published 12 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

A: The bottom of your page, just before the </body> tag is your safest bet. Of course, with Web development, nothing is as easy as a blanket statement like that, right? But, when I’m helping people troubleshoot their JavaScript problems, 95% of the time the first step is to move the JS to the bottom, order the scripts properly and wrap it in some sort of function that starts only after the page is loaded. This not only fixes their problem, but often speeds up content loading. Read on to learn why this is a good rule.

You can’t affect an element that doesn’t yet exist

When attaching events to an object (one of the most often used JavaScript things I see), that object must exist to have an event attached. When you have a bit of script at the top of the page, it is run as soon as the script appears, meaning the object you’re trying to attach the event listener to doesn’t exist. For starters, the DOM, which is the structure that allows you to interact with elements in your page, has not finished loading at this point, nor have your elements inside of the <body>.

If your script is at the bottom, however, even if the DOM isn’t complete, chances are good that your element will at least exist on the page, able to be manipulated. That’s why nothing is happening when your code in the <head> is trying to set up some cool thing to happen when you click an object; the object didn’t “hear” you tell it to do that cool thing—it was in rendering limbo, outside the realm of your script’s reach.

Waiting for the DOM to be ready

Simply moving the code to the bottom doesn’t necessarily mean everything will be loaded, however. The best practice is to explicitly tell your code not to run until either the body is loaded (for older browsers), or until the DOM is ready (for modern browsers). I can’t explain how to do this in every library that exists, because I haven’t used them all (check out their documentation), and that’d make for a very long article, but in jQuery, it can be done with this code:

$(document).ready(function() {      ... all your code here ...    });

Or the shorthand version that looks like:

$(function(){    ... all your code here ...   });

However, if you’re manipulating images, you’ll need to wait until those are downloaded as well. That’s not necessarily done before the DOM says it’s ready. In that situation, you would wrap your code with:

$(window).load(function() {  ... your code ... });

The above is triggered after every piece of the document has been downloaded, including all of your images.

In plain-Jane non-libraried JavaScript, you’d be using something along the lines of

window.onload = function(){  ... your code ... });

This is the essentially the same as the method of <body onload="some code goes here">, which should not be used because you should be separating your function from content. Using window.onload allows you to have your code in a separate file, easily included or changed in multiple documents.

Does any one know how to check if the DOM is ready with plain JavaScript? Forgive me, but the process escapes me at the moment.

On the subject of page speed

Now, a slow-loading page isn’t necessarily a broken page, although some research shows that visitors will quickly bounce if they have to wait too long for the page to load. But page speed can often be improved, and many times it’s hanging because of scripts in the <head>. Most pages consist of a multitude of files in addition to the basic page: CSS, JavaScript, images, etc. To speed up loading times, browsers will try to download these in parallel—multiple files at the same time. JavaScript, however, is not pulled down in parallel. So, once a JavaScript file download starts, everything else is put on hold until the script finishes. If the JavaScript is in the <head> of your document, this means your users are starting at a blank screen while the script finishes. If your JavaScript is at the bottom of the page, your content loads first. Your well-written, interesting content should keep visitors busy while the rest of the scripts finish loading.

How I roll

I use the following order for setting up my scripts at the bottom of the page. I’ve found that it provides the best results for my uses both here on my personal site and on sites I develop for others.

  1. JS Library (usually jQuery)
  2. Plug-ins, if any (such as Lightbox, SimpleModal)
  3. My site-specific code (usually invoking plug-ins, form validation, etc)
  4. Social media plug-in (AddThis)
  5. Tracking code

You can view the source of this page to see all of that code at the bottom. (Or don’t, I really need to clean it up! I’m causing you to load the contact form validation even when there is no form. That’s very naughty of me, and I promise to fix it post haste.) The exceptions are ads and the custom search script which both appear at the point in the code where they show on the page, due to requirements of the code and companies.

When should you not place it at the bottom?

When making such a generalized statement like “at the bottom,” there are going to be exceptions. The number one exception to placing the code at the very bottom of the page is: when the provided documentation, manual, or instructions say otherwise. Now, I rarely come across such instructions except for in outdated code that shouldn’t be used anyhow*. One notable exception is SWFObject, a wonderful script for use with Flash on a page. They say put the code in the <head>. I haven’t done enough testing to say that it’ll work with the script at the bottom, so <head> it is.

The other exceptions I see regularly are ads and widgets. Ad servers, such as Google AdSense, are usually structured so that you place the scripts wherever you want the ad to appear. Unfortunately, these slow down your page load, but there’s nothing to be done until they improve their scripts. Likewise, some widgets require placement at the point in the code where they should appear rather than at the bottom of the page. Try to find alternatives if possible, otherwise, do as the documentation instructs.

A final note, speaking of code that’s supposed to go in the <head> element…: please, please, for the love of all things sacred do not use MM_Preload or MM_Menu or any other old Dreamweaver/Fireworks JavaScript that is prefixed by “MM.” Without exception, I have never seen this code do anything that cannot be accomplished in a better way, often without the use of JavaScript to begin with. </rant>

Do you have any other quick JS debugging tips? Has this strategy fixed your JS issues?