Syndicate content
News, opinion, and fresh thinking for web developers and designers. The official podcast of sitepoint.com.
Updated: 3 weeks 4 days ago

5 Tips for Dealing With Clients Who Won’t Pay

Fri, 01/13/2012 - 16:46

If the current economic condition isn’t tough for you, remember that some of your clients may be suffering. That said, we all have clients who are slow to pay no matter how well they’re faring. If you’re new to freelancing, you’ll soon understand the importance of cashflow. On the other hand, you’ll also understand the importance of keeping customers happy.

I hope you never find yourself in the position of chasing payment but, remember, you are in the right (assuming you supplied what was agreed). Here are five tips to help reduce the stress caused by non-paying clients…

1. Be Proactive and Have a Process

Even if you’re a one-person company, there’s no excuse for not having a clearly defined processes and policies for dealing with late payments. Chasing money is time-consuming; having a process in-place will help your sanity and profitability.

2. Contact the Client Immediately

Contact the client directly on the day payment becomes overdue. Try not to use email — a telephone call or face-to-face meeting is far more effective. During your conversation:

  1. Ask whether there have been any problems with the work you supplied.
  2. State you have not received payment and ask whether they had problems paying.
  3. Ask when the payment will be made and agree a date. If they don’t know, state that you will call the following day once they’ve had a chance to investigate.

Be polite and don’t make unreasonable demands. In many cases, the client may simply have been away or has forgotten — you’ll be paid immediately. GA_googleFillSlot("InArticle_728x90_1");

3. Nudge the Client Harder

If you remain unpaid, contact the person directly responsible for paying invoices. This is fairly easy for larger companies — simply call the reception and ask. It’ll also give you a chance to build a relationship with another person in the company. In some cases, the organization may simply have a payment schedule which is different to yours.

It’s a little more difficult for smaller or one-person companies, but keep persisting. They’ll soon be dreading the embarrassment of your regular calls.

If payment is considerably delayed, write a formal letter stating a date when late fees and interest will start to accrue. Check the legal situation for your country; most have a statutory interest rates for overdue payments. US states vary between 6% and 10% per annum. It’s 8% in the UK.

4. Accept the Inevitable

If negotiations break down, write a letter stating that the client is in breach of contract (verbal agreements are still legally-binding in most countries) and you have no choice but to withdraw your services.

By all means, state that you will be instigating legal action on a specific date and they will be responsible for all debt recovery costs. But don’t make empty threats; be prepared to start legal proceedings on the understanding it may cost you more in time and money than the original payment — with no guarantee of success.

5. What NOT to do…

Never complain about a non-paying client to others — especially on social networks. It’s not professional and is unlikely to result in a positive outcome.

If you’ve delivered a web project where you’ve supplied the hosting, it’s tempting to flick the off switch or use a system such as CSS Killswitch to black-out their site. Be wary. While you may bathe in the warm glow of moralistic justification, it’s an antagonistic move which may ultimately end the relationship and won’t necessarily resolve the payment issue. In some cases, it may put you in breach of contract.

If you want to use a technical solution, provide the client with a written warning. It’s even better if you can give the impression that the whole process is automated or beyond your control in some way.

Alternatively, you could be a little more subtle. If a ‘bug’ caused, say, a security error message or shop payments to fail, the client may have no choice but to contact you. But I wouldn’t suggest you should ever be that sneaky…

BONUS TIP: Prevention is Better Than Cure

In my next post we’ll discuss how you can avoid payment problems from the start.

How did you deal with a non-paying client? Would you do the same again?

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

SitePoint Podcast #145: Backbone.js Fundamentals with Addy Osmani

Fri, 01/13/2012 - 14:40

Episode 145 of The SitePoint Podcast is now available! This week our regular interview host Louis Simoneau (@rssaddict) interviews Addy Osmani (@addyosmani) about his free online book about the Fundamentals Of Backbone.js and how using javascript frameworks can really help when building a front-end Web app.

Listen in Your Browser

Play this episode directly in your browser — just click the orange “play” button below:

Download this Episode

You can download this episode as a standalone MP3 file. Here’s the link:

Subscribe to the Podcast

The SitePoint Podcast is on iTunes! Add the SitePoint Podcast to your iTunes player. Or, if you don’t use iTunes, you can subscribe to the feed directly.

Episode Summary

Louis chats to Addy Osmani (@addyosmani) about backbone.js. GA_googleFillSlot("InArticle_728x90_1");

Browse the full list of links referenced in the show at http://delicious.com/sitepointpodcast/145.

Interview Transcript

Transcript To Follow

Theme music by Mike Mella.

Thanks for listening! Feel free to let us know how we’re doing, or to continue the discussion, using the comments field below.

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

ASP.NET 4.5 Bundling and Minification Support

Fri, 01/13/2012 - 14:07

If you’re serious about web development, you strive for a fast website.  Nothing beats the feeling of sitting back and viewing a great website that’s fast.  Speed matters.  Your customers expect it.  If you don’t think they do, you’re living in a different world to mine.  With a growing trend of consumers buying online in 2011, developers have to cope with the extra devices customers will use to browse your website.

There are many ways to increase the performance of a website, but the way with the biggest impact by far is to decrease the number of HTTP requests.  Every time you reference an image, CSS file, JavaScript file, video, audio or a flash file, that adds an extra HTTP request.  That is time that could be used elsewhere, such as taking customer orders!

One way of reducing the number of HTTP requests is to combine the files.  If you have three style sheets sitting in your web page, that’s three separate HTTP requests.  Combining them into one file means there’s only one HTTP request.

You can take this one step further and add minification to this process.  Minification is the process of stripping out all of the white-space and comments from your CSS and JavaScript files. GA_googleFillSlot("InArticle_728x90_1");

If you’re familiar with ASP.NET, bundling and minification was always a job for your build process.  With the advent of Visual Studio 2011 and ASP.NET 4.5, Microsoft has added bundling and minification out of the box, which in my opinion has been long overdue.  This process happens at run-time and is available to ASP.NET WinForms, MVC and Web Pages.

Installation

Before starting any development, you’ll need to install ASP.NET 4.5.  The simplest way to do this is via the Web Platform Installer.  All of the ASP.NET 4.5 articles I’m authoring are developed in Visual Studio 2011 Developer Preview. Below are the links to get started.

Why Do This?

The answer is simple; to reduce the number of HTTP requests that go between the client and server.  The result is a faster website.  By default when you create a new MVC 4 website, the following JavaScript files are loaded into the page.

<script type="text/javascript" src="../../Scripts/jquery-1.6.2.min.js"></script> <script type="text/javascript" src="../../Scripts/jquery-ui-1.8.11.js"></script> <script type="text/javascript" src="../../Scripts/modernizr-2.0.6-development-only.js"></script> <script type="text/javascript" src="../../Scripts/AjaxLogin.js"></script>

Looking at this through Chrome you can see the 4 separate HTTP requests.

We can do better that that! After you bundle it, you’ll see one request.

Where’s the Magic?

The magic happens at runtime in ASP.NET 4.5.  Instead of referencing each JavaScript file separately, you can replace them all with this:

<script src="scripts/js"></script>

And you can also bundle and minify your CSS files too by adding this line of code:

<link href="content/css" rel="stylesheet" />

This is assuming you have your JavaScript files in a folder called scripts, and your style sheets are in a folder called content.  This is configurable, of course – as you’ll soon see.

Before this will work, you need to add one line of code to the global.asax file in the Application Start event.

Bundle.Bundles.EnableDefaultBundles();

The need for this line of code will be removed when ASP.NET 4.5 is released.  When the website is running, if ASP.NET encounters either of these tags, it will automatically bundle and minify each file in the given folder and send back a single HTTP response for the JavaScript file and a single response for the CSS.  Out of the box you don’t need to do anything else.  This is a welcome feature.

By default, when the files are bundled by ASP.NET they are in alphabetical order.  If there are known libraries such as jQuery, jQuery UI and Dojo, they are loaded first.  For the CSS files, they are also bundled in alphabetical order.  The results can be seen in the image below.

Custom Rules

If the default bundling rules don’t give you the control that you need, you can always create your own bundling rules.  A common reason for doing this is to group common libraries.  There aren’t too many occasions when you need to bundle your entire JavaScript or CSS files into the one file.  To create a custom rule you create a new Bundle object.  Then you add files individually or an entire directory.

var jSBundle = new Bundle("~/CustomJs", typeof(JsMinify)); jSBundle.AddFile("~/Scripts/CustomFunction.js"); jSBundle.AddFile("~/Scripts/jquery-1.4.1-vsdoc.js"); jSBundle.AddFile("~/Scripts/jquery-1.4.1.js"); jSBundle.AddFile("~/Scripts/JSONCreate.js");

Notice the type JsMinify above?  That’s the default object that bundles and minifies the JavaScript files.  For CSS, you use CssMinify like the example below.

var cssBundle = new Bundle("~/CustomCss", typeof(CssMinify)); cssBundle.AddFile("~/Content/Collection.css"); cssBundle.AddFile("~/Content/GlobalSupport.css"); cssBundle.AddFile("~/Content/MasterStyle.css"); cssBundle.AddFile("~/Styles/MenuStyle.css");

To reference these custom rules, you put the name of each bundle in your HTML.

<script src="CustomJs"></script> or <link href="CustomCss" rel="stylesheet" />Custom Processing

If you want total control, you can override the default CSS and JavaScript bundling support and replace it with a custom process.  An easy way to do this is to create a class that implements the IBundleTransform interface.  The following example is trivial but it demonstrates how to do this.  The example inserts a company copyright into each JavaScript files and sets the default cache for the file.

public class AddCopyrightToFiles : IBundleTransform { public void Process(BundleResponse bundle) { StringBuilder sb = new StringBuilder(); sb.AppendLine("// Copyright your company"); sb.AppendLine(bundle.Content); bundle.Content = sb.ToString(); bundle.Cacheability = HttpCacheability.ServerAndNoCache; } }

And to use this custom process, create a new Bundle and reference the custom class.

BundleTable.Bundles.EnableDefaultBundles(); Bundle customBundle = new Bundle("~/CustomBundle", typeof(AddCopyrightToFiles)); customBundle.AddFile("~/Scripts/CustomTypes.js"); BundleTable.Bundles.Add(customBundle);

And in the HTML, just reference the bundle by its name.

<script src="CustomBundle"></script>Unbundle JavaScript Files

It’s worth noting that there are services that will unbundle your files, or beautify them.  The one I love to use is jsbeautifier.  This flattens the file.  One of the biggest drawbacks of bundling and minification is readability.

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

Google’s New Top vs. Side Segment 101

Thu, 01/12/2012 - 05:30

In any online business, one of the most important ways to make money is through advertising. If a business owner does not put their business out there in front of the public then people have no way of finding them, and if people can’t find them, they can’t make money.

A huge part of most businesses ad portfolio is pay per click ads. With these comes a huge amount of data that needs to be crunched in order to make sure the advertising budget is being spent in the right places. Ad managers only have limited resources and they need to make sure they are not being allocated to unprofitable ad campaigns. One important piece of data that ad managers need to look at is how effective an ad is in a certain position. Some ads perform better on the side, and others hit higher marks on top.

Recently, Google AdWords rolled out a feature that lets ad managers keep track of how their ads do on the side of Google search results versus the top. This is incredibly valuable information because it lets businesses know where they should invest more of their money when it comes to ad placement. GA_googleFillSlot("InArticle_728x90_1");

When it comes to data on a PPC ad campaign, there is no such thing as too much information, and this Top vs. Side feature on Google AdWords is just another piece of the information puzzle.

The first step is access this data. To do so is a fairly simple process. The follow is a step by step guide to access this data:

  1. Select the Campaign, then click the Ad groups, Ads or Keywords tab of the AdWords account.
  2. Click the Segment button in the toolbar above the data table.
  3. Select Top vs. side from the drop-down menu. The results will appear in rows beneath each of the ads in the selected campaign.

Having access to this data is great, but it still needs to be interpreted in order to really make proper use of it. This is where AdWords advanced reports come in, they make it so the data can be properly parsed for the important information, which can really help an ad campaign manager make the most of their budget.

The first kind of report to run is Head Keyword Performance. To run this report, follow these simple steps:

  1. Go to the Keyword tab on AdWords
  2. Create a filter that shows keywords with a minimum of clicks, impressions or conversions, depending on which metric the particular site uses.
  3. Select the proper campaign that shows the correct unbranded keywords.
  4. Go the segment menu and select Top vs. Side

This new report will present the most important keywords. Using this report allows ad managers to see which keywords are effective at a reasonable cost. Because these keywords are the highest performing, small tweaks and improvements can make a huge difference to the bottom line.

The next report this new tweak from Google allows access to is an Ad Text Performance report. This report will provide information about how certain keywords perform depending on which position they appear in on Google.

  1. Go over to the Ads tab in AdWords.
  2. Create a filter that show ads with a minimum of clicks, impressions or conversions depending on what metrics the site in question uses.
  3. Select the campaigns or ad groups that contain the ads information is need on.
  4. Look at the segment menu and select Top vs. Side

This will provide some incredibly valuable information about how keywords can affect performance, and really let the ad managers know what words to run on the side and what words should be placed on the top. Since the top costs more than the side, they will want to make sure they optimize what ads they are spending the extra money on.

Ad managers should take some time to really explore this new feature of Google AdWords. There are all kinds of reports they can run to truly narrow down when it is worth placing an ad at the top, and when it draws more attention on the side of the page.

Play around with the different kind of reports and find out what works best. Every company has different priorities, but the basic reports shown here will help a lot finding exactly what works.

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

How To Increase Conversions by 50% Overnight

Thu, 01/12/2012 - 05:06

A few years ago free shipping was taking the e-commerce world by storm … we saw several of our competitors implement free or flat-rate shipping and decided it was time to give it a try. In our e-commerce business we decided to offer free shipping on orders above $100, and flat rate shipping on all other orders (to the contiguous US). We created a coupon code that customers had to enter into the shopping cart at checkout to claim the promotional shipping offer, and added banners to every page of our website advertising the promotion and code.

The free shipping offer was very successful, and we saw a noticeable spike in conversion rate and orders. There were also a number of people who didn’t select the free shipping offer, and we just assumed they wanted their order shipped via a specific carrier. After a while, we started to get a few complaints from customers that overlooked the coupon code or couldn’t remember it once they were on the checkout screen. They would email us asking why they paid for shipping, when our site advertises it as being free.

During the holiday shopping season that year we did some user testing through UserTesting.com and quickly realized the free shipping offer was a major source of confusion with potential customers. Many didn’t see the banners advertising the offer, and of the ones that did, quite a few overlooked the coupon code. GA_googleFillSlot("InArticle_728x90_1");

I decided to make the flat rate shipping the default, and automatically select free shipping for all qualifying orders (in US over $100). Our e-commerce software wasn’t really set up to handle that kind of scenario, so I actually wrote a custom shipping module for our e-commerce platform.

When we implemented the new shipping options on our website, our conversion rate increased by 50% overnight.

Find Areas of Frustration

Adding the free shipping offer increased conversions, sure. But the way we implemented it also caused a lot of confusion and frustration. For months, we didn’t even know we had a problem. Looking back, I shudder to think how much revenue we lost in that period of time.

We get so used to our own websites, it’s hard to see it from a visitor’s perspective. Usability testing is the answer. Use a service such as UserTesting.com to let real users evaluate your website or landing page. UserTesting.com is a very affordable remote usability testing service that employs real users to test your website according to criteria you determine. You choose your target demographic including age, income, gender and even web experience. The user follows your instructions, recording their screen and audio as they tell you what they are thinking through each step of the process.

The real feedback you get from these users will likely give you several areas in need of improvement.

You can also use tools like CrazyEgg.com to see where people click, even areas that aren’t hotlinked, and your web analytics package can often shed some light on potential problem areas as well.

Survey Your Visitors

Another great way to find out about potential problem areas is to conduct an exit survey on your visitors. Invite visitors who started filling out your contact form, or have added an item to their shopping cart but didn’t complete the transaction to tell you about their experience.

You might be surprised to hear the reasons they left. Some may have just been doing research or comparison shopping, but some will have experienced problems along the way that prevented them from completing.

Test Changes

Using a tool such as Google Website Optimizer, test changes to problem areas (one at a time). I have made changes I was sure would increase conversions and to my surprise they actually made things worse. Even with all our experience, some things just aren’t “logical.” Test, test, test.

Using simple A/B split testing in GWO, test a couple of different variations and see which one performs best. Then move on to another problem area, make a change and test. Continue making changes, and testing, to continuously improve your conversion rate over time. You’ll likely find that some changes will have drastic improvements, like ours above, and others may only increase conversion rates by 5% or 10%.

Always Work to Improve Conversions

You should always be working to improve your conversion rates. If you run out of areas to test, check out this great article by Conversion Rate Experts. That will give you a few things to try: 108 to be exact!

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

3 Step Plan to Grow Your Business in 2012

Thu, 01/12/2012 - 04:52

Identify Your Ideal Clients

Not all clients are ideal. The Pareto principle, also known as the 80/20 rule, states that for many events roughly 80% of the effect comes from just 20% of the causes. In our case that translates to: “80% of your revenues come from just 20% of your clients”.

Not only have I found the Pareto principle to be true, I’ve also found that it works in reverse too. The worst 20% of our clients seem to monopolize 80% of our unbillable time doing account service, quoting projects that never reach fruition, and resending statements dealing with accounts payable.

You can free up so much energy and drive up your profit margin and overall revenues by identifying which of your clients are the 20%. We did this by creating a list of criteria we feel is important in a client, and we then rated each and every client on those criteria.

Find Opportunities with Existing Clients

Once you know who your top clients are, it’s time to do more work with them! You know how to almost guarantee more work from a client? Talk to them. Often.

That’s right, there’s no secret strategy – if you don’t ever talk to a client there’s a good chance they won’t talk to you either. Out of sight out of mind. So pick up the phone and give them a call. Take them to lunch or out for coffee and ask them about their recent challenges. What has been bugging them, what problems do they have? GA_googleFillSlot("InArticle_728x90_1");

When we do this we often find creative solutions to those problems naturally. We aren’t “selling” them anything, we’re just trying to help them find solutions to issues they are experiencing.

Find Other Clients with Those Same Problems

So you’ve found several opportunities with existing clients, and solved them. Don’t stop there … if they had that problem there’s a good chance other companies have, too. They are your ideal client (top 20%, remember?) so find some other clients like them with the same problem, and resell that solution.

They don’t have to be competitors, or even in the same industry. Often times it will be a problem entire categories face (service companies, for instance). Seek out other companies with those issues, and offer your expertise.

Repeat

We do this often with our existing clients, and it has led to both small and extremely large projects, and to new clients as well. Give it a try with one of your clients and let us know how it works out!

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

PHPMaster: Zend Job Queue

Wed, 01/11/2012 - 23:48

Web applications usually follow a synchronous communication model. However, non-interactive and long-running tasks (such as report generation) are better suited for asynchronous execution. One way to off-load tasks to run at a later time, or even on a different server, is use the Job Queue module available as a part of Zend Server 5 (though not as part of the Community Edition). Job Queue allows job scheduling based on time, priority, and even dependencies.

See the article here:
PHPMaster: Zend Job Queue

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

RubySource: How to Customize Twitter Bootstrap’s Design in a Rails app

Wed, 01/11/2012 - 21:45

Maybe customizing Twitter Bootstrap’s designlike this wasn’t such a good idea! Back in November I discussed various options for integrating Twitter Bootstrap into a Rails 3.1 app, including using the less-rails-bootstrap and bootstrap-sass gems. Then last month I wrote a follow up tutorial showing how to quickly create a working web site using Twitter Bootstrap, Formtastic and Tabulous. Today I’d like to continue this series by discussing how to customize the Twitter Bootstrap design itself.

Continue Reading:
RubySource: How to Customize Twitter Bootstrap’s Design in a Rails app

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

BuildMobile: Best iOS App for To Do List?

Wed, 01/11/2012 - 19:10

After carrying a trusty Black ‘n Red notebook for years (not quite hipster enough for a moleskin, you see…), I finally decided I should give complete digitisation a proper go. Trying various apps, I found some too complex, some too simple … and then one that felt just right. Remember the Milk Remember The Milk (RTM) began as a website-based service, but the companion iPhone app (and the newly released iPad app) takes it to the next level of usefulness. In order to trust anything as the “one and only” place to keep all of your tasks and reminders, you need to believe that you will always have it with you and that adding something will be quick and easy

Read the original post:
BuildMobile: Best iOS App for To Do List?

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

How to Customize the WordPress 3.3 Toolbar

Wed, 01/11/2012 - 16:26

You can make the WordPress interface easier for clients by removing unnecessary menus, widgets and meta boxes. However, in WordPress 3.3, the admin and header bars have been merged to create a single toolbar. It may also contain options you want to hide…

The WordPress Toolbar API

The new toolbar is defined using a single WP_Admin_Bar object (see wp-includes/class-wp-admin-bar.php). This provides a number of useful methods:

  • add_node() — add a new toolbar item
  • remove_node() — remove a toolbar item
  • get_node() — fetch a node’s properties
  • get_nodes() — fetch a list of all nodes
Removing Toolbar Items

We’re going to place our code into a reusable plugin named wp-content/plugins/change-toolbar.php but you could put it within your theme’s functions.php file.

WordPress plugins require a header at the top of the file, e.g.

<?php /* Plugin Name: Change Toolbar Plugin URI: http://www.sitepoint.com/change-wordpress-33-toolbar Description: Modifies the WordPress 3.3+ toolbar. Version: 1.0 Author: Craig Buckler Author URI: http://optimalworks.net/ License: GPL2 */

We now require a single function where our changes will be made: GA_googleFillSlot("InArticle_728x90_1");

function change_toolbar($wp_toolbar) { /* ... code to go here ... */ }

followed by an action hook which runs the function and passes the toolbar object:

add_action('admin_bar_menu', 'change_toolbar', 999);

We can now remove toolbar items within the change_toolbar() function. For example, the following line hides the WordPress logo and help sub-menu by referencing its ID, “wp-logo”:

$wp_toolbar->remove_node('wp-logo');

To remove other items you need to discover what ID they’re using. You could delve into the PHP code but there’s an easier way:

  • Open Firebug or your favorite Firebug-like development console.
  • Locate the toolbar item you want to remove (in most browsers you can right-click the item and select “Inspect Element”).
  • Navigate up the parent nodes until you find an LI tag. It will have an ID starting “wp-admin-bar-” followed by the internal ID code:

In this example, the Comments item is highlighted. Therefore, to remove it from the toolbar, we use:

$wp_toolbar->remove_node('comments'); Adding Toolbar Items

We can add toolbar items within the same function. The syntax is:

$wp_toolbar->add_node($arg);

Where $arg is an associative array containing:

  • id — the item’s ID
  • title — the title text
  • parent — the parent menu ID (optional)
  • href — the link URL (optional)
  • group — true if the node is a group (optional)
  • meta — another array providing other keys including: html, class, onclick, target, title, tabindex

Let’s add a “Help” item which links to our support pages:

$wp_toolbar->add_node(array( 'id' => 'myhelp', 'title' => 'Help', 'href' => 'http://mysite.com/support/', 'meta' => array('target' => 'help') ));

We could now add an email support link within a sub-menu by referencing the ‘myhelp’ ID in the parent:

$wp_toolbar->add_node(array( 'id' => 'mysupport', 'title' => 'Email Support', 'parent' => 'myhelp', 'href' => 'mailto:support@mysite.com?subject=support%20request' ));

I hope you find it useful — it’s easy to customize the whole WordPress 3.3 toolbar using a few API calls.

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

The Hidden Nuggets of WCAG2: The Wonderful World of ALT Attributes, Part I

Wed, 01/11/2012 - 11:16

Recently I judged the accessibility component of the Australian Web Awards. Time and time again I saw the same errors when it came to ALT attributes. Success Criterion 1.1.1 – the ALT attribute requirement – is a complicated success criterion.

Missing versus empty ALT attributes

Images must always have an ALT attribute. Don’t believe me? Then read When Not to Use an ALT Attribute and see if I can convince you.

ALT attributes are not TITLE attributes

TITLE attributes provide information on mouse hover. This is their purpose. The purpose of an ALT attribute is not to provide information on mouse hover – even though the ALT attribute does sometimes appear this way in certain browsers (such as Internet Explorer). The purpose of the ALT attribute is to provide an alternative, textual description of the image, for use by people who cannot access or see the image. So if you have some information that you want to appear to the user when hovering over an image, use the TITLE attribute, and keep the ALT attribute for describing the image. GA_googleFillSlot("InArticle_728x90_1");

Problems with ALT attributes

Also remember that ALT attributes (and TITLE attributes) are not available to keyboard users – therefore you should never put anything in an ALT attribute that isn’t conveyed by the image. That means no author or attribution text, dates or copyright information (unless it is displayed in the image itself).

Another issue occurs when people are browsing with images turned off. In Firefox, the ALT attribute is constricted to the size of the actual image – so if you have a 10 by 10 pixel GIF then it will be almost impossible to read the ALT attribute. In Internet Explorer the entire ALT attribute displays, but does not wrap, so can cause horizontal scrolling. In fact there has been an accessibility bug raised about this on Allybugs, and if you are interested you can co-sign the petition.

Writing ALT attributes

ALT attributes can be difficult to write. It is important to describe the function of the image, not the actual image itself (with one major exception: image galleries, which I will cover in another article). The context of an image will always inform what you should write in the ALT attribute. For example, an image of the world might have several different images, depending on its context within a site:

  • On a Greenpeace website it might say “Save our world”
  • On a travel website it might say “International travel”
  • On a University website it might say “We have campuses around the world”
  • On an auction website it might say “World globe approximately 30 cm in diameter, made of plastic and fully inflatable”
How long can ALT attributes be?

There are no hard and fast rules about the length of ALT attributes. The Working Group considered adding a 100 character maximum to the ALT attribute technique, but decided against it in WCAG2. While it might not be in the WCAG2 Techniques, it is a good rule to follow.

Next article I will be talking about specific ALT attribute requirements for images such as art, graphs, maps, links and images of text.

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

Project Scope Reduced? Make Sure You Still Get Paid

Wed, 01/11/2012 - 05:58

Three days into the new year, I was thrown a curve ball. A project I’d been working on had been wrapped up—great news! But that wrapping up was, in part, due to the fact that the project scope had been reduced.

Not great news.

Why not? Well, I discounted my rate for the client on the basis of the size of the project. Over the festive season, the project scope was reduced by more than 50%. And I’d already invoiced for the work I’d done.

Anatomy of freelancing folly

There are a number of elements to this problem. Let me pore painfully over them so that you, smart freelancer, can avoid them yourself.

First, when I presented the agreement for this project, I didn’t state the discount clearly on it—although I did explain it to the client. I don’t often discount my rates, so inexperience was the problem here.

By the time the new year hit, I was wishing I’d clearly stated the discount in the agreement.

Second, as I was submitting my most recent invoice at the end of last year, I had indications from the client that there wasn’t much work left to do. GA_googleFillSlot("InArticle_728x90_1");

If I hadn’t been in such a hurry to get paid, I might have spent some time thinking about this, and what it would mean for my remuneration on this job.

Third, I turned down a contract that came up after this one, because, since this was booked in, I couldn’t make time to take the second gig on.

While I’m not queuing at the soup kitchen just yet, that forfeited income certainly made the sting of my error so much greater.

What now?

These kinds of issues face freelancers all the time—you may even have experienced something similar yourself.

As I saw it, this situation left me with two options:

  1. Chalk it up to experience.
  2. Chalk it up to experience and try to recover some of the lost income.

The project I’m talking about here has already lead to other projects with this client, so they’re clearly happy with my work. And those other projects have been charged at my standard rate, which has not been a problem.

Additionally, I have a solid working relationship with the client team, and with the individuals I’m working with directly within that team. It’s just as well, because otherwise I might find the thought of trying to recover some of the lost income more than a little daunting.

Given all this, I contacted the client early in the new year to discuss an adjustment of my discount on the project. I was hoping that they’d be happy to entertain this request, based on three things:

  • they were aware of the discount up-front
  • they’d approved significantly more budget for this project
  • they’re as eager as I am to maintain a solid working relationship.

As it turned out, the client was keen to resolve the problem. They gave me back some of the work they’d taken in-house, and agreed to rectify the difference in the estimate with me.

Another lesson I learned from this experience is to include in my proposals a note to the effect that if the project scope drops by a certain percentage, a given percentage of the estimate will still need to be paid. While this isn’t an issue for small projects, when it comes to larger ones, it can be a really big deal.

Have you ever found yourself the unwitting victim of a scope reduction? How do you anticipate these kinds of problems in your project pitches? I’d love to hear your thoughts and advice in the comments.

Image courtesy stock.xchng user Ambrozjo.

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");

DesignFestival: 10 Awesome iOS App Icon Concepts

Wed, 01/11/2012 - 05:30

Almost everyone with an iPhone or iPad spends a lot of time trying out new apps. Soon enough, your home screen is cluttered and most things you’ve installed go unused. It’s important for designers to get the design of their icons right so they look like they’re in the right environment while still cutting through the mass of apps and enticing the user to come back and try it out again — a fine line to walk. Here are ten iOS app concepts from the first few weeks of 2012 for your inspiration

See the original post:
DesignFestival: 10 Awesome iOS App Icon Concepts

GA_googleFillSlot("Edit_300x100_C"); GA_googleFillSlot("Edit_300x100_D");