# articles

title: Incite A Riot
year: 2009
author: Jeremy Keith
author_slug: jeremykeith
published: 2009-12-11T00:00:00+00:00
url: https://24ways.org/2009/incite-a-riot/
topic: code
contents:
Given its relatively limited scope, HTML can be remarkably expressive. With a bit of lateral thinking, we can mark up content such as tag clouds and progress meters, even when we don’t have explicit HTML elements for those patterns.

Suppose we want to mark up a short conversation:

 
  Alice: I think Eve is watching. 

  Bob: This isn’t a cryptography tutorial …we’re in the wrong example!
 


A note in the the HTML 4.01 spec says it’s okay to use a definition list:


	Another application of DL, for example, is for marking up dialogues, with each DT naming a speaker, and each DD containing his or her words.


That would give us:

<dl>
	<dt>Alice</dt>: <dd>I think Eve is watching.</dd>
	<dt>Bob</dt>: <dd>This isn't a cryptography tutorial ...we're in the wrong example!</dd>
</dl>

This usage of a definition list is proof that writing W3C specifications and smoking crack are not mutually exclusive activities. “I think Eve is watching” is not a definition of “Alice.” If you (ab)use a definition list in this way, Norm will hunt you down.

The conversation problem was revisited in HTML5. What if dt and dd didn’t always mean “definition title” and “definition description”? A new element was forged: dialog. Now the the “d” in dt and dd doesn’t stand for “definition”, it stands for “dialog” (or “dialogue” if you can spell):

<dialog>
	<dt>Alice</dt>: <dd>I think Eve is watching.</dd>
	<dt>Bob</dt>: <dd>This isn't a cryptography tutorial ...we're in the wrong example!</dd>
</dialog>

Problem solved …except that dialog is no longer in the HTML5 spec. Hixie further expanded the meaning of dt and dd so that they could be used inside details (which makes sense—it starts with a “d”) and figure (…um). At the same time as the content model of details and figure were being updated, the completely-unrelated dialog element was dropped.

Back to the drawing board, or in this case, the HTML 4.01 specification. The spec defines the cite element thusly:


	Contains a citation or a reference to other sources.


Perfect! There’s even an example showing how this can applied when attributing quotes to people:

As <CITE>Harry S. Truman</CITE> said,
<Q lang="en-us">The buck stops here.</Q>

For longer quotes, the blockquote element might be more appropriate. In a conversation, where the order matters, I think an ordered list would make a good containing element for this pattern:

<ol>
	<li><cite>Alice</cite>: <q>I think Eve is watching.</q></li>
	<li><cite>Bob</cite>: <q>This isn't a cryptography tutorial ...we're in the wrong example!</q></li>
</ol>

Problem solved …except that the cite element has been redefined in the HTML5 spec:


	The cite element represents the title of a work … A person’s name is not the title of a work … and the element must therefore not be used to mark up people’s names.


HTML5 is supposed to be backwards compatible with previous versions of HTML, yet here we have a semantic pattern already defined in HTML 4.01 that is now non-conforming in HTML5. The entire justification for the change boils down to this line of reasoning:


	Given that: titles of works are often italicised and
	given that: people’s names are not often italicised and
	given that: most browsers italicise the contents of the cite element,
	therefore: the cite element should not be used to mark up people’s names.


In other words, the default browser styling is now dictating semantic meaning. The tail is wagging the dog.

Not to worry, the HTML5 spec tells us how we can mark up names in conversations without using the cite element:


	In some cases, the b element might be appropriate for names


I believe the colloquial response to this is a combination of the letters W, T and F, followed by a question mark.

The non-normative note continues:


	In other cases, if an element is really needed, the span element can be used.


This is not a joke. We are seriously being told to use semantically meaningless elements to mark up content that is semantically meaningful.

We don’t have to take it.

Firstly, any conformance checker—that’s the new politically correct term for “validator”—cannot possibly check every instance of the cite element to see if it’s really the title of a work and not the name of a person. So we can disobey the specification without fear of invalidating our documents.

Secondly, Hixie has repeatedly stated that browser makers have a powerful voice in deciding what goes into the HTML5 spec; if a browser maker refuses to implement a feature, then that feature should come out of the spec because otherwise, the spec is fiction. Well, one of the design principles of HTML5 is the Priority of Constituencies:


	In case of conflict, consider users over authors over implementors over specifiers over theoretical purity.


That places us—authors—above browser makers. If we resolutely refuse to implement part of the HTML5 spec, then the spec becomes fiction.

Join me in a campaign of civil disobedience against the unnecessarily restrictive, backwards-incompatible change to the cite element. Start using HTML5 but start using it sensibly. Let’s ensure that bad advice remains fictitious.

Tantek has set up a page on the WHATWG wiki to document usage of the cite element for conversations. Please contribute to it.


title: A Pet Project is For Life, Not Just for Christmas
year: 2009
author: Elliot Jay Stocks
author_slug: elliotjaystocks
published: 2009-12-18T00:00:00+00:00
url: https://24ways.org/2009/a-pet-project-is-for-life-not-just-for-christmas/
topic: business
contents:
I’m excited: as December rolls on, I’m winding down from client work and indulging in a big pet project I’ve been dreaming up for quite some time, with the aim of releasing it early next year. I’ve always been a bit of a sucker for pet projects and currently have a few in the works: the big one, two collaborations with friends, and my continuing (and completely un-web-related) attempt at music. But when I think about the other designers and developers out there whose work I admire, one thing becomes obvious: they’ve all got pet projects! Look around the web and you’ll see that anyone worth their salt has some sort of side project on the go. If you don’t have yours yet, now’s the time!

Have a pet project to collaborate with your friends

It’s not uncommon to find me staring at my screen, looking at beautiful websites my friends have made, grinning inanely because I feel so honoured to know such talented individuals. But one thing really frustrates me: I hardly ever get to work with these people! Sure, there are times when it’s possible to do so, but due to various project situations, it’s a rarity.

So, in order to work with my friends, I’ve found the best way is to instigate the collaboration outside of client work; in other words, have a pet project together! Free from the hard realities of budgets, time restraints, and client demands, you and your friends can come up with something purely for your own pleasures. If you’ve been looking for an excuse to work with other designers or developers whose work you love, the pet project is that excuse. They don’t necessarily have to be friends, either: if the respect is mutual, it can be a great way of breaking the ice and getting to know someone. 

 Figure 1: A forthcoming secret love-child from myself and Tim Van Damme

Have a pet project to escape from your day job

We all like to moan about our clients and bosses, don’t we? But if leaving your job or firing your evil client just isn’t an option, why not escape from all that and pour your creative energies into something you genuinely enjoy? 

It’s not just about reacting to negativity, either: a pet project is a great way to give yourself a bit of variety. As web designers, our day-to-day work forces us to work within a set of web-related contraints and sometimes it can be demoralising to spend so many hours fixing IE bugs. The perfect antidote? Go and do some print design! If it’s not possible in your day job or client work, the pet project is the perfect place to exercise your other creative muscles. Yes, print design (or your chosen alternative) has its own constraints, but if they’re different to those you experience on a daily basis, it’ll be a welcome relief and you’ll return to your regular work feeling refreshed.

 Figure 2: Ligature, Loop & Stem, from Scott Boms & Luke Dorny

Have a pet project to fulfill your own needs

Many pet projects come into being because the designers and/or developers behind them are looking for a tool to accomplish a task and find that it doesn’t exist, thus prompting them to create their own solution. In fact, the very app I’m using to write this article — Ommwriter, from Herraiz Soto & Co — was originally a tool they’d created for their internal staff, before releasing it to the public so that it could be enjoyed by others.

Just last week, Tina Roth Eisenberg launched Teux Deux, a pet project she’d designed to meet her own requirements for a to-do list, having found that no existing apps fulfilled her needs. Oh, and it was a collaboration with her studio mate Cameron. Remember what I was saying about working with your friends?

 Figure 3: Teux Deux, the GTD pet project that launched just last week

Have a pet project to help people out

Ommwriter and Teux Deux are free for anyone to use. Let’s just think about that for a moment: the creators have invested their time and effort in the project, and then given it away to be used by others. That’s very cool and something we’re used to seeing a lot of in the web community (how lucky we are)! People love free stuff and giving away the fruits of your labour will earn you major kudos. Of course, there’s nothing wrong with making some money, either — more on that in a second.

 Figure 4: Dan Rubin‘s extremely helpful Make Photoshop Faster

Have a pet project to raise your profile

So, giving away free stuff earns you kudos. And kudos usually helps you raise your profile in the industry. We all like a bit of shameless fame, don’t we? But seriously, if you want to become well known, make something cool. It could be free (to buy you the love and respect of the community) or it could be purchasable (if you’ve made something that’s cool enough to deserve hard-earned cash), but ultimately it needs to be something that people will love. 

 Figure 5: Type designer Jos Buivenga has shot to fame thanks to his beautiful typefaces and ‘freemium’ business model

If you’re a developer with no design skills, team up with a good designer so that the design community appreciate its aesthetic. If you’re a designer with no development skills, team up with a good developer so that it works. Oh, and not that I’d recommend you ever do this for selfish reasons, but collaborating with someone you admire — whose work is well-respected by the community — will also help raise your profile.

Have a pet project to make money

In spite of our best hippy-esque intentions to give away free stuff to the masses, there’s also nothing wrong with making a bit of money from your pet project. In fact, if your project involves you having to make a considerable financial investment, it’s probably a good idea to try and recoup those costs in some way.

 Figure 6: The success of Shaun Inman‘s various pet projects — Mint, Fever, Horror Vacui, etc. — have allowed him to give up client work entirely.

A very common way to do that in both the online and offline worlds is to get some sort of advertising. For a slightly different approach, try contacting a company who are relevant to your audience and ask them if they’d be interesting in sponsoring your project, which would usually just mean having their brand associated with yours in some way. This is still a form of advertising but tends to allow for a more tasteful implementation, so it’s worth pursuing. 

Advertising is a great way to cover your own costs and keep things free for your audience, but when costs are considerably higher (like if you’re producing a magazine with high production values, for instance), there’s nothing wrong with charging people for your product. But, as I mentioned above, you’ve got to be positive that it’s worth paying for!

Have a pet project just for fun

Sometimes there’s a very good reason for having a pet project — and sometimes even a viable business reason — but actually you don’t need any reason at all. Wanting to have fun is just as worthy a motivation, and if you’re not going to have fun doing it, then what’s the point? Assuming that almost all pet projects are designed, developed, written, printed, marketed and supported in our free time, why not do something enjoyable?

 Figure 7: Jessica Hische‘s beautiful Daily Drop Cap

In conclusion

The fact that you’re reading 24 ways shows that you have a passion for the web, and that’s something I’m happy to see in abundance throughout our community. Passion is a term that’s thrown about all over the place, but it really is evident in the work that people do. It’s perhaps most evident, however, in the pet projects that people create. Don’t forget that the very site you’re reading this article on is… a pet project.

If you’ve yet to do so, make it a new year’s resolution for 2010 to have your own pet project so that you can collaborate with your friends, escape from your day job, fulfil your own needs, help people out, raise your profile, make money, and — above all — have fun.


title: Rock Solid HTML Emails
year: 2009
author: David Greiner
author_slug: davidgreiner
published: 2009-12-13T00:00:00+00:00
url: https://24ways.org/2009/rock-solid-html-emails/
topic: code
contents:
At some stage in your career, it’s likely you’ll be asked by a client to design a HTML email. Before you rush to explain that all the cool kids are using social media, keep in mind that when done correctly, email is still one of the best ways to promote you and your clients online. In fact, a recent survey showed that every dollar spent on email marketing this year generated more than $40 in return. That’s more than any other marketing channel, including the cool ones.

There are a whole host of ingredients that contribute to a good email marketing campaign. Permission, relevance, timeliness and engaging content are all important. Even so, the biggest challenge for designers still remains building an email that renders well across all the popular email clients.

Same same, but different

Before getting into the details, there are some uncomfortable facts that those new to HTML email should be aware of. Building an email is not like building for the web. While web browsers continue their onward march towards standards, many email clients have stubbornly stayed put. Some have even gone backwards. In 2007, Microsoft switched the Outlook rendering engine from Internet Explorer to Word. Yes, as in the word processor. Add to this the quirks of the major web-based email clients like Gmail and Hotmail, sprinkle in a little Lotus Notes and you’ll soon realize how different the email game is.

While it’s not without its challenges, rest assured it can be done. In my experience the key is to focus on three things. First, you should keep it simple. The more complex your email design, the more likely is it to choke on one of the popular clients with poor standards support. Second, you need to take your coding skills back a good decade. That often means nesting tables, bringing CSS inline and following the coding guidelines I’ll outline below. Finally, you need to test your designs regularly. Just because a template looks nice in Hotmail now, doesn’t mean it will next week.

Setting your lowest common denominator

To maintain your sanity, it’s a good idea to decide exactly which email clients you plan on supporting when building a HTML email. While general research is helpful, the email clients your subscribers are using can vary significantly from list to list. If you have the time there are a number of tools that can tell you specifically which email clients your subscribers are using. Trust me, if the testing shows almost none of them are using a client like Lotus Notes, save yourself some frustration and ignore it altogether. 

Knowing which email clients you’re targeting not only makes the building process easier, it can save you lots of time in the testing phase too. For the purpose of this article, I’ll be sharing techniques that give the best results across all of the popular clients, including the notorious ones like Gmail, Lotus Notes 6 and Outlook 2007. Just remember that pixel perfection in all email clients is a pipe dream.

Let’s get started.

Use tables for layout

Because clients like Gmail and Outlook 2007 have poor support for float, margin and padding, you’ll need to use tables as the framework of your email. While nested tables are widely supported, consistent treatment of width, margin and padding within table cells is not. For the best results, keep the following in mind when coding your table structure.

Set the width in each cell, not the table

When you combine table widths, td widths, td padding and CSS padding into an email, the final result is different in almost every email client. The most reliable way to set the width of your table is to set a width for each cell, not for the table itself.

<table cellspacing="0" cellpadding="10" border="0">
	<tr>
		<td width="80"></td>
		<td width="280"></td>
	</tr>
</table>

Never assume that if you don’t specify a cell width the email client will figure it out. It won’t.  Also avoid using percentage based widths. Clients like Outlook 2007 don’t respect them, especially for nested tables. Stick to pixels. If you want to add padding to each cell, use either the cellpadding attribute of the table or CSS padding for each cell, but never combine the two.

Err toward nesting

Table nesting is far more reliable than setting left and right margins or padding for table cells. If you can achieve the same effect by table nesting, that will always give you the best result across the buggier email clients.

Use a container table for body background colors

Many email clients ignore background colors specified in your CSS or the <body> tag. To work around this, wrap your entire email with a 100% width table and give that a background color.

<table cellspacing="0" cellpadding="0" border="0" width="100%">
	<tr>
		<td bgcolor=”#000000”>
			Your email code goes here.
		</td>
	</tr>
</table>

You can use the same approach for background images too. Just remember that some email clients don’t support them, so always provide a fallback color.

Avoid unnecessary whitespace in table cells

Where possible, avoid whitespace between your <td> tags. Some email clients (ahem, Yahoo! and Hotmail) can add additional padding above or below the cell contents in some scenarios, breaking your design for no apparent reason.

CSS and general font formatting

While some email designers do their best to avoid CSS altogether and rely on the dreaded <font> tag, the truth is many CSS properties are well supported by most email clients. See this comprehensive list of CSS support across the major clients for a good idea of the safe properties and those that should be avoided. 

Always move your CSS inline

Gmail is the culprit for this one. By stripping the CSS from the <head> and <body> of any email, we’re left with no choice but to move all CSS inline. The good news is this is something you can almost completely automate. Free services like Premailer will move all CSS inline with the click of a button. I recommend leaving this step to the end of your build process so you can utilize all the benefits of CSS.

Avoid shorthand for fonts and hex notation

A number of email clients reject CSS shorthand for the font property. For example, never set your font styles like this.

p {
	font:bold 1em/1.2em georgia,times,serif;
}

Instead, declare the properties individually like this.

p {
	font-weight: bold;
	font-size: 1em;
	line-height: 1.2em;
	font-family: georgia,times,serif;
}

While we’re on the topic of fonts, I recently tested every conceivable variation of @font-face across the major email clients. The results were dismal, so unfortunately it’s web-safe fonts in email for the foreseeable future.

When declaring the color property in your CSS, some email clients don’t support shorthand hexadecimal colors like color:#f60; instead of color:#ff6600;. Stick to the longhand approach for the best results.

Paragraphs

Just like table cell spacing, paragraph spacing can be tricky to get a consistent result across the board. I’ve seen many designers revert to using double <br /> or DIVs with inline CSS margins to work around these shortfalls, but recent testing showed that paragraph support is now reliable enough to use in most cases (there was a time when Yahoo! didn’t support the paragraph tag at all).

The best approach is to set the margin inline via CSS for every paragraph in your email, like so:

p {
	margin: 0 0 1.6em 0;
}

Again, do this via CSS in the head when building your email, then use Premailer to bring it inline for each paragraph later.

If part of your design is height-sensitive and calls for pixel perfection, I recommend avoiding paragraphs altogether and setting the text formatting inline in the table cell. You might need to use table nesting or cellpadding / CSS to get the desired result. Here’s an example:

<td width="200" style="font-weight:bold; font-size:1em; line-height:1.2em; font-family:georgia,'times',serif;">your height sensitive text</td>

Links

Some email clients will overwrite your link colors with their defaults, and you can avoid this by taking two steps. First, set a default color for each link inline like so:

<a href="http://somesite.com/" style="color:#ff00ff">this is a link</a>

Next, add a redundant span inside the a tag.

<a href="http://somesite.com/" style="color:#ff00ff"><span style="color:#ff00ff">this is a link</span></a>

To some this may be overkill, but if link color is important to your design then a superfluous span is the best way to achieve consistency.

Images in HTML emails

The most important thing to remember about images in email is that they won’t be visible by default for many subscribers. If you start your design with that assumption, it forces you to keep things simple and ensure no important content is suppressed by image blocking.

With this in mind, here are the essentials to remember when using images in HTML email:

Avoid spacer images

While the combination of spacer images and nested tables was popular on the web ten years ago, image blocking in many email clients has ruled it out as a reliable technique today. Most clients replace images with an empty placeholder in the same dimensions, others strip the image altogether. Given image blocking is on by default in most email clients, this can lead to a poor first impression for many of your subscribers. Stick to fixed cell widths to keep your formatting in place with or without images.

Always include the dimensions of your image

If you forget to set the dimensions for each image, a number of clients will invent their own sizes when images are blocked and break your layout. Also, ensure that any images are correctly sized before adding them to your email. Some email clients will ignore the dimensions specified in code and rely on the true dimensions of your image. 

Avoid PNGs

Lotus Notes 6 and 7 don’t support 8-bit or 24-bit PNG images, so stick with the GIF or JPG formats for all images, even if it means some additional file size.

Provide fallback colors for background images

Outlook 2007 has no support for background images (aside from this hack to get full page background images working). If you want to use a background image in your design, always provide a background color the email client can fall back on. This solves both the image blocking and Outlook 2007 problem simultaneously.

Don’t forget alt text

Lack of standards support means email clients have long destroyed the chances of a semantic and accessible HTML email. Even still, providing alt text is important from an image blocking perspective. Even with images suppressed by default, many email clients will display the provided alt text instead. Just remember that some email clients like Outlook 2007, Hotmail and Apple Mail don’t support alt text at all when images are blocked.

Use the display hack for Hotmail

For some inexplicable reason, Windows Live Hotmail adds a few pixels of additional padding below images. A workaround is to set the display property like so.

img {display:block;}

This removes the padding in Hotmail and still gives you the predicable result in other email clients.

Don’t use floats

Both Outlook 2007 and earlier versions of Notes offer no support for the float property. Instead, use the align attribute of the img tag to float images in your email.

<img src="image.jpg" align="right">

If you’re seeing strange image behavior in Yahoo! Mail, adding align=“top” to your images can often solve this problem.

Video in email

With no support for JavaScript or the object tag, video in email (if you can call it that) has long been limited to animated gifs. However, some recent research I did into the HTML5 video tag in email showed some promising results.

Turns out HTML5 video does work in many email clients right now, including Apple Mail, Entourage 2008, MobileMe and the iPhone. The real benefit of this approach is that if the video isn’t supported, you can provide reliable fallback content such as an animated GIF or a clickable image linking to the video in the browser.

Of course, the question of whether you should add video to email is another issue altogether. If you lean toward the “yes” side check out the technique with code samples.

What about mobile email?

The mobile email landscape was a huge mess until recently. With the advent of the iPhone, Android and big improvements from Palm and RIM, it’s becoming less important to think of mobile as a different email platform altogether.

That said, there are a few key pointers to keep in mind when coding your emails to get a decent result for your more mobile subscribers.

Keep the width less than 600 pixels

Because of email client preview panes, this rule was important long before mobile email clients came of age. In truth, the iPhone and Pre have a viewport of 320 pixels, the Droid 480 pixels and the Blackberry models hover around 360 pixels. Sticking to a maximum of 600 pixels wide ensures your design should still be readable when scaled down for each device. This width also gives good results in desktop and web-based preview panes.

Be aware of automatic text resizing

In what is almost always a good feature, email clients using webkit (such as the iPhone, Pre and Android) can automatically adjust font sizes to increase readability. If testing shows this feature is doing more harm than good to your design, you can always disable it with the following CSS rule:

-webkit-text-size-adjust: none;

Don’t forget to test

While standards support in email clients hasn’t made much progress in the last few years, there has been continual change (for better or worse) in some email clients. Web-based providers like Yahoo!, Hotmail and Gmail are notorious for this. On countless occasions I’ve seen a proven design suddenly stop working without explanation.

For this reason alone it’s important to retest your email designs on a regular basis. I find a quick test every month or so does the trick, especially in the web-based clients. The good news is that after designing and testing a few HTML email campaigns, you will find that order will emerge from the chaos. Many of these pitfalls will become quite predictable and your inbox-friendly designs will take shape with them in mind.

Looking ahead

Designing HTML email can be a tough pill for new designers and standardistas to swallow, especially given the fickle and retrospective nature of email clients today. With HTML5 just around the corner we are entering a new, uncertain phase. Will email client developers take the opportunity to repent on past mistakes and bring email clients into the present? The aim of groups such as the Email Standards Project is to make much of the above advice as redundant as the long-forgotten <blink> and <marquee> tags, however, only time will tell if this is to become a reality.

Although not the most compliant (or fashionable) medium, the results speak for themselves – email is, and will continue to be one of the most successful and targeted marketing channels available to you. As a designer with HTML email design skills in your arsenal, you have the opportunity to not only broaden your service offering, but gain a unique appreciation of how vital standards are.

Next steps

Ready to get started? There are a number of HTML email design galleries to provide ideas and inspiration for your own designs. 


	http://www.campaignmonitor.com/gallery/
	http://htmlemailgallery.com/
	http://inboxaward.com/


Enjoy!


title: The Construction of Instruction
year: 2009
author: Relly Annett-Baker
author_slug: rellyannettbaker
published: 2009-12-08T00:00:00+00:00
url: https://24ways.org/2009/the-construction-of-instruction/
topic: content
contents:
If the world were made to my specifications, all your clients would be happy to pay for a web writer to craft every sentence into something as elegant as it was functional, and the client would have planned the content so that you had it just when you asked, but we both know that won’t happen every time. Sometimes you just know they are going to write the About page, two company blog pages and a Facebook fan page before resigning their position as chief content writer and you are going to end up filling in all the details that will otherwise just be Lorem Ipsum.

Welcome to the big world of microcopy:


	A man walks into a bar. The bartender nods a greeting and watches as the man scans the bottles behind the bar. 
“Er, you have a lot of gin here. Is there one you would recommend?” 
“Yes sir.”
Long pause. 
“… Never mind, I’ll have the one in the green bottle.” 
“Certainly, sir. But you can’t buy it from this part of the bar. You need to go through the double doors there.” 
“But they look like they lead into the kitchen.” 
“Really, sir? Well, no, that’s where we allow customers to purchase gin.” 
The man walks through the doors. On the other side he is greeted by the same bartender. 
“Y-you!” he stammers but the reticent bartender is now all but silent. 
Unnerved, the man points to a green bottle, “Er, I’d like to buy a shot of that please. With ice and tonic water.” 
The bartender mixes the drink and puts it on the bar just out of the reach of the man and looks up. 
“Um, do you take cards?” the man asks, ready to present his credit card. 
The bartender goes to take the card to put it through the machine. 
“Wait! How much was it – with sales tax and everything? Do you take a gratuity?” 
The bartender simply shrugs. 
The man eyes him for a moment and decides to try his luck at the bar next door.


In the Choose Your Own Adventure version of this story there are plenty of ways to stop the man giving up. You could let him buy the gin right where he was; you could make the price more obvious; you could signpost the place to buy gin. The mistakes made by the bar and bartender are painfully obvious. And yet, there are websites losing users everyday due to the same lack of clear instruction.

A smidgen of well written copy goes a long way to reassure the nervous prospect. Just imagine if our man walked into the bar and the bartender explained that although the bar was here, sales were conducted in the next room because people were not then able to overhear the man’s card details. Instead, he is left to fend for himself. Online, we kick customers through the anonymous double doors with a merry ‘Paypal will handle your transaction!’.

Recently I worked on a site where the default error message, to account for anything happening that the developers hadn’t accounted for, was ‘SOMETHING HAS GONE WRONG!’. It might have been technically accurate but this is not how to inspire confidence in your customers that they can make a successful purchase through you. As everyone knows they can shop just fine, thank you very much, it is your site they will blame. Card declined? It’s the site. Didn’t know my email address has changed? It’s the site. Can’t log in? It’s the site.

Yes, yes. I know. None of these things are related to your site, or you the developer, but drop outs will be high and you’ll get imploring emails from your client asking you to wade knee deep into the site analytics to find a solution by testing 41 shades of blue because if it worked for Google…? Before you try a visual fix involving the Dulux paint chart breeding with a Pantone swatch, take an objective look at the information you are giving customers. How much are you assuming they know? How much are you relying on age-old labels and prompts without clarification?

Here’s a fun example for non-North Americans: ask your Granny to write out her billing address. If she looks at you blankly, tell her it is the address where the bank sends her statements. Imagine how many fewer instances of the wrong address there would be if we routinely added that information when people purchased from the UK? Instead, we rely on a language convention that hasn’t much common usage without explanation because, well, because we always have since the banks told us how we could take payments online.

So. Your client is busying themselves with writing the ultimate Facebook fan page about themselves and here you are left with creating a cohesive signup process or basket or purchase instructions. Here are five simple rules for bending puny humans to your will creating instructive instructions and constructive error messages that ultimately mean less hassle for you.

Plan what you want to say and plan it out as early as possible 

This goes for all content. Walk a virtual mile in the shoes of your users. What specific help can you offer customers to actively encourage continuation and ensure a minimal amount of dropouts? Make space for that information. One of the most common web content mistakes is jamming too much into a space that has been defined by physical boundaries rather than planned out. If you manage it, the best you can hope for is that no-one notices it was a last-minute job. Mostly it reads like a bad game of Tetris with content sticking out all over the place.

Use your words

Microcopy often says a lot in a few words but without those words you could leave room for doubt. When doubt creeps in a customer wants reassurance just like Alice:


	This time (Alice) found a little bottle… with the words ‘DRINK ME’ beautifully printed on it in large letters. It was all very well to say ‘Drink me,’ but the wise little Alice was not going to do that in a hurry. ‘No, I’ll look first,’ she said, ‘and see whether it’s marked “poison” or not’


Alice in Wonderland, Lewis Carroll.

Value clarity over brevity. Or a little more prosaically, “If in doubt, spell it out.” Thanks, Jeremy!

Be prepared to help


	‘Login failed: email/password combination is incorrect.’


Oh.


	‘Login failed: email/password combination is incorrect. 
Are you typing in all capitals? Caps Lock may be on. 
Have you changed your email address recently and not updated your account with us? Try your old email address first. 
Can’t remember your password? We can help you reset it.’ 


Ah!

Be direct and be informative

There is rarely a site that doesn’t suffer from some degree of jargon. Squash it early by setting a few guidelines about what language and tone of voice you will use to converse with your users. Be consistent. Equally, try to be as specific as possible when giving error messages or instructions and allay fears upfront.

Card payments are handled by paypal but you do not need a paypal account to pay.

We will not display your email address but we might need it to contact you.

Sign up for our free trial (no credit card required).

Combine copy and visual cues, learn from others and test new combinations

While visual design and copy can work independently, they work best together. New phrases and designs are being tested all the time so take a peek at abtests.com for more ideas, then test some new ideas and add your own results. Have a look at the microcopy pool on Flickr for some wonderful examples of little words and pictures working together. And yes, you absolutely should join the group and post more examples.


	A man walks into a bar. The bartender greets him in a friendly manner and asks him what he would like to drink. 
“Gin and Tonic, please.” 
“Yes sir, we have our house gin on offer but we also have a particularly good import here too.”
“The import, please.” 
“How would you like it? With a slice of lemon? Over ice?” 
“Both” 
“That’s £3.80. We accept cash, cards or you could open a tab.” 
“Card please.” 
“Certainly sir. Move just over here so that you can’t be observed. Now, please enter your pin number.” 
“Thank you.” 
“And here is your drink. Do let me know if there is a problem with it. I shall just be here at the bar. Enjoy.”


Cheers!


title: Real Fonts and Rendering: The New Elephant in the Room
year: 2009
author: Jeffrey Zeldman
author_slug: jeffreyzeldman
published: 2009-12-22T00:00:00+00:00
url: https://24ways.org/2009/real-fonts-and-rendering/
topic: design
contents:
My friend, the content strategist Kristina Halvorson, likes to call content “the elephant in the room” of web design. She means it’s the huge problem that no one on the web development team or client side is willing to acknowledge, face squarely, and plan for. 

A typical web project will pass through many helpful phases of research, and numerous beneficial user experience design iterations, while the content—which in most cases is supposed to be the site’s primary focus—gets handled haphazardly at the end. Hence, elephant in the room, and hence also artist Kevin Cornell’s recent use of elephantine imagery to illustrate A List Apart articles on the subject. But I digress.

Without discounting the primacy of the content problem, we web design folk have now birthed ourselves a second lumbering mammoth, thanks to our interest in “real fonts on the web“ (the unfortunate name we’ve chosen for the recent practice of serving web-licensed fonts via CSS’s decade-old @font-face declaration—as if Georgia, Verdana, and Times were somehow unreal). 

For the fact is, even bulletproof and mo’ bulletproofer @font-face CSS syntax aren’t really bulletproof if we care about looks and legibility across browsers and platforms.

Hyenas in the Breakfast Nook

The problem isn’t just that foundries have yet to agree on a standard font format that protects their intellectual property. And that, even when they do, it will be a while before all browsers support that standard—leaving aside the inevitable politics that impede all standardization efforts. Those are problems, but they’re not the elephant. Call them the coyotes in the room, and they’re slowly  being tamed.

Nor is the problem that workable, scalable business models (of which Typekit‘s is the most visible and, so far, the most successful) are still being shaken out and tested. The quality and ease of use of such services, their stability on heavily visited sites (via massively backed-up server clusters), and the fairness and sustainability of their pricing will determine how licensing and serving “real fonts” works in the short and long term for the majority of designer/developers.

Nor is our primary problem that developers with no design background may serve ugly or illegible fonts that take forever to load, or fonts that take a long time to download and then display as ordinary system fonts (as happens on, say, about.validator.nu). Ugliness and poor optimization on the web are nothing new. That support for @font-face in Webkit and Mozilla browsers (and for TrueType fonts converted to Embedded OpenType in Internet Explorer) adds deadly weapons to the non-designer’s toolkit is not the technology’s fault. JavaScript and other essential web technologies are equally susceptible to abuse. 

Beauty is in the Eye of the Rendering Engine

No, the real elephant in the room—the thing few web developers and no “web font” enthusiasts are talking about—has to do with legibility (or lack thereof) and aesthetics (or lack thereof) across browsers and platforms. Put simply, even fonts optimized for web use (which is a whole thing: ask a type designer) will not look good in every browser and OS. That’s because every browser treats hinting differently, as does every OS, and every OS version. 

Firefox does its own thing in both Windows and Mac OS, and Microsoft is all over the place because of its need to support multiple generations of Windows and Cleartype and all kinds of hardware simultaneously. Thus “real type” on a single web page can look markedly different, and sometimes very bad, on different computers at the same company. If that web page is your company’s, your opinion of “web fonts” may suffer, and rightfully. (The advantage of Apple’s closed model, which not everyone likes, is that it allows the company to guarantee the quality and consistency of user experience.)  

As near as my font designer friends and I can make out, Apple’s Webkit in Safari and iPhone ignores hinting and creates its own, which Apple thinks is better, and which many web designers think of as “what real type looks like.” The forked version of Webkit in Chrome, Android, and Palm Pre also creates its own hinting, which is close to iPhone’s—close enough that Apple, Palm, and Google could propose it as a standard for use in all browsers and platforms. Whether Firefox would embrace a theoretical Apple and Google standard is open to conjecture, and I somehow have difficulty imagining Microsoft buying in—even though they know the web is more and more mobile, and that means more and more of their customers are viewing web content in some version of Webkit.

The End of Simple

There are ways around this ugly type ugliness, but they involve complicated scripting and sniffing—the very nightmares from which web standards and the simplicity of @font-face were supposed to save us. I don’t know that even mighty Typekit has figured out every needed variation yet (although, working with foundries, they probably will). 

For type foundries, the complexity and expense of rethinking classic typefaces to survive in these hostile environments may further delay widespread adoption of web fonts and the resolution of licensing and formatting issues. The complexity may also force designers (even those who prefer to own) to rely on a hosted rental model simply to outsource and stay current with the detection and programming required.

Forgive my tears. I stand in a potter’s field of ideas like “Keep it simple,” by a grave whose headstone reads “Write once, publish everywhere.”


title: Type-Inspired Interfaces
year: 2009
author: Dan Mall
author_slug: danmall
published: 2009-12-07T00:00:00+00:00
url: https://24ways.org/2009/type-inspired-interfaces/
topic: design
contents:
One of the things that terrifies me most about a new project is the starting point. How is the content laid out? What colors do I pick? Once things like that are decided, it becomes significantly easier to continue design, but it’s the blank page where I spend the most time.

To that end, I often start by choosing type. I don’t need to worry about colors or layout or anything else… just the right typefaces that support the art direction. (This article won’t focus on how to choose a typeface, but there are some really great resources if you interested in that sort of thing.)

And just like that, all your work is done. “Hold it just a second,” you might say. “All I’ve done is pick type. I still have to do the rest!”

To which I would reply, “Silly rabbit. You already have!” You see, picking the right typeface gets you farther than you might think. Here are a few tips on taking cues from type to design interfaces and interface elements.

Perfecting Web 2.0

If you’re going for that beloved rounded corner look, you might class it up a bit by choosing the wonderful Omnes Pro by Joshua Darden. As the typeface already has a rounded aesthetic, making buttons that fit the style should be pretty easy.

I’ve found that using multiples helps to keep your interfaces looking balanced and proportional. Noticing that the top left edge of the letter “P” has about an 12px corner radius, let’s choose a 24px radius for our button (a multiple of 2), so that we get proper rounded corners. By taking mathematical measurements from the typeface, our button looks more thought out than just “place arbitrary text on arbitrarily-sized button.” Pretty easy, eh?



What’s in a name(plate)?

Rounded buttons are pretty popular buttons nowadays, so let’s try something a bit more stylized.

Have a gander at Brothers, a sturdy face from Emigre. The chiseled edges give us a perfect cue for a stylized button. Using the same slope, you can make plated-looking buttons that fit a different kind of style.



Headlining

You might even take some cues from the style of the typeface itself. Didone serifs are known for their lack of bracketsーthat is, a gradual transition from the stem to the serif. Instead, they typically connect at a right angle. Another common characteristic is the high contrast in the strokes: very thick stems, very thin serifs.

So, when using a high contrast typeface, you can use it to your advantage to enhance hierarchy. Following our “multiples” guideline, a 12px measurement from the stems helps us create a top rule with a height of 24px (a multiple of 2). We can take the exact 1px measurement from the serif—a multiple of 1—to create the bottom rule. Voilà! I use this technique a lot.



Swashbucklers

And don’t forget the importance of visual “speed bumps” to break up long passages of text. A beautiful face like Alejandro Paul’s Ministry Script has over a thousand characters that can be manipulated or even combined to create elegant interface elements. Altering the partial differential character (∂) creates a delightful ornament that can help to guide the eye through content.



Stagger & Swagger

What about layout? How can we use typography to inform how our content is displayed?

Let’s take a typeface like Assembler. We might use this for a design that needs to feel uneasy or uncomfortable. In design terms, that might translate into using irregular shapes and asymmetry. Using the proportional distances and degrees from the perpendiculars, we could easily create a multi-column layout that jives with the general tone. And for all you skeptics that don’t think a layout like this is doable on the web, stranger things have happened.

 Background texture generously offered by Bittbox.

Overall Design Direction

Finally, your typography could impact the entire look of the site, from the navigation to the interaction and everything in between. Check out how the (now-defunct) Nike Free site’s typography echoes the product itself, and in turn influences the navigation.



Find Your Type

With thousands of fonts to choose from, the possibilities are ridiculously open. From angles to radii to color to weight, you’ve got endless fodder before you. Great type designers spent countless hours slaving over these detailed letterforms; take advantage of it! Don’t feel like you have to limit yourself to the same old Helvetica and wet floors… unless your design calls for it. 

Happy hunting!


title: Front-End Code Reusability with CSS and JavaScript
year: 2009
author: Trevor Morris
author_slug: trevormorris
published: 2009-12-06T00:00:00+00:00
url: https://24ways.org/2009/front-end-code-reusability-with-css-and-javascript/
topic: code
contents:
Most web standards-based developers are more than familiar with creating their sites with semantic HTML with lots and lots of CSS. With each new page in a design, the CSS tends to grow and grow and more elements and styles are added. But CSS can be used to better effect.

The idea of object-oriented CSS isn’t new. Nicole Sullivan has written a presentation on the subject and outlines two main concepts: separate structure and visual design; and separate container and content. Jeff Croft talks about Applying OOP Concepts to CSS:


	I can make a class of .box that defines some basic layout structure, and another class of .rounded that provides rounded corners, and classes of .wide and .narrow that define some widths, and then easily create boxes of varying widths and styles by assigning multiple classes to an element, without having to duplicate code in my CSS.


This concept helps reduce CSS file size, allows for great flexibility, rapid building of similar content areas and means greater consistency throughout the entire design. You can also take this concept one step further and apply it to site behaviour with JavaScript.

Build a versatile slideshow

I will show you how to build multiple slideshows using jQuery, allowing varying levels of functionality which you may find on one site design. The code will be flexible enough to allow you to add previous/next links, image pagination and the ability to change the animation type. More importantly, it will allow you to apply any combination of these features.

Image galleries are simply a list of images, so the obvious choice of marking the content up is to use a <ul>. Many designs, however, do not cater to non-JavaScript versions of the website, and thus don’t take in to account large multiple images. You could also simply hide all the other images in the list, apart from the first image. This method can waste bandwidth because the other images might be downloaded when they are never going to be seen.

Taking this second concept — only showing one image — the only code you need to start your slideshow is an <img> tag. The other images can be loaded dynamically via either a per-page JavaScript array or via AJAX.

The slideshow concept is built upon the very versatile Cycle jQuery Plugin and is structured in to another reusable jQuery plugin. Below is the HTML and JavaScript snippet needed to run every different type of slideshow I have mentioned above.

<img src="path/to/image.jpg" alt="About the image" title="" height="250" width="400" class="slideshow">
<script type="text/javascript">
	jQuery().ready(function($) {
		$('img.slideshow').slideShow({
			images: ['1.jpg', '2.jpg', '3.jpg']
		});
	});
</script>

Slideshow plugin

If you’re not familiar with jQuery or how to write and author your own plugin there are plenty of articles to help you out.

jQuery has a chainable interface and this is something your plugin must implement. This is easy to achieve, so your plugin simply returns the collection it is using:

return this.each(
	function () {}
};

Local Variables

To keep the JavaScript clean and avoid any conflicts, you must set up any variables which are local to the plugin and should be used on each collection item. Defining all your variables at the top under one statement makes adding more and finding which variables are used easier. For other tips, conventions and improvements check out JSLint, the “JavaScript Code Quality Tool”.

var $$, $div, $images, $arrows, $pager,
	id, selector, path, o, options,
	height, width,
	list = [], li = 0,
	parts = [], pi = 0,
	arrows = ['Previous', 'Next'];

Cache jQuery Objects

It is good practice to cache any calls made to jQuery. This reduces wasted DOM calls, can improve the speed of your JavaScript code and makes code more reusable.

The following code snippet caches the current selected DOM element as a jQuery object using the variable name $$. Secondly, the plugin makes its settings available to the Metadata plugin‡ which is best practice within jQuery plugins.

For each slideshow the plugin generates a <div> with a class of slideshow and a unique id. This is used to wrap the slideshow images, pagination and controls.

The base path which is used for all the images in the slideshow is calculated based on the existing image which appears on the page. For example, if the path to the image on the page was /img/flowers/1.jpg the plugin would use the path /img/flowers/ to load the other images.

$$ = $(this);
o = $.metadata ? $.extend({}, settings, $$.metadata()) : settings;
id = 'slideshow-' + (i++ + 1);
$div = $('<div />').addClass('slideshow').attr('id', id);
selector = '#' + id + ' ';
path = $$.attr('src').replace(/[0-9]\.jpg/g, '');
options = {};
height = $$.height();
width = $$.width();

Note: the plugin uses conventions such as folder structure and numeric filenames. These conventions help with the reusable aspect of plugins and best practices.

Build the Images

The cycle plugin uses a list of images to create the slideshow. Because we chose to start with one image we must now build the list programmatically. This is a case of looping through the images which were added via the plugin options, building the appropriate HTML and appending the resulting <ul> to the DOM.

$.each(o.images, function () {
	list[li++] = '<li>';
	list[li++] = '<img src="' + path + this + '" height="' + height + '" width="' + width + '">';
	list[li++] = '</li>';
});
$images = $('<ul />').addClass('cycle-images');
$images.append(list.join('')).appendTo($div);

Although jQuery provides the append method it is much faster to create one really long string and append it to the DOM at the end.

Update the Options

Here are some of the options we’re making available by simply adding classes to the <img>. You can change the slideshow effect from the default fade to the sliding effect. By adding the class of stopped the slideshow will not auto-play and must be controlled via pagination or previous and next links.

// different effect
if ($$.is('.slide')) {
	options.fx = 'scrollHorz';
}
// don't move by default
if ($$.is('.stopped')) {
	options.timeout = 0;
}

If you are using the same set of images throughout a website you may wish to start on a different image on each page or section. This can be easily achieved by simply adding the appropriate starting class to the <img>.

// based on the class name on the image
if ($$.is('[class*=start-]')) {
	options.startingSlide = parseInt($$.attr('class').replace(/.*start-([0-9]+).*/g, "$1"), 10) - 1;
}

For example:

<img src="/img/slideshow/3.jpg" alt="About the image" title="" height="250" width="400" class="slideshow start-3">

By default, and without JavaScript, the third image in this slideshow is shown. When the JavaScript is applied to the page the slideshow must know to start from the correct place, this is why the start class is required.

You could capture the default image name and parse it to get the position, but only the default image needs to be numeric to work with this plugin (and could easily be changed in future). Therefore, this extra specifically defined option means the plugin is more tolerant.

Previous/Next Links

A common feature of slideshows is previous and next links enabling the user to manually progress the images. The Cycle plugin supports this functionality, but you must generate the markup yourself. Most people add these directly in the HTML but normally only support their behaviour when JavaScript is enabled. This goes against progressive enhancement. To keep with the best practice progress enhancement method the previous/next links should be generated with JavaScript.

The follow snippet checks whether the slideshow requires the previous/next links, via the arrows class. It restricts the Cycle plugin to the specific slideshow using the selector we created at the top of the plugin. This means multiple slideshows can run on one page without conflicting each other.

The code creates a <ul> using the arrows array we defined at the top of the plugin. It also adds a class to the slideshow container, meaning you can style different combinations of options in your CSS.

// create the arrows
if ($$.is('.arrows') && list.length > 1) {
	options.next = selector + '.next';
	options.prev = selector + '.previous';
	$arrows = $('<ul />').addClass('cycle-arrows');
	$.each(arrows, function (i, val) {
		parts[pi++] = '<li class="' + val.toLowerCase() + '">';
		parts[pi++] = '<a href="#' + val.toLowerCase() + '">';
		parts[pi++] = '<span>' + val + '</span>';
		parts[pi++] = '</a>';
		parts[pi++] = '</li>';
	});
	$arrows.append(parts.join('')).appendTo($div);
	$div.addClass('has-cycle-arrows');
}

The arrow array could be placed inside the plugin settings to allow for localisation.

Pagination

The Cycle plugin creates its own HTML for the pagination of the slideshow. All our plugin needs to do is create the list and selector to use. This snippet creates the pagination container and appends it to our specific slideshow container. It sets the Cycle plugin pager option, restricting it to the specific slideshow using the selector we created at the top of the plugin. Like the previous/next links, a class is added to the slideshow container allowing you to style the slideshow itself differently.

// create the clickable pagination
if ($$.is('.pagination') && list.length > 1) {
	options.pager = selector + '.cycle-pagination';
	$pager = $('<ul />').addClass('cycle-pagination');
	$pager.appendTo($div);
	$div.addClass('has-cycle-pagination');
}

Note: the Cycle plugin creates a <ul> with anchors listed directly inside without the surrounding <li>. Unfortunately this is invalid markup but the code still works.

Demos

Well, that describes all the ins-and-outs of the plugin, but demos make it easier to understand! Viewing the source on the demo page shows some of the combinations you can create with a simple <img>, a few classes and some thought-out JavaScript.

View the demos →

Decide on defaults

The slideshow plugin uses the exact same settings as the Cycle plugin, but some are explicitly set within the slideshow plugin when using the classes you have set.

When deciding on what functionality is going to be controlled via this class method, be careful to choose your defaults wisely. If all slideshows should auto-play, don’t make this an option — make the option to stop the auto-play. Similarly, if every slideshow should have previous/next functionality make this the default and expose the ability to remove them with a class such as “no-pagination”.

In the examples presented on this article I have used a class on each <img>. You can easily change this to anything you want and simply apply the plugin based on the jQuery selector required.

Grab your images

If you are using AJAX to load in your images, you can speed up development by deciding on and keeping to a folder structure and naming convention. There are two methods: basing the image path based on the current URL; or based on the src of the image. The first allows a different slideshow on each page, but in many instances a site will have a couple of sets of images and therefore the second method is probably preferred.

Metadata ‡

A method which allows you to directly modify settings in certain plugins, which also uses the classes from your HTML already exists. This is a jQuery plugin called Metadata. This method allows for finer control over the plugin settings themselves. Some people, however, may dislike the syntax and prefer using normal classes, like above which when sprinkled with a bit more JavaScript allows you to control what you need to control.

The takeaway

Hopefully you have understood not only what goes in to a basic jQuery plugin but also learnt a new and powerful idea which you can apply to other areas of your website.

The idea can also be applied to other common interfaces such as lightboxes or mapping services such as Google Maps — for example creating markers based on a list of places, each with different pin icons based the anchor class.


title: What makes a website successful? It might not be what you expect!
year: 2009
author: Paul Boag
author_slug: paulboag
published: 2009-12-04T00:00:00+00:00
url: https://24ways.org/2009/what-makes-a-website-successful/
topic: business
contents:
What makes some sites succeed and others fail? Put another way, when you are asked to redesign an existing website, what problems are you looking out for and where do you concentrate your efforts?

I would argue that as web designers we spend too much time looking at the wrong kind of problem.

I recently ran a free open door consultancy clinic to celebrate the launch of my new book (yes I know, two shameless plugs in one sentence). This involved various website owners volunteering their sites for review. Both myself and the audience then provided feedback.

What quickly became apparent is that the feedback being given by the audience was biased towards design and development.

Although their comments were excellent it focused almost exclusively on the quality of code, site aesthetics and usability. To address these issues in isolation is similar to treating symptoms and ignoring the underlying illness.

Cure the illness not the symptoms

Poor design, bad usability and terribly written code are symptoms of bigger problems. Often when we endeavour to address these symptoms, we meet resistance from our clients and become frustrated. This is because our clients are still struggling with fundamental concepts we take for granted.

Before we can address issues of aesthetics, usability and code, we need to tackle business objectives, calls to action and user tasks. Without dealing with these fundamental principles our clients’ website will fail.

Let me address each in turn:

Understand the business objectives

Do you ask your clients why they have a website? It feels like an obvious question. However, it is surprising how many clients do not have an answer.

Without having a clear idea of the siteʼs business objectives, the client has no way to know whether it is succeeding. This means they have no justification for further investment and that leads to quibbling over every penny.

However most importantly, without clearly defined business aims they have no standard against which to base their decisions. Everything becomes subjective and that will inevitably lead to problems.

Before we start discussing design, usability and development, we need to focus our clients on establishing concrete business objectives. This will provide a framework for decision making during the development phase.

This will not only help the client make decisions, it will also focus them on the business and away from micro managing the design.

Establish clear calls to action

Once business objectives have been set this opens up the possibility to establish clear calls to action.

I am amazed at how few website owners can name their calls to action. However, I am even more staggered at how few web designers ask about them.

Calls to action are not just limited to ecommerce sites. Whether you are asking people to sign up for a newsletter or complete a contact us form, every site should have a desired objective for users.

What is more, each page of a site should have micro calls to action that always draw users on and never leave them at a dead end.

Without clearly defined calls to action you cannot successfully design a site, structure the user experience or measure its success. They bring focus to the site and encourage the client to concentrate their efforts on helping people reach those goals.

Of course in order to know if a call to action is going to work, it is necessary to do some user testing.

Test against the right tasks

As web designers we all like to boast about being ʻuser centricʼ whatever that means! However, in reality I think many of us are paying lip service to the subject.

Sure, we ask our clients about who their users are and maybe even do some usability testing. However, usability testing is no good if we are not asking the right questions.

Again we find ourselves working on a superficial level rather than tackling the deeper issues.

Clients find it relatively easy to tell you who their target audience is. Admittedly the list they come back with is often overly long and contains a lot of edge cases. However, where they begin to struggle is articulating what these users will want to achieve on the website. They know who they want to reach. However, they cannot always tell you why those people would be interested in the site.

These user tasks are another fundamental building block for any successful website. Although it is important for a website owner to understand what their objectives are and what they want users to do, it is even more important that they understand the users objectives as well.

Again, this provides context for the decisions they are making about design, usability and functionality. Without it the site will become self serving, largely ignoring the needs of users.

User tasks help to focus the clientʼs mind on the needs of their user, rather than what they can get out of them.

So am I claiming that design, usability and code do not matter? Well the shocking truth is that to some extent I am!

The shocking truth

Whether we like it or not there is significant evidence that you can create a successful website with bad design, terrible code and without ever running a usability test session.

You only need to look at the design of Craigslist or the code of Amazon to see that this is true.

However, I do not believe it is possible to build a successful website without business objectives, calls to action and a clear idea of user tasks.

Do not misunderstand me. I do believe design, usability and code matters. I just believe that they only matter if the fundamentals are already in place. These things improve a solid foundation but are no use in their own right.

As web designers it is our responsibility to ensure fundamental questions are being asked, before we start exploring other issues. If we do not, our websites will look great, be well coded and have gone through endless usability tests, however it will not be truly successful.


title: HTML5: Tool of Satan, or Yule of Santa?
year: 2009
author: Bruce Lawson
author_slug: brucelawson
published: 2009-12-05T00:00:00+00:00
url: https://24ways.org/2009/html5-tool-of-satan-or-yule-of-santa/
topic: code
contents:
It would lead to unseasonal arguments to discuss the title of this piece here, and the arguments are as indigestible as the fourth turkey curry of the season, so we’ll restrict our article to the practical rather than the philosophical: what HTML5 can you reasonably expect to be able to use reliably cross-browser in the early months of 2010?

The answer is that you can use more than you might think, due to the seasonal tinsel of feature-detection and using the sparkly pixie-dust of IE-only VML (but used in a way that won’t damage your Elf).

Canvas

canvas is a 2D drawing API that defines a blank area of the screen of arbitrary size, and allows you to draw on it using JavaScript. The pictures can be animated, such as in this canvas mashup of Wolfenstein 3D and Flickr. (The difference between canvas and SVG is that SVG uses vector graphics, so is infinitely scalable. It also keeps a DOM, whereas canvas is just pixels so you have to do all your own book-keeping yourself in JavaScript if you want to know where aliens are on screen, or do collision detection.)

Previously, you needed to do this using Adobe Flash or Java applets, requiring plugins and potentially compromising keyboard accessibility. Canvas drawing is supported now in Opera, Safari, Chrome and Firefox. The reindeer in the corner is, of course, Internet Explorer, which currently has zero support for canvas (or SVG, come to that).

Now, don’t pull a face like all you’ve found in your Yuletide stocking is a mouldy satsuma and a couple of nuts—that’s not the end of the story. Canvas was originally an Apple proprietary technology, and Internet Explorer had a similar one called Vector Markup Language which was submitted to the W3C for standardisation in 1998 but which, unlike canvas, was not blessed with retrospective standardisation.

What you need, then, is some way for Internet Explorer to translate canvas to VML on-the-fly, while leaving the other, more standards-compliant browsers to use the HTML5. And such a way exists—it’s a JavaScript library called excanvas. It’s downloadable from http://code.google.com/p/explorercanvas/ and it’s simple to include it via a conditional comment in the head for IE:

<!--[if IE]>
<script src="excanvas.js"></script>
<![endif]-->

Simply include this, and your canvas will be natively supported in the modern browsers (and the library won’t even be downloaded) whereas IE will suddenly render your canvas using its own VML engine. Be sure, however, to check it carefully, as the IE JavaScript engine isn’t so fast and you’ll need to be sure that performance isn’t too degraded to use.

Forms

Since the beginning of the Web, developers have been coding forms, and then writing JavaScript to check whether an input is a correctly formed email address, URL, credit card number or conforms to some other pattern. The cumulative labour of the world’s developers over the last 15 years makes whizzing round in a sleigh and delivering presents seem like popping to the corner shop in comparison.

With HTML5, that’s all about to change. As Yaili began to explore on Day 3, a host of new attributes to the input element provide built-in validation for email address formats (input type=email), URLs (input type=url), any pattern that can be expressed with a JavaScript-syntax regex (pattern="[0-9][A-Z]{3}") and the like. New attributes such as required, autofocus, input type=number min=3 max=50 remove much of the tedious JavaScript from form validation.

Other, really exciting input types are available (see all input types). The datalist is reminiscent of a select box, but allows the user to enter their own text if they don’t want to choose one of the pre-defined options. input type=range is rendered as a slider, while input type=date pops up a date picker, all natively in the browser with no JavaScript required at all.

Currently, support is most complete in an experimental implementation in Opera and a number of the new attributes in Webkit-based browsers. But don’t let that stop you! The clever thing about the specification of the new Web Forms is that all the new input types are attributes (rather than elements). input defaults to input type=text, so if a browser doesn’t understand a new HTML5 type, it gracefully degrades to a plain text input.

So where does that leave validation in those browsers that don’t support Web Forms? The answer is that you don’t retire your pre-existing JavaScript validation just yet, but you leave it as a fallback after doing some feature detection. To detect whether (say) input type=email is supported, you make a new input type=email with JavaScript but don’t add it to the page. Then, you interrogate your new element to find out what its type attribute is. If it’s reported back as “email”, then the browser supports the new feature, so let it do its work and don’t bring in any JavaScript validation. If it’s reported back as “text”, it’s fallen back to the default, indicating that it’s not supported, so your code should branch to your old validation routines. Alternatively, use the small (7K) Modernizr library which will do this work for you and give you JavaScript booleans like Modernizr.inputtypes[email] set to true or false.

So what does this buy you? Well, first and foremost, you’re future-proofing your code for that time when all browsers support these hugely useful additions to forms. Secondly, you buy a usability and accessibility win. Although it’s tempting to style the stuffing out of your form fields (which can, incidentally, lead to madness), whatever your branding people say, it’s better to leave forms as close to the browser defaults as possible. A browser’s slider and date pickers will be the same across different sites, making it much more comprehensible to users. And, by using native controls rather than faking sliders and date pickers with JavaScript, your forms are much more likely to be accessible to users of assistive technology.

HTML5 DOCTYPE

You can use the new DOCTYPE !doctype html now and – hey presto – you’re writing HTML5, as it’s pretty much a superset of HTML4. There are some useful advantages to doing this. The first is that the HTML5 validator (I use http://html5.validator.nu) also validates ARIA information, whereas the HTML4 validator doesn’t, as ARIA is a new spec developed after HTML4. (Actually, it’s more accurate to say that it doesn’t validate your ARIA attributes, but it doesn’t automatically report them as an error.)

Another advantage is that HTML5 allows tabindex as a global attribute (that is, on any element). Although originally designed as an accessibility bolt-on, I ordinarily advise you don’t use it; a well-structured page should provide a logical tab order through links and form fields already.

However, tabindex="-1" is a legal value in HTML5 as it allows for the element to be programmatically focussable by JavaScript. It’s also very useful for correcting a bug in Internet Explorer when used with a keyboard; in-page links go nowhere if the destination doesn’t have a proprietary property called hasLayout set or a tabindex of -1.

So, whether it is the tool of Satan or yule of Santa, HTML5 is just around the corner. Some you can use now, and by the end of 2010 I predict you’ll be able to use a whole lot more as new browser versions are released.


title: Make Out Like a Bandit
year: 2009
author: Jina Anne
author_slug: jina
published: 2009-12-21T00:00:00+00:00
url: https://24ways.org/2009/make-out-like-a-bandit/
topic: business
contents:
If you are anything like me, you are a professional juggler. No, we don’t juggle bowling pins or anything like that (or do you? Hey, that’s pretty rad!). I’m talking about the work that we juggle daily. In my case, I’m a full-time designer, a half-time graduate student, a sometimes author and conference speaker, and an all-the-time social networker. Only two of these “positions” have actually put any money in my pocket (and, well, the second one takes a lot of money out). Still, this is all part of the work that I do. Your work situation is probably similar. We are workaholics.

So if we work so much in our daily lives, shouldn’t we be making out like bandits? Umm, honestly, I’m not hitting on you, silly. I’m talking about our success. We work and work and work. Shouldn’t we be filthy, stinking rich? Well… okay, that’s not quite what I mean either. I’m not necessarily talking about money (though that could potentially be a part of it). I’m talking about success — as in feeling a true sense of accomplishment and feeling happy about what we do and why we do it.

It’s important to feel accomplished and a general happiness in our work. To make out like a bandit (or have an incredible amount of success), you can either get lucky or work hard for it. And if you’re going to work hard for it, you might as well make it all meaningful and worthwhile. This is what I strive for in my own work and my life, and the following points I’m sharing with you are the steps I am taking to work toward this.


	I know the price of success: dedication, hard work & an unremitting devotion to the things you want to see happen. — Frank Lloyd Wright


Learn. Participate. Do.

The best way to get good at something is to keep doing whatever it is you’re doing that you want to be good at. For example, a sushi-enthusiast might take a sushi-making class because she wants to learn to make sushi for herself. It totally makes sense while the teacher demonstrates all the procedures, materials, and methods needed to make good, beautiful sushi. Later, the student goes home and tries to make sushi on her own, she gets totally confused and lost. Okay, I’m not even going to hide it, I’m talking about myself (this happened to me). As much as I love sushi, I couldn’t even begin to make good sushi because I’ve never really practiced.

Take advantage of learning opportunities where possible. Whether you’re learning CSS, Actionscript, or visual design, the best way to grasp how to do things is to participate, practice, do. Apply what you learn in your work. Participation is so vital to your success. If you have problems, let people know, and ask. But definitely practice on your own. And as cliché as it may sound, believe in yourself because if you don’t think you can do it, no one else will think you can either.

Maintain momentum

With whatever it is you’re doing, if you find yourself “on a roll”, you should take advantage of that momentum and keep moving. Sure, you’ll definitely want to take breaks here or there, but remember that momentum can be very difficult to obtain again once you’ve lost it. Get it done!

Deal with people

Whether you love or hate people, the fact is, you gotta deal with them — even the difficult ones. If you’re in a management position, then you know pretty well that most people don’t like being told what to do (even if that’s their job). Find ways to get people excited about what they’re doing. Make people feel that they (and what they do) are needed — people respond better if they’re valued, not commanded. Even if you’re not in a management position, this still applies to the way you work with your coworkers, clients, vendors, etc.

Resolve any conflicts right away. Conflicts will inevitably happen. Move on to how you can improve the situation, and do it as quickly as possible. Don’t spend too much time focusing on whose screw up it is — nobody feels good in this situation. Also, try to keep people informed on whatever it is you need or what it is you’re doing. If you’re waiting on something from someone, and it’s been a while, don’t be afraid to say something (tactfully). Sometimes people are forgetful — or just slacking. Hey, it happens!

Help yourself by helping others

What are some of the small, simple things you can do when you’re working that will help the people you work with (and in most cases, will end up helping yourself)? For example: if you’re a designer, perhaps taking a couple minutes now to organize and name your Photoshop layers will end up saving time later (since it will be easier to find things). This is going to help both you and your team. Or, developers: taking some time to write some documentation (even if it’s as simple as a comment in the code, or a well-written commit message) could potentially save valuable time for both you and your team later. Maybe you have to take a little time to sit down with a coworker and explain why something works the way it does. This helps them out tremendously — and will most likely lead to them respecting you a little more. This is a benefit.

If you make little things like this a habit, people will notice. People will enjoy working with you. People will trust you and rely on you. Sure, it might seem beneficial at any given moment to be “in it for yourself” (and therefore only helping yourself), but that won’t last very long. Helping others (whether it be a small or large feat) will cause a positive impact in the long run — and that is what will be more valuable to you and your career.

Do work that is meaningful

One of the best ways to feel successful about what you do is to feel good and happy about it. And a great way to feel good and happy about what you’re doing is to actually do good. This could be purpose-driven work that focuses on sustainability and environmentalism, or work that helps support causes and charity. Perhaps the work simply inspires people. Or maybe the work is just something you are very passionate about. Whatever the work may be, try working on projects that are meaningful to you. You’ll do well simply by being more motivated and interested. And it’s a double-win if the project is meaningful to others as well.

I feel very fortunate to work at a place like Crush + Lovely, where we have found quite frequently that the projects that inspire people, focus on global and social good, and create some sort of positive impact are the very projects that bring us more paid projects. But more importantly, we are happy and excited to do it. You might not work at a company that takes on those types of projects. But perhaps you have your own personal endeavors that create this excitement for you. Elliot Jay Stocks wrote about having pet projects. Do you take on side projects? What are those projects?

Over the last couple years, I’ve seen some really fantastic side projects come out that are great examples of meaningful work. These projects reflect the passions and goals of the respective designers and developers involved, and therefore become quite successful (because the people involved simply love what they are doing while they’re doing it). Some of these projects include:


	Typedia is a shared encyclopedia of typefaces which serves as a resource to classify, categorize, and connect typefaces. It was founded by Jason Santa Maria, a graphic designer with a love and passion for typography. He created it as a solution to a problem he faced as a designer: finding the right typeface.
	Huffduffer was created by Jeremy Keith, a web developer who wanted to create a podcast of inspirational talks — but after he found that this could be tedious, he decided to create a tool to automate this.
	Level & Tap was created by passionate photographer and web developer, Tom Watson. It began as a photography print store for Tom’s best personal photography. Over time, more photographers were added to the site and the site has grown to become quite a great collection of beautiful photography.
	Heat Eat Review is a review blog created by information architect and user experience designer, Abi Jones. As a foodie, she is able to use this passion for this blog, as it focuses on reviewing TV Dinners, Frozen Meals, and Microwavable Foods.
	Art in My Coffee, a favorite personal project of my own, is a photo blog of coffee art I created, after I found that my friends and I were frequently posting coffee art photos to Flickr, Twitter, and other websites. After the blog became more popular, I teamed up with Meagan Fisher on the project, who has just as much a passion for coffee art, if not more.


So, what’s important to you?

This is the very, very important question here. What really matters to you most? Beyond just working on meaningful projects you are passionate about, is the work you’re doing the right work for you, so that you can live a good lifestyle? Scott Boms wrote an excellent article, Burnout, in which he shares his own experience in battling stress and exhaustion, and what he learned from it. You should definitely read the article in its entirety, but a couple of his points that are particularly excellent are:


	Make time for numero uno, in which you make time for the things in life that make you happy
	Examine your values, goals, and measures of success, in which you work toward the things you are passionate about, your own personal development, and focusing on the things that matter.


A solid work-life balance can be a challenging struggle to obtain. Of course, you can cheat this by finding ways to combine the things you love with the things you do (so then it doesn’t even feel like you’re working — oh, you sneaky little bandit!). However, there are other factors to consider beyond your general love for the work you’re doing. Take proper care of yourself physically, mentally, and socially.

So, are you making out like a bandit?

Do you feel accomplished and generally happy with your work? If not, perhaps that is something to focus on for the next year. Consider your work (both in your job as well as any side projects you may take on) and how it benefits you — present and future. Take any steps necessary to get you to where you need to be. If you are miserable, fix it!

Finally, it’s important to be thankful for the things that matter to you and make you happy. Pass it along everyday. Thank people. It’s a simple thing, really. Saying “thank you” can and will have enormous impact on the people around you. Oh. And, I apologize if the title of this article led you to thinking it would teach you how to be an amazing kisser. That’s a different article entirely for 24 ways to impress your friends!


title: Have a Field Day with HTML5 Forms
year: 2009
author: Inayaili de León Persson
author_slug: inayailideleon
published: 2009-12-03T00:00:00+00:00
url: https://24ways.org/2009/have-a-field-day-with-html5-forms/
topic: code
contents:
Forms are usually seen as that obnoxious thing we have to markup and style. I respectfully disagree: forms (on a par with tables) are the most exciting thing we have to work with.

Here we’re going to take a look at how to style a beautiful HTML5 form using some advanced CSS and latest CSS3 techniques. I promise you will want to style your own forms after you’ve read this article.

Here’s what we’ll be creating:

 The form. (Icons from Chalkwork Payments)

Meaningful markup

We’re going to style a simple payment form. There are three main sections on this form:


	The person’s details
	The address details
	The credit card details


We are also going to use some of HTML5’s new input types and attributes to create more meaningful fields and use less unnecessary classes and ids:


	email, for the email field
	tel, for the telephone field
	number, for the credit card number and security code
	required, for required fields
	placeholder, for the hints within some of the fields
	autofocus, to put focus on the first input field when the page loads


There are a million more new input types and form attributes on HTML5, and you should definitely take a look at what’s new on the W3C website. Hopefully this will give you a good idea of how much more fun form markup can be.

A good foundation

Each section of the form will be contained within its own fieldset. In the case of the radio buttons for choosing the card type, we will enclose those options in another nested fieldset.

We will also be using an ordered list to group each label / input pair. This will provide us with a (kind of) semantic styling hook and it will also make the form easier to read when viewing with no CSS applied:

 The unstyled form

So here’s the markup we are going to be working with:

<form id=payment>
	<fieldset>
		<legend>Your details</legend>
		<ol>
			<li>
				<label for=name>Name</label>
				<input id=name name=name type=text placeholder="First and last name" required autofocus>
			</li>
			<li>
				<label for=email>Email</label>
				<input id=email name=email type=email placeholder="example@domain.com" required>
			</li>
			<li>
				<label for=phone>Phone</label>
				<input id=phone name=phone type=tel placeholder="Eg. +447500000000" required>
			</li>
		</ol>
	</fieldset>
	<fieldset>
		<legend>Delivery address</legend>
		<ol>
			<li>
				<label for=address>Address</label>
				<textarea id=address name=address rows=5 required></textarea>
			</li>
			<li>
				<label for=postcode>Post code</label>
				<input id=postcode name=postcode type=text required>
			</li>
			<li>
				<label for=country>Country</label>
				<input id=country name=country type=text required>
			</li>
		</ol>
	</fieldset>
	<fieldset>
		<legend>Card details</legend>
		<ol>		
			<li>
				<fieldset>
					<legend>Card type</legend>
					<ol>
						<li>
							<input id=visa name=cardtype type=radio>
							<label for=visa>VISA</label>
						</li>
						<li>
							<input id=amex name=cardtype type=radio>
							<label for=amex>AmEx</label>
						</li>
						<li>
							<input id=mastercard name=cardtype type=radio>
							<label for=mastercard>Mastercard</label>
						</li>
					</ol>
				</fieldset>
			</li>
			<li>
				<label for=cardnumber>Card number</label>
				<input id=cardnumber name=cardnumber type=number required>
			</li>
			<li>
				<label for=secure>Security code</label>
				<input id=secure name=secure type=number required>
			</li>
			<li>
				<label for=namecard>Name on card</label>
				<input id=namecard name=namecard type=text placeholder="Exact name as on the card" required>
			</li>
		</ol>
	</fieldset>
	<fieldset>
		<button type=submit>Buy it!</button>
	</fieldset>
</form>

Making things look nice

First things first, so let’s start by adding some defaults to our form by resetting the margins and paddings of the elements and adding a default font to the page:

html, body, h1, form, fieldset, legend, ol, li {
	margin: 0;
	padding: 0;
}
body {
	background: #ffffff;
	color: #111111;
	font-family: Georgia, "Times New Roman", Times, serif;
	padding: 20px;
}

Next we are going to style the form element that is wrapping our fields:

form#payment {
	background: #9cbc2c;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	border-radius: 5px;
	padding: 20px;
	width: 400px;
}

We will also remove the border from the fieldset and apply some bottom margin to it. Using the :last-of-type pseudo-class, we remove the bottom margin of the last fieldset — there is no need for it:

form#payment fieldset {
	border: none;
	margin-bottom: 10px;
}
form#payment fieldset:last-of-type {
	margin-bottom: 0;
}

Next we’ll make the legends big and bold, and we will also apply a light-green text-shadow, to add that little extra special detail:

form#payment legend {
	color: #384313;
	font-size: 16px;
	font-weight: bold;
	padding-bottom: 10px;
	text-shadow: 0 1px 1px #c0d576;
}

Our legends are looking great, but how about adding a clear indication of how many steps our form has? Instead of adding that manually to every legend, we can use automatically generated counters.

To add a counter to an element, we have to use either the :before or :after pseudo-elements to add content via CSS. We will follow these steps:


	create a counter using the counter-reset property on the form element
	call the counter with the content property (using the same name we’ve created before)
	with the counter-incremet property, indicate that for each element that matches our selector, that counter will be increased by 1


form#payment > fieldset > legend:before {
	content: "Step " counter(fieldsets) ": ";
	counter-increment: fieldsets;
}

Finally, we need to change the style of the legend that is part of the radio buttons group, to make it look like a label:

form#payment fieldset fieldset legend {
	color: #111111;
	font-size: 13px;
	font-weight: normal;
	padding-bottom: 0;
}

Styling the lists

For our list elements, we’ll just add some nice rounded corners and semi-transparent border and background. Because we are using RGBa colors, we should provide a fallback for browsers that don’t support them (that comes before the RBGa color). For the nested lists, we will remove these properties because they would be overlapping:

form#payment ol li {
	background: #b9cf6a;
	background: rgba(255,255,255,.3);
	border-color: #e3ebc3;
	border-color: rgba(255,255,255,.6);
	border-style: solid;
	border-width: 2px;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	border-radius: 5px;
	line-height: 30px;
	list-style: none;
	padding: 5px 10px;
	margin-bottom: 2px;
}
form#payment ol ol li {
	background: none;
	border: none;
	float: left;
}

Form controls

Now we only need to style our labels, inputs and the button element.

All our labels will look the same, with the exception of the one for the radio elements. We will float them to the left and give them a width.

For the credit card type labels, we will add an icon as the background, and override some of the properties that aren’t necessary. We will be using the attribute selector to specify the background image for each label — in this case, we use the for attribute of each label.

To add an extra user-friendly detail, we’ll add a cursor: pointer to the radio button labels on the :hover state, so the user knows that he can simply click them to select that option.

form#payment label {
	float: left;
	font-size: 13px;
	width: 110px;
}
form#payment fieldset fieldset label {
	background:none no-repeat left 50%;
	line-height: 20px;
	padding: 0 0 0 30px;
	width: auto;
}
form#payment label[for=visa] {
	background-image: url(visa.gif);
}
form#payment label[for=amex] {
	background-image: url(amex.gif);
}
form#payment label[for=mastercard] {
	background-image: url(mastercard.gif);
}
form#payment fieldset fieldset label:hover {
	cursor: pointer;
}

Almost there! Now onto the input elements. Here we want to match all inputs, except for the radio ones, and the textarea. For that we will use the negation pseudo-class (:not()). With it we can target all input elements except for the ones with type of radio.

We will also make sure to add some :focus styles and add the appropriate styling for the radio inputs:

form#payment input:not([type=radio]),
form#payment textarea {
	background: #ffffff;
	border: none;
	-moz-border-radius: 3px;
	-webkit-border-radius: 3px;
	-khtml-border-radius: 3px;
	border-radius: 3px;
	font: italic 13px Georgia, "Times New Roman", Times, serif;
	outline: none;
	padding: 5px;
	width: 200px;
}
form#payment input:not([type=submit]):focus,
form#payment textarea:focus {
	background: #eaeaea;
}
form#payment input[type=radio] {
	float: left;
	margin-right: 5px;
}

And finally we come to our submit button. To it, we will just add some nice typography and text-shadow, align it to the center of the form and give it some background colors for its different states:

form#payment button {
	background: #384313;
	border: none;
	-moz-border-radius: 20px;
	-webkit-border-radius: 20px;
	-khtml-border-radius: 20px;
	border-radius: 20px;
	color: #ffffff;
	display: block;
	font: 18px Georgia, "Times New Roman", Times, serif;
	letter-spacing: 1px;
	margin: auto;
	padding: 7px 25px;
	text-shadow: 0 1px 1px #000000;
	text-transform: uppercase;
}
form#payment button:hover {
	background: #1e2506;
	cursor: pointer;
}

And that’s it! See the completed form.

This form will not look the same on every browser. Internet Explorer and Opera don’t support border-radius (at least not for now); the new input types are rendered as just normal inputs on some browsers; and some of the most advanced CSS, like the counter, :last-of-type or text-shadow are not supported on some browsers. But that doesn’t mean you can’t use them right now, and simplify your development process. My gift to you!


title: Going Nuts with CSS Transitions
year: 2009
author: Natalie Downe
author_slug: nataliedowne
published: 2009-12-14T00:00:00+00:00
url: https://24ways.org/2009/going-nuts-with-css-transitions/
topic: code
contents:
I’m going to show you how CSS 3 transforms and WebKit transitions can add zing to the way you present images on your site.

Laying the foundations

First we are going to make our images look like mini polaroids with captions. Here’s the markup:

<div class="polaroid pull-right">
	<img src="../img/seal.jpg" alt="">
	<p class="caption">Found this little cutie on a walk in New Zealand!</p>
</div>

You’ll notice we’re using a somewhat presentational class of pull-right here. This means the logic is kept separate from the code that applies the polaroid effect. The polaroid class has no positioning, which allows it to be used generically anywhere that the effect is required. The pull classes set a float and add appropriate margins—they can be used for things like blockquotes as well.

.polaroid {
	width: 150px;
	padding: 10px 10px 20px 10px;
	border: 1px solid #BFBFBF;
	background-color: white;
	-webkit-box-shadow: 2px 2px 3px rgba(135, 139, 144, 0.4);
	-moz-box-shadow: 2px 2px 3px rgba(135, 139, 144, 0.4);
	box-shadow: 2px 2px 3px rgba(135, 139, 144, 0.4);
}

The actual polaroid effect itself is simply applied using padding, a border and a background colour. We also apply a nice subtle box shadow, using a property that is supported by modern WebKit browsers and Firefox 3.5+. We include the box-shadow property last to ensure that future browsers that support the eventual CSS3 specified version natively will use that implementation over the legacy browser specific version.

The box-shadow property takes four values: three lengths and a colour. The first is the horizontal offset of the shadow—positive values place the shadow on the right, while negative values place it to the left. The second is the vertical offset, positive meaning below. If both of these are set to 0, the shadow is positioned equally on all four sides. The last length value sets the blur radius—the larger the number, the blurrier the shadow (therefore the darker you need to make the colour to have an effect).

The colour value can be given in any format recognised by CSS. Here, we’re using rgba as explained by Drew behind the first door of this year’s calendar.

Rotation

For browsers that understand it (currently our old favourites WebKit and FF3.5+) we can add some visual flair by rotating the image, using the transform CSS 3 property.

-webkit-transform: rotate(9deg);
-moz-transform: rotate(9deg);
transform: rotate(9deg);

Rotations can be specified in degrees, radians (rads) or grads. WebKit also supports turns unfortunately Firefox doesn’t just yet.

For our example, we want any polaroid images on the left hand side to be rotated in the opposite direction, using a negative degree value:

.pull-left.polaroid {
	-webkit-transform: rotate(-9deg);
	-moz-transform: rotate(-9deg);
	transform: rotate(-9deg);
}

Multiple class selectors don’t work in IE6 but as luck would have it, the transform property doesn’t work in any current IE version either. The above code is a good example of progressive enrichment: browsers that don’t support box-shadow or transform will still see the image and basic polaroid effect.



Animation

WebKit is unique amongst browser rendering engines in that it allows animation to be specified in pure CSS. Although this may never actually make it in to the CSS 3 specification, it degrades nicely and more importantly is an awful lot of fun!

Let’s go nuts.

In the next demo, the image is contained within a link and mousing over that link causes the polaroid to animate from being angled to being straight.

Here’s our new markup:

<a href="http://www.flickr.com/photos/nataliedowne/2340993237/" class="polaroid">
	<img src="../img/raft.jpg" alt="">
	White water rafting in Queenstown
</a>

And here are the relevant lines of CSS:

a.polaroid {
	/* ... */
   -webkit-transform: rotate(10deg);
   -webkit-transition: -webkit-transform 0.5s ease-in;
}
a.polaroid:hover,
a.polaroid:focus,
a.polaroid:active {
	/* ... */
	-webkit-transform: rotate(0deg);
}

The @-webkit-transition@ property is the magic wand that sets up the animation. It takes three values: the property to be animated, the duration of the animation and a ‘timing function’ (which affects the animation’s acceleration, for a smoother effect).

-webkit-transition only takes affect when the specified property changes. In pure CSS, this is done using dynamic pseudo-classes. You can also change the properties using JavaScript, but that’s a story for another time.

Throwing polaroids at a table

Imagine there are lots of differently sized polaroid photos scattered on a table. That’s the effect we are aiming for with our next demo.



As an aside: we are using absolute positioning to arrange the images inside a flexible width container (with a minimum and maximum width specified in pixels). As some are positioned from the left and some from the right when you resize the browser they shuffle underneath each other. This is an effect used on the UX London site.

This demo uses a darker colour shadow with more transparency than before. The grey shadow in the previous example worked fine, but it was against a solid background. Since the images are now overlapping each other, the more opaque shadow looked fake.

-webkit-box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3);
-moz-box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3);
box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3);

On hover, as well as our previous trick of animating the image rotation back to straight, we are also making the shadow darker and setting the z-index to be higher than the other images so that it appears on top.

And Finally…

Finally, for a bit more fun, we’re going to simulate the images coming towards you and lifting off the page. We’ll achieve this by making them grow larger and by offsetting the shadow & making it longer.




Screenshot 1 shows the default state, while 2 shows our previous hover effect. Screenshot 3 is the effect we are aiming for, illustrated by demo 4.

a.polaroid {
	/* ... */
	z-index: 2;
	-webkit-box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3);
	-moz-box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3);
	box-shadow: 2px 2px 4px rgba(0,0, 0, 0.3);
	-webkit-transform: rotate(10deg);
	-moz-transform: rotate(10deg);
	transform: rotate(10deg);
	-webkit-transition: all 0.5s ease-in;
}
a.polaroid:hover,
a.polaroid:focus,
a.polaroid:active {
	z-index: 999;
	border-color: #6A6A6A;
	-webkit-box-shadow: 15px 15px 20px rgba(0,0, 0, 0.4);
	-moz-box-shadow: 15px 15px 20px rgba(0,0, 0, 0.4);
	box-shadow: 15px 15px 20px rgba(0,0, 0, 0.4);
	-webkit-transform: rotate(0deg) scale(1.05);
	-moz-transform: rotate(0deg) scale(1.05);
	transform: rotate(0deg) scale(1.05);
}

You’ll notice we are now giving the transform property another transform function: scale, which takes increases the size by the specified factor. Other things you can do with transform include skewing, translating or you can go mad creating your own transforms with a matrix.

The box-shadow has both its offset and blur radius increased dramatically, and is darkened using the alpha channel of the rgba colour.

And because we want the effects to all animate smoothly, we pass a value of all to the -webkit-transition property, ensuring that any changed property on that link will be animated.

Demo 5 is the finished example, bringing everything nicely together.

CSS transitions and transforms are a great example of progressive enrichment, which means improving the experience for a portion of the audience without negatively affecting other users. They are also a lot of fun to play with!

Further reading


	-moz-transform – the mozilla developer center has a comprehensive explanation of transform that also applies to -webkit-transform and transform.
	CSS: Animation Using CSS Transforms – this is a good, more indepth tutorial on animations.
	CSS Animation – the Safari blog explains the usage of -webkit-transform.
	Dinky pocketbooks with transform – another use for transforms, create your own printable pocketbook.
	A while back, Simon wrote a little bookmarklet to spin the entire page… warning: this will spin the entire page.


title: Working With RGBA Colour
year: 2009
author: Drew McLellan
author_slug: drewmclellan
published: 2009-12-01T00:00:00+00:00
url: https://24ways.org/2009/working-with-rgba-colour/
topic: code
contents:
When Tim and I were discussing the redesign of this site last year, one of the clear goals was to have a graphical style without making the pages heavy with a lot of images. When we launched, a lot of people were surprised that the design wasn’t built with PNGs. Instead we’d used RGBA colour values, which is part of the CSS3 specification.

What is RGBA Colour?

We’re all familiar with specifying colours in CSS using by defining the mix of red, green and blue light required to achieve our tone. This is fine and dandy, but whatever values we specify have one thing in common — the colours are all solid, flat, and well, a bit boring.

 Flat RGB colours

CSS3 introduces a couple of new ways to specify colours, and one of those is RGBA. The A stands for Alpha, which refers to the level of opacity of the colour, or to put it another way, the amount of transparency. This means that we can set not only the red, green and blue values, but also control how much of what’s behind the colour shows through. Like with layers in Photoshop.

Don’t We Have Opacity Already?

The ability to set the opacity on a colour differs subtly from setting the opacity on an element using the CSS opacity property. Let’s look at an example.

Here we have an H1 with foreground and background colours set against a page with a patterned background.

 Heading with no transparency applied

h1 {
	color: rgb(0, 0, 0);
	background-color: rgb(255, 255, 255);
}

By setting the CSS opacity property, we can adjust the transparency of the entire element and its contents:

 Heading with 50% opacity on the element

h1 {
	color: rgb(0, 0, 0);
	background-color: rgb(255, 255, 255);
	opacity: 0.5;
}

RGBA colour gives us something different – the ability to control the opacity of the individual colours rather than the entire element. So we can set the opacity on just the background:

 50% opacity on just the background colour

h1 {
	color: rgb(0, 0, 0);
	background-color: rgba(255, 255, 255, 0.5);
}

Or leave the background solid and change the opacity on just the text:

 50% opacity on just the foreground colour

h1 {
	color: rgba(0, 0, 0, 0.5);
	background-color: rgb(255, 255, 255);
}

The How-To

You’ll notice that above I’ve been using the rgb() syntax for specifying colours. This is a bit less common than the usual hex codes (like #FFF) but it makes sense when starting to use RGBA. As there’s no way to specify opacity with hex codes, we use rgba() like so:

color: rgba(255, 255, 255, 0.5);

Just like rgb() the first three values are red, green and blue. You can specify these 0-255 or 0%-100%. The fourth value is the opacity level from 0 (completely transparent) to 1 (completely opaque).

You can use this anywhere you’d normally set a colour in CSS — so it’s good for foregrounds and background, borders, outlines and so on. All the transparency effects on this site’s current design are achieved this way.

Supporting All Browsers

Like a lot of the features we’ll be looking at in this year’s 24 ways, RGBA colour is supported by a lot of the newest browsers, but not the rest. Firefox, Safari, Chrome and Opera browsers all support RGBA, but Internet Explorer does not.

Fortunately, due to the robust design of CSS as a language, we can specify RGBA colours for browsers that support it and an alternative for browsers that do not.

Falling back to solid colour

The simplest technique is to allow the browser to fall back to using a solid colour when opacity isn’t available. The CSS parsing rules specify that any unrecognised value should be ignored. We can make use of this because a browser without RGBA support will treat a colour value specified with rgba() as unrecognised and discard it.

So if we specify the colour first using rgb() for all browsers, we can then overwrite it with an rgba() colour for browsers that understand RGBA.

h1 {
	color: rgb(127, 127, 127);
	color: rgba(0, 0, 0, 0.5);
}

Falling back to a PNG

In cases where you’re using transparency on a background-color (although not on borders or text) it’s possible to fall back to using a PNG with alpha channel to get the same effect. This is less flexible than using CSS as you’ll need to create a new PNG for each level of transparency required, but it can be a useful solution.

Using the same principal as before, we can specify the background in a style that all browsers will understand, and then overwrite it in a way that browsers without RGBA support will ignore.

h1 {
	background: transparent url(black50.png);
	background: rgba(0, 0, 0, 0.5) none;
}

It’s important to note that this works because we’re using the background shorthand property, enabling us to set both the background colour and background image in a single declaration. It’s this that enables us to rely on the browser ignoring the second declaration when it encounters the unknown rgba() value.

Next Steps

The really great thing about RGBA colour is that it gives us the ability to create far more graphically rich designs without the need to use images. Not only does that make for faster and lighter pages, but sites which are easier and quicker to build and maintain. CSS values can also be changed in response to user interaction or even manipulated with JavaScript in a way that’s just not so easy using images.

 Opacity can be changed on :hover or manipulated with JavaScript

div {
	color: rgba(255, 255, 255, 0.8);
	background-color: rgba(142, 213, 87, 0.3);
}
div:hover {
	color: rgba(255, 255, 255, 1);
	background-color: rgba(142, 213, 87, 0.6);
}

Clever use of transparency in border colours can help ease the transition between overlay items and the page behind.

 Borders can receive the RGBA treatment, too

div {
	color: rgb(0, 0, 0);
	background-color: rgb(255, 255, 255);
	border: 10px solid rgba(255, 255, 255, 0.3);
}

In Conclusion


That’s a brief insight into RGBA colour, what it’s good for and how it can be used whilst providing support for older browsers. With the current lack of support in Internet Explorer, it’s probably not a technique that commercial designs will want to heavily rely on right away – simply because of the overhead of needing to think about fallback all the time. 

It is, however, a useful tool to have for those smaller, less critical touches that can really help to finesse a design. As browser support becomes more mainstream, you’ll already be familiar and practised with RGBA and ready to go.


title: Breaking Out The Edges of The Browser
year: 2009
author: Remy Sharp
author_slug: remysharp
published: 2009-12-02T00:00:00+00:00
url: https://24ways.org/2009/breaking-out-the-edges-of-the-browser/
topic: code
contents:
HTML5 contains more than just the new entities for a more meaningful document, it also contains an arsenal of JavaScript APIs.  So many in fact, that some APIs have outgrown the HTML5 spec’s backyard and have been sent away to grow up all on their own and been given the prestigious honour of being specs in their own right.

So when I refer to (bendy finger quote) “HTML5”, I mean the HTML5 specification and a handful of other specifications that help us authors build web applications.

Examples of those specs I would include in the umbrella term would be: geolocation, web storage, web databases, web sockets and web workers, to name a few.

For all you guys and gals, on this special 2009 series of 24 ways, I’m just going to focus on data storage and offline applications: boldly taking your browser where no browser has gone before!

Web Storage

The Web Storage API is basically cookies on steroids, a unhealthy dosage of steroids.  Cookies are always a pain to work with.  First of all you have the problem of setting, changing and deleting them.  Typically solved by Googling and blindly relying on PPK’s solution.  If that wasn’t enough, there’s the 4Kb limit that some of you have hit when you really don’t want to.

The Web Storage API gets around all of the hoops you have to jump through with cookies.  Storage supports around 5Mb of data per domain (the spec’s recommendation, but it’s open to the browsers to implement anything they like) and splits in to two types of storage objects:


	sessionStorage – available to all pages on that domain while the window remains open
	localStorage – available on the domain until manually removed


Support

Ignoring beta browsers for our support list, below is a list of the major browsers and their support for the Web Storage API:


	Latest: Internet Explorer, Firefox, Safari (desktop & mobile/iPhone)
	Partial: Google Chrome (only supports localStorage)
	Not supported: Opera (as of 10.10)


Usage

Both sessionStorage and localStorage support the same interface for accessing their contents, so for these examples I’ll use localStorage.

The storage interface includes the following methods:


	setItem(key, value)
	getItem(key)
	key(index)
	removeItem(key)
	clear()


In the simple example below, we’ll use setItem and getItem to store and retrieve data:

localStorage.setItem('name', 'Remy');
alert( localStorage.getItem('name') );

Using alert boxes can be a pretty lame way of debugging.  Conveniently Safari (and Chrome) include database tab in their debugging tools (cmd+alt+i), so you can get a visual handle on the state of your data:

 Viewing localStorage

As far as I know only Safari has this view on stored data natively in the browser.  There may be a Firefox plugin (but I’ve not found it yet!) and IE… well that’s just IE.

Even though we’ve used setItem and getItem, there’s also a few other ways you can set and access the data.

In the example below, we’re accessing the stored value directly using an expando and equally, you can also set values this way:

localStorage.name = "Remy";
alert( localStorage.name ); // shows "Remy"

The Web Storage API also has a key method, which is zero based, and returns the key in which data has been stored. This should also be in the same order that you set the keys, for example:

alert( localStorage.getItem(localStorage.key(0)) ); 
// shows "Remy"

I mention the key() method because it’s not an unlikely name for a stored value.  This can cause serious problems though.

When selecting the names for your keys, you need to be sure you don’t take one of the method names that are already on the storage object, like key, clear, etc. As there are no warnings when you try to overwrite the methods, it means when you come to access the key() method, the call breaks as key is a string value and not a function.

You can try this yourself by creating a new stored value using localStorage.key = "foo" and you’ll see that the Safari debugger breaks because it relies on the key() method to enumerate each of the stored values.

Usage Notes

Currently all browsers only support storing strings. This also means if you store a numeric, it will get converted to a string:

localStorage.setItem('count', 31);
alert(typeof localStorage.getItem('count')); 
// shows "string"

This also means you can’t store more complicated objects natively with the storage objects.  To get around this, you can use Douglas Crockford’s JSON parser (though Firefox 3.5 has JSON parsing support baked in to the browser – yay!) json2.js to convert the object to a stringified JSON object:

var person = {
	name: 'Remy',
	height: 'short',
	location: 'Brighton, UK'
};
localStorage.setItem('person', JSON.stringify(person));
alert( JSON.parse(localStorage.getItem('person')).name ); 
// shows "Remy"

Alternatives

There are a few solutions out there that provide storage solutions that detect the Web Storage API, and if it’s not available, fall back to different technologies (for instance, using a flash object to store data).  One comprehensive version of this is Dojo’s storage library.  I’m personally more of a fan of libraries that plug missing functionality under the same namespace, just as Crockford’s JSON parser does (above).

For those interested it what that might look like, I’ve mocked together a simple implementation of sessionStorage.  Note that it’s incomplete (because it’s missing the key method), and it could be refactored to not using the JSON stringify (but you would need to ensure that the values were properly and safely encoded):

// requires json2.js for all browsers other than Firefox 3.5
if (!window.sessionStorage && JSON) {
	window.sessionStorage = (function () {
		// window.top.name ensures top level, and supports around 2Mb
		var data = window.top.name ? JSON.parse(window.top.name) : {};
		return {    
			setItem: function (key, value) {
				data[key] = value+""; // force to string
				window.top.name = JSON.stringify(data);
			},
			removeItem: function (key) {
				delete data[key];
				window.top.name = JSON.stringify(data);        
			},
			getItem: function (key) {
				return data[key] || null;
			},
			clear: function () {
				data = {};
				window.top.name = '';
			}
		};
	})();
}

Now that we’ve cracked the cookie jar with our oversized Web Storage API, let’s have a look at how we take our applications offline entirely.

Offline Applications

Offline applications is (still) part of the HTML5 specification.  It allows developers to build a web app and have it still function without an internet connection.  The app is access via the same URL as it would be if the user were online, but the contents (or what the developer specifies) is served up to the browser from a local cache. From there it’s just an everyday stroll through open web technologies, i.e. you still have access to the Web Storage API and anything else you can do without a web connection.

For this section, I’ll refer you to a prototype demo I wrote recently of a contrived Rubik’s cube (contrived because it doesn’t work and it only works in Safari because I’m using 3D transforms).

 Offline Rubik’s cube

Support

Support for offline applications is still fairly limited, but the possibilities of offline applications is pretty exciting, particularly as we’re seeing mobile support and support in applications such as Fluid (and I would expect other render engine wrapping apps).

Support currently, is as follows:


	Latest: Safari (desktop & mobile/iPhone)
	Sort of: Firefox‡
	Not supported: Internet Explorer, Opera, Google Chrome


‡ Firefox 3.5 was released to include offline support, but in fact has bugs where it doesn’t work properly (certainly on the Mac), Minefield (Firefox beta) has resolved the bug.

Usage

The status of the application’s cache can be tested from the window.applicationCache object.  However, we’ll first look at how to enable your app for offline access.

You need to create a manifest file, which will tell the browser what to cache, and then we point our web page to that cache:

<!DOCTYPE html>
<html manifest="remy.manifest">
<!-- continues ... -->

For the manifest to be properly read by the browser, your server needs to serve the .manifest files as text/manifest by adding the following to your mime.types:

text/cache-manifest  manifest

Next we need to populate our manifest file so the browser can read it:

CACHE MANIFEST
/demo/rubiks/index.html
/demo/rubiks/style.css
/demo/rubiks/jquery.min.js
/demo/rubiks/rubiks.js
# version 15

The first line of the manifest must read CACHE MANIFEST.  Then subsequent lines tell the browser what to cache.

The HTML5 spec recommends that you include the calling web page (in my case index.html), but it’s not required.  If I didn’t include index.html, the browser would cache it as part of the offline resources.

These resources are implicitly under the CACHE namespace (which you can specify any number of times if you want to).

In addition, there are two further namespaces: NETWORK and FALLBACK.

NETWORK is a whitelist namespace that tells the browser not to cache this resource and always try to request it through the network.

FALLBACK tells the browser that whilst in offline mode, if the resource isn’t available, it should return the fallback resource.

Finally, in my example I’ve included a comment with a version number.  This is because once you include a manifest, the only way you can tell the browser to reload the resources is if the manifest contents changes. So I’ve included a version number in the manifest which I can change forcing the browser to reload all of the assets.

How it works

If you’re building an app that makes use of the offline cache, I would strongly recommend that you add the manifest last. The browser implementations are very new, so can sometimes get a bit tricky to debug since once the resources are cached, they really stick in the browser.

These are the steps that happen during a request for an app with a manifest:


	Browser: sends request for your app.html
	Server: serves all associated resources with app.html – as normal
	Browser: notices that app.html has a manifest, it re-request the assets in the manifest
	Server: serves the requested manifest assets (again)
	Browser: window.applicationCache has a status of UPDATEREADY
	Browser: reloads
	Browser: only request manifest file (which doesn’t show on the net requests panel)
	Server: responds with 304 Not Modified on the manifest file
	Browser: serves all the cached resources locally


What might also add confusion to this process, is that the way the browsers work (currently) is if there is a cache already in place, it will use this first over updated resources.  So if your manifest has changed, the browser will have already loaded the offline cache, so the user will only see the updated on the next reload.  

This may seem a bit convoluted, but you can also trigger some of this manually through the applicationCache methods which can ease some of this pain.

If you bind to the online event you can manually try to update the offline cache. If the cache has then updated, swap the updated resources in to the cache and the next time the app loads it will be up to date.  You could also prompt your user to reload the app (which is just a refresh) if there’s an update available.

For example (though this is just pseudo code):

addEvent(applicationCache, 'updateready', function () {
	applicationCache.swapCache();
	tellUserToRefresh();
});
addEvent(window, 'online', function () {
	applicationCache.update();
});

Breaking out of the Browser

So that’s two different technologies that you can use to break out of the traditional browser/web page model and get your apps working in a more application-ny way.

There’s loads more in the HTML5 and non-HTML5 APIs to play with, so take your Christmas break to check them out!


title: Designing For The Switch
year: 2009
author: Mark Boulton
author_slug: markboulton
published: 2009-12-16T00:00:00+00:00
url: https://24ways.org/2009/designing-for-the-switch/
topic: design
contents:
For a long time on the web, we’ve been typographically spoilt. Yes, you heard me correctly. Think about it: our computers come with web fonts already installed; fonts that have been designed specifically to work well online and at small size; and fonts that we can be sure other people have too. 

Yes, we’ve been spoilt. We don’t need to think about using Verdana, Arial, Georgia or Cambria. 

Yet, for a long time now, designers have felt we needed more. We want to choose whatever typeface we feel necessary for our designs. We did bad things along the way in pursuit of this goal such as images for text. Smart people dreamt up tools to help us such as sIFR, or Cufón. Only fairly recently, @font-face is supported in most browsers. The floodgates are opening. It really is the dawn of a new typographic era on the web. And we must tread carefully. 

The New Typesetters 

Many years ago, before the advent of desktop publishing, if you wanted words set in a particular typeface, you had to go to a Typesetter. A Typesetter, or Compositor, as they were sometimes called, was a person whose job it was to take the written word (in the form of a document or manuscript) and ‘set’ the type in the desired typeface. The designer would chose what typeface they wanted – and all the ligatures, underlines, italics and whatnot – and then scribble all over the manuscript so the typesetter could set the correct type.  

Then along came Desktop Publishing and every Tom, Dick and Harry could choose type on their computer and an entire link in the typographic chain was removed within just a few years. Well, that’s progress I guess. That was until six months ago when Typesetting was reborn on the web in the guise of a font service: Typekit. 

Typekit – and services like Typekit such as Typotheque, Kernest and the upcoming Fontdeck – are typesetting services for the web. You supply them with your content, in the form of a webpage, and they provide you with some JavaScript to render that webpage in the typeface you’ve specified simply by adding the font name in your CSS file. 

Thanks to services like these, font foundries are now talking to create licensing structures to allow us to embed fonts into our web pages legally – which has always been a sticking point in the past. So, finally, us designers can get what we want: whatever typeface we want on the web. 

Yes, but… there are hurdles. One of which is the subject of this article. 

The differences between Web Fonts and other fonts 

Web fonts are different to normal fonts. They differ in a whole bunch of ways, from loose letter spacing to larger x-heights. But perhaps the most notable practical difference is file size. Let’s take a look at one of Typekit’s latest additions from the FontFont library, Meta. 

Meta Roman weighs in at 42 KB. This is a fairly typical file size for a single weight of a good font. Now, let’s have a look at Verdana. Verdana is 186 KB. For one weight. The four weight family for Verdana weighs in at 686 KB. Four weights for half a megabyte!? Why so huge? 

Well, Verdana has a lot of information packed into its 186 KB. It has the largest hinting data table of any typeface (the information carried by a font that tells it how to align itself to the pixels on your screen). As it has been shipped with Microsoft products since 1996, it has had time to grow to support many, many languages. Along with its cousin, Georgia (283 KB), Verdana was a new breed of typeface. And it’s grown fat.  

If really serious web typography takes off – and by that I mean typefaces specifically designed for the screen – then we’re going to see more fonts increase in file size as the font files include more data. So, if you’re embedding a font weighing in at 100 KB, what happens? 

The Flash of Unstyled Text 

We all remember the Flash of Unstyled Content bug on Internet Explorer, right? That annoying bug that caused a momentary flash of unstyled HTML page. Well, the same thing can happen with embedding fonts using @font-face. An effect called The Flash of Unstyled Text (FOUT), first coined by Paul Irish. Personally, I prefer to call it the Flash of UnTypeset Text (still FOUT), as the text is styled, just not with what you want. 

If you embed a typeface in your CSS, then the browser will download that typeface. Typically, browsers differ in the way they handle this procedure. 

Firefox and Opera will render the text using the next font in your font stack until the first (embedded) font is loaded. It will then switch to the embedded font. 

Webkit takes the approach that you asked for that font so it will wait until it’s completely loaded before showing it you. 

In Opera and Firefox, you get a FOUT. In Webkit, you don’t. You wait. 

Hang on there. Didn’t I say that good web fonts weigh in considerably more than ‘normal’ fonts?   And whilst the browser is downloading the font, the user gets what to look at? Some pictures, background colours and whatever else isn’t HTML? I believe Webkit’s handling of font embedding – as deliberate as it is – is damaging to the practice of font embedding. Why? Well, we can design to a switch in typeface (as jarring as that is for the user), but we can’t design to blank space. 

Let’s have a closer look at how we can design to FOUT. 

More considered font stacks 

We all know that font stacks in CSS are there for when a user doesn’t have a font; the browser will jump to the next one in the stack. Adding embedded fonts into the font stack means that because of FOUT (in gecko and Opera), the user can see a switch, and depending on their connection that switch could happen well into any reading that the user may be doing. 

The practicalities of this are that a user could be reading and be towards the end of a line when the paragraph they are reading changes shape. The word they were digesting suddenly changes to three lines down. It’s the online equivalent of someone turning the page for you when you least expect it. So, how can we think about our font stacks slightly differently so we can minimise the switch? 

Two years ago, Richard Rutter wrote on this very site about increasing our font stacks. By increasing the font stacks (by using his handy matrix) we can begin to experiment with different typefaces. However, when we embed a typeface, we must look very carefully at the typefaces in the font stack and the relationship between them. Because, previously, the user would not see a switch from one typeface to another, they’d just get either one or the other. Not both. With FOUT, the user sees two typefaces. 

By carefully looking at the characteristics of the typefaces you choose, you can minimise the typographic ‘distance’ between the type down the stack. In doing so, you minimise the jarring effect of the switch. 

Let’s take a look at an example of how to go about this.  

Micro Typography to build better font stacks 

Let’s say I want to use a recent edition to Typekit – Meta Serif Book – as my embedded font. My font stack would start like this: 

font-family: 'Meta Serif Bold'; 

Where do you go from here? Well, first, familiarise yourself with Richard’s Font Matrix so you get an idea of what fonts are available for different people. Then start by looking closely at the characters of the embedded font and then compare them to different fonts from the matrix. 

When I do this, I’m looking to match type characteristics such as x-height, contrast (the thickness and thinness of strokes), the stress (the angle of contrast) and the shape of the serifs (if the typeface has any). 



Using just these simple comparative metrics means you can get to a ‘best fit’ reasonably quickly. And remember, you’re not after an ideal match. You’re after a match that means the switch is less painful for the reader, but also a typeface that carries similar characteristics so your design doesn’t change too much. 

Building upon my choice of embedded font, I can quickly build up a stack by comparing letters. 



This then creates my ‘best fit’ stack. 



This translates to the CSS as: 

font-family: 'Meta Serif Bold', 'Lucida Bright', Cambria, Georgia, serif 

Following this process, and ending up with considered font stacks, means that we can design to the Flash of UnTypeset Content and ensure that our readers don’t get a diminished experience.


title: Spruce It Up
year: 2009
author: Jonathan Snook
author_slug: jonathansnook
published: 2009-12-19T00:00:00+00:00
url: https://24ways.org/2009/spruce-it-up/
topic: code
contents:
The landscape of web typography is changing quickly these days. We’ve gone from the wild west days of sIFR to Cufón to finally seeing font embedding seeing wide spread adoption by browser developers (and soon web designers) with @font-face. For those who’ve felt limited by the typographic possibilities before, this has been a good year.

As Mark Boulton has so eloquently elucidated, @font-face embedding doesn’t come without its drawbacks. Font files can be quite large and FOUT—that nasty flash of unstyled text—can be a distraction for users.

Data URIs

We can battle FOUT by using Data URIs. A Data URI allows the font to be encoded right into the CSS file. When the font comes with the CSS, the flash of unstyled text is mitigated. No extra HTTP requests are required. 

Don’t be a grinch, though. Sending hundreds of kilobytes down the pipe still isn’t great. Sometimes, all we want to do is spruce up our site with a little typographic sugar. 

Be Selective

Dan Cederholm’s SimpleBits is an attractive site. 



Take a look at the ampersand within the header of his site. It’s the lovely (and free) Goudy Bookletter 1911 available from The League of Movable Type. The Opentype format is a respectable 28KB. Nothing too crazy but hold on here. Mr. Cederholm is only using the ampersand! Ouch. That’s a lot of bandwidth just for one character.

Can we optimize a font like we can an image? Yes. Image optimization essentially works by removing unnecessary image data such as colour data, hidden comments or using compression algorithms. How do you remove unnecessary information from a font? Subsetting. 

If you’re the adventurous type, grab a copy of FontForge, which is an open source font editing tool. You can open the font, view and edit any of the glyphs and then re-generate the font. The interface is a little clunky but you’ll be able to select any character you don’t want and then cut the glyphs. Re-generate your font and you’ve now got a smaller file. 



There are certainly more optimizations that can also be made such as removing hinting and kerning information. Keep in mind that removing this information may affect how well the type renders.

At this time of year, though, I’m sure you’re quite busy. Save yourself some time and head on over to the Font Squirrel Font Generator.



The Font Generator is extremely handy and allows for a number of optimizations and cross-platform options to be generated instantly. Select the font from your local system—make sure that you are only using properly licensed fonts! 

In this particular case, we only want the ampersand. Click on Subset Fonts which will open up a new menu. Unselect any preselected sets and enter the ampersand into the Single Characters text box. 

Generate your font and what are you left with? 3KB. 



The Font Generator even generates a base64 encoded data URI stylesheet to be imported easily into your project.

Check out the Demo page. (This demo won’t work in Internet Explorer as we’re only demonstrating the Data URI font embedding and not using the EOT file format that IE requires.) 

No Unnecessary Additives

If you peeked under the hood of that demo, did you notice something interesting? There’s no <span> around the ampersand. The great thing about this is that we can take advantage of the font stack’s natural ability to switch to a fallback font when a character isn’t available.

Just like that, we’ve managed to spruce up our page with a little typographic sugar without having to put on too much weight.


title: Make Your Mockup in Markup
year: 2009
author: Meagan Fisher
author_slug: meaganfisher
published: 2009-12-24T00:00:00+00:00
url: https://24ways.org/2009/make-your-mockup-in-markup/
topic: process
contents:
We aren’t designing copies of web pages, we’re designing web pages.

	 Andy Clarke, via Quotes on Design


The old way

I used to think the best place to design a website was in an image editor. I’d create a pixel-perfect PSD filled with generic content, send it off to the client, go through several rounds of revisions, and eventually create the markup.

Does this process sound familiar? You’re not alone. In a very scientific and official survey I conducted, close to 90% of respondents said they design in Photoshop before the browser.  

That process is whack, yo!

Recently, thanks in large part to the influence of design hero Dan Cederholm, I’ve come to the conclusion that a website’s design should begin where it’s going to live: in the browser.

Die Photoshop, die

Some of you may be wondering, “what’s so bad about using Photoshop for the bulk of my design?” Well, any seasoned designer will tell you that working in Photoshop is akin to working in a minefield: you never know when it’s going to blow up in your face.

 The application Adobe Photoshop CS4 has unexpectedly ruined your day.

Photoshop’s propensity to crash at crucial moments is a running joke in the industry, as is its barely usable interface. And don’t even get me started on the hot, steaming pile of crap that is  text rendering.

 Text rendered in Photoshop (left) versus Safari (right).

Crashing and text rendering issues suck, but we’ve learned to live with them. The real issue with using Photoshop for mockups is the expectations you’re setting for a client. When you send the client a static image of the design, you’re not giving them the whole picture — they can’t see how a fluid grid would function, how the design will look in a variety of browsers, basic interactions like :hover effects, or JavaScript behaviors. For more on the disadvantages to showing clients designs as images rather than websites, check out Andy Clarke’s Time to stop showing clients static design visuals.

A necessary evil?

In the past we’ve put up with Photoshop because it was vital to achieving our beloved rounded corners, drop shadows, outer glows, and gradients. However, with the recent adaptation of CSS3 in major browsers, and the slow, joyous death of IE6, browsers can render mockups that are just as beautiful as those created in an image editor. With the power of RGBA, text-shadow, box-shadow, border-radius, transparent PNGs, and @font-face combined, you can create a prototype that radiates shiny awesomeness right in the browser. If you can see this epic article through to the end, I’ll show you step by step how to create a gorgeous mockup using mostly markup.

Get started by getting naked 


	Content precedes design. Design in the absence of content is not design, it’s decoration.

	 Jeffrey Zeldman


In the beginning, don’t even think about style. Instead, start with the foundation: the content. Lay the groundwork for your markup order, and ensure that your design will be useable with styles and images turned off. This is great for prioritizing the content, and puts you on the right path for accessibility and search engine optimization. Not a bad place to start, amirite?

 An example of unstyled content, in all its naked glory. View it large.

Flush out the layout 

The next step is to structure the content in a usable way. With CSS, making basic layout changes is as easy as switching up a float, so experiment to see what structure suits the content best.

 The mockup with basic layout work done.

Got your grids covered

There are a variety of tools that allow you to layer a grid over your browser window. For Mac users I recommend using Slammer, and PC users can check out one of the bookmarklets that are available, such as 960 Gridder.

 The mockup with a grid applied using Slammer.

Once you’ve found a layout that works well for the content, pass it along to the client for review. This keeps them involved in the design process, and gives them an idea of how the site will be structured when it’s live.

Start your styling

Now for the fun part: begin applying the presentation layer. Let usability considerations drive your decisions about color and typography; use highlighted colors and contrasting typefaces on elements you wish to emphasize.

RGBA? More like RGByay!

Introducing color is easy with RGBA. I like to start with the page’s main color, then use white at varying opacities to empasize content sections.

 In the example mockup the body background is set to rgba(203,111,21), the content containers are set to rgba(255,255,255,0.7), and a few elements are highlighted with rgba(255,255,255,0.1) If you’re not sure how RGBA works, check out Drew McLellan’s super helpful 24ways article.

Laying down type

Just like with color, you can use typography to evoke a feeling and direct a user’s attention. Have contrasting typefaces (like serif headlines and sans-serif body text) to group the content into meaningful sections.

In a recent A List Apart article, the Master of Web Typography™ Jason Santa Maria offers excellent advice on how to choose your typefaces:


	Write down a general description of the qualities of the message you are trying to convey, and then look for typefaces that embody those qualities.


Sounds pretty straightforward. I wanted to give my design a classic feel with a hint of nostalgia, so I used Georgia for the headlines, and incorporated the ornate ampersand from Baskerville into the header.

 A closeup on the site’s header.

Let’s get sexy

The design doesn’t look too bad as it is, but it’s still pretty flat. We can do better, and after mixing in some CSS3 and a couple of PNGs, it’s going to get downright steamy in here.

Give it some glow

Objects in the natural world reflect light, so to make your design feel tangible and organic, give it some glow. In the example design I achieved this by creating two white to transparent gradients of varying opacities. Both have a solid white border across their top, which gives edges a double border effect and makes them look sharper. Using CSS3’s text-shadow on headlines and box-shadow on content modules is another quick way to add depth.

 A wide and closeup view of the design with gradients, text-shadow and box-shadow added. For information on how to implement text-shadow and box-shadow using RGBA, check out the article I wrote on it last week.


37 pieces of flair

Okay, maybe you don’t need that much flair, but it couldn’t hurt to add a little; it’s the details that will set your design apart. Work in imagery and texture, using PNGs with an alpha channel so you can layer images and still tweak the color later on.

 The design with grungy textures, a noisy diagonal stripe pattern, and some old transportation images layered behind the text. Because the colors are rendered using RGBA, these images bleed through the content, giving the design a layered feel. Best viewed large.


Send it off

Hey, look at that. You’ve got a detailed, well structured mockup for the client to review. Best of all, your markup is complete too. If the client approves the design at this stage, your template is practically finished. Bust out the party hats!

Not so fast, Buster!

So I don’t know about you, but I’ve never gotten a design past the client’s keen eye for criticism on the first go. Let’s review some hypothetical feedback (none of which is too outlandish, in my experience), and see how we’d make the requested changes in the browser. 

Updating the typography


	My ex-girlfriend loved Georgia, so I never want to see it again. Can we get rid of it? I want to use a font that’s chunky and loud, just like my stupid ex-girlfriend.

	 Fakey McClient


Yikes! Thankfully with CSS, removing Georgia is as easy as running a find and replace on the stylesheet. In my revised mockup, I used @font-face and League Gothic on the headlines to give the typography the, um, unique feel the client is looking for.

 The same mockup, using @font-face on the headlines. If you’re unfamiliar with implementing @font-face, check out Nice Web Type‘s helpful article.

Adding rounded corners


	I’m not sure if I’ll like it, but I want to see what it’d look like with rounded corners. My cousin, a Web 2.0 marketing guru, says they’re trendy right now.

	 Fakey McClient


Switching to rounded corners is a nightmare if you’re doing your mockup in Photoshop, since it means recreating most of the shapes and UI elements in the design. Thankfully, with CSS border-radius comes to our rescue! By applying this gem of a style to a handful of classes, you’ll be rounded out in no time.

 The mockup with rounded corners, created using border-radius. If you’re not sure how to implement border-radius, check out CSS3.info‘s quick how-to.

Making changes to the color


	The design is too dark, it’s depressing! They call it ‘the blues’ for a reason, dummy. Can you try using a brighter color? I want orange, like Zeldman uses.

	 Fakey McClient


Making color changes is another groan-inducing task when working in Photoshop. Finding and updating every background layer, every drop shadow, and every link can take forever in a complex PSD. However, if you’ve done your mockup in markup with RGBA and semi-transparent PNGs, making changes to your color is as easy as updating the body background and a few font colors.

 The mockup with an orange color scheme. Best viewed large.

Ahem, what about Internet Explorer?

Gee, thanks for reminding me, buzzkill. Several of the CSS features I’ve suggested you use, such as RGBA, text-shadow and box-shadow, and border-radius, are not supported in Internet Explorer. I know, it makes me sad too. However, this doesn’t mean you can’t try these techniques out in your markup based mockups.  The point here is to get your mockups done as efficiently as possible, and to keep the emphasis on markup from the very beginning.

Once the design is approved, you and the client have to decide if you can live with the design looking different in different browsers. Is it so bad if some users get to see drop shadows and some don’t? Or if the rounded corners are missing for a portion of your audience? The design won’t be broken for IE people, they’re just missing out on a few visual treats that other users will see.

The idea of rewarding users who choose modern browsers is not a new concept; Dan covers it thoroughly in Handcrafted CSS, and it’s been written about in the past by Aaron Gustafson and Andy Clarke on several occasions. I believe we shouldn’t have to design for the lowest common denominator (cough, IE6 users, cough); instead we should create designs that are beautiful in modern browsers, but still degrade nicely for the other guy. However, some clients just aren’t that progressive, and in that case you can always use background images for drop shadows and rounded corners, as you have in the past. 

Closing thoughts

With the advent of CSS3, browsers are just as capable of giving us beautiful, detailed mockups as Photoshop, and in half the time. I’m not the only one to make an argument for this revised process; in his article Time to stop showing clients static design visuals, and in his presentation Walls Come Tumbling Down, Andy Clarke makes a fantastic case for creating your mockups in markup.

So I guess my challenge to you for 2010 is to get out of Photoshop and into the code. Even if the arguments for designing in the browser aren’t enough to make you change your process permanently, it’s worthwhile to give it a try. Look at the New Year as a time to experiment; applying constraints and evaluating old processes can do wonders for improving your efficiency and creativity.


title: The Web Is Your CMS
year: 2009
author: Christian Heilmann
author_slug: chrisheilmann
published: 2009-12-17T00:00:00+00:00
url: https://24ways.org/2009/the-web-is-your-cms/
topic: code
contents:
It is amazing what you can do these days with the services offered on the web. Flickr stores terabytes of photos for us and converts them automatically to all kind of sizes, finds people in them and even allows us to edit them online. YouTube does almost the same complete job with videos, LinkedIn allows us to maintain our CV, Delicious our bookmarks and so on.

We don’t have to do these tasks ourselves any more, as all of these systems also come with ways to use the data in the form of Application Programming Interfaces, or APIs for short. APIs give us raw data when we send requests telling the system what we want to get back.

The problem is that every API has a different idea of what is a simple way of accessing this data and in which format to give it back.

Making it easier to access APIs

What we need is a way to abstract the pains of different data formats and authentication formats away from the developer — and this is the purpose of the Yahoo Query Language, or YQL for short. 

Libraries like jQuery and YUI make it easy and reliable to use JavaScript in browsers (yes, even IE6) and YQL allows us to access web services and even the data embedded in web documents in a simple fashion – SQL style.

Select * from the web and filter it the way I want

YQL is a web service that takes a few inputs itself:


	A query that tells it what to get, update or access
	An output format – XML, JSON, JSON-P or JSON-P-X
	A callback function (if you defined JSON-P or JSON-P-X)


You can try it out yourself – check out this link to get back Flickr photos for the search term ‘santa’*%20from%20flickr.photos.search%20where%20text%3D%22santa%22&format=xml in XML format. The YQL query for this is 

select * from flickr.photos.search where text="santa"

The easiest way to take your first steps with YQL is to look at the console. There you get sample queries, access to all the data sources available to you and you can easily put together complex queries. In this article, however, let’s use PHP to put together a web page that pulls in Flickr photos, blog posts, Videos from YouTube and latest bookmarks from Delicious.

Check out the demo and get the source code on GitHub.

<?php
  /* YouTube RSS */
  $query = 'select description from rss(5) where url="http://gdata.youtube.com/feeds/base/users/chrisheilmann/uploads?alt=rss&v=2&orderby=published&client=ytapi-youtube-profile";';
  /* Flickr search by user id */
  $query .= 'select farm,id,owner,secret,server,title from flickr.photos.search where user_id="11414938@N00";';
  /* Delicious RSS */
  $query .= 'select title,link from rss where url="http://feeds.delicious.com/v2/rss/codepo8?count=10";';
  /* Blog RSS */
  $query .= 'select title,link from rss where url="http://feeds.feedburner.com/wait-till-i/gwZf"';
  /* The YQL web service root with JSON as the output */
  $root = 'http://query.yahooapis.com/v1/public/yql?format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys';
  /* Assemble the query */
  $query = "select * from query.multi where queries='".$query."'";
  $url = $root . '&q=' . urlencode($query);
  /* Do the curl call (access the data just like a browser would) */
  $ch = curl_init(); 
  curl_setopt($ch, CURLOPT_URL, $url); 
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  $output = curl_exec($ch); 
  curl_close($ch);
  $data = json_decode($output);
  $results = $data->query->results->results;
  /* YouTube output */
  $youtube = '<ul id="youtube">';
  foreach($results[0]->item as $r){
	$cleanHTML = undoYouTubeMarkupCrimes($r->description);
	$youtube .= '<li>'.$cleanHTML.'</li>';
  }
  $youtube .= '</ul>';
  /* Flickr output */
  $flickr = '<ul id="flickr">';
  foreach($results[1]->photo as $r){
	$flickr .= '<li>'.
			   '<a href="http://www.flickr.com/photos/codepo8/'.$r->id.'/">'.
			   '<img src="http://farm' .$r->farm . '.static.flickr.com/'.
			   $r->server . '/' . $r->id . '_' . $r->secret . 
			   '_s.jpg" alt="'.$r->title.'"></a></li>';
  }
  $flickr .= '</ul>';
  /* Delicious output */
  $delicious = '<ul id="delicious">';
  foreach($results[2]->item as $r){
	$delicious .= '<li><a href="'.$r->link.'">'.$r->title.'</a></li>';
  }
  $delicious .= '</ul>';
  /* Blog output */
  $blog = '<ul id="blog">';
  foreach($results[3]->item as $r){
	$blog .= '<li><a href="'.$r->link.'">'.$r->title.'</a></li>';
  }
  $blog .= '</ul>';
  function undoYouTubeMarkupCrimes($str){
	$cleaner = preg_replace('/555px/','100%',$str);
	$cleaner = preg_replace('/width="[^"]+"/','',$cleaner);
	$cleaner = preg_replace('/<tbody>/','<colgroup><col width="20%"><col width="50%"><col width="30%"></colgroup><tbody>',$cleaner);
	return $cleaner;
  }
?>

What we are doing here is create a few different YQL statements and queue them together with the query.multi table. Each of these can be run inside YQL itself. Check out the YouTube, Flickr, Delicious and Blog example in the console if you don’t believe me. The benefit of using this table is that we don’t make individual requests for each query but we get all the data in one single request – which means a much better performing solution as the YQL server farm is faster on the web than our servers.

We point the query to the YQL web service end point and get the resulting data using cURL. All that we need to do then is to convert the returned data to HTML lists that can be printed out inside an HTML template.

Mixing, matching and using HTML as a data source

This was a simple example of what YQL can do for you. Where it gets really powerful however is by mixing and matching different APIs. YQL is also a good tool to get information from HTML documents. By using the html table you can load the content of an HTML document (which gets fixed automatically by HTMLTidy) and use XPATH to filter down results to what you need. Take the following example which takes headlines from the news.bbc.co.uk homepage and runs the results through Yahoo’s Term Extractor API to give you a list of currently hot topics.

select * from search.termextract where context in (
  select content from html where url="http://news.bbc.co.uk" and xpath="//table[@width=800]//a"
)

Try it out in the console or see the results here. In English, this means:


	Go to http://news.bbc.co.uk and get me the HTML
	Run it through HTML Tidy to clean it up.
	Get me only the links inside the table with an attribute of width and the value 800
	Get only the content of the link and for each of the links
	
		Take the content and send it as context to the Yahoo Term Extractor API
	
	

If we choose JSON-P as the output format we can use the outcome directly in JavaScript (see this demo or see its source):

<ul id="hottopics"></ul>
<script type="text/javascript">
function hottopics(o){
  var res = o.query.results.Result,
	  all = res.length,
	  topics = {},
	  out = [],
	  html = '',
	  i=0;
  /* create hash from topics to prevent repetition */	 
  for(i=0;i<all;i++){
	topics[res[i]] = res[i];
  };
  for(i in topics){
	out.push(i);
  };
  html = '<li>' + out.join('</li><li>') + '</li>';
  document.getElementById('hottopics').innerHTML = html;
};
</script>
<script type="text/javascript" src="http://query.yahooapis.com/v1/public/yql?q=select%20content%20from%20search.termextract%20where %20context%20in%20(select%20content%20from%20html%20where%20url%3D%22http%3A%2F%2Fnews.bbc.co.uk%22%20and%20xpath%3D%22%2F%2Ftable%5B%40width%3D800%5D%2F%2Fa%22)&format=json&callback=hottopics"></script>

Using JSON, we can also use PHP which means the demo works for everybody – not only those with JavaScript enabled (see this demo or see its source):

<ul id="hottopics"><li>
<?php
$url = 'http://query.yahooapis.com/v1/public/yql?q=select%20content'.
	   '%20from%20search.termextract%20where%20context%20in'.
	   '%20(select%20content%20from%20html%20where%20url%3D%22'.
	   'http%3A%2F%2Fnews.bbc.co.uk%22%20and%20xpath%3D%22%2F%2F'.
	   'table%5B%40width%3D800%5D%2F%2Fa%22)&format=json';
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$output = curl_exec($ch); 
curl_close($ch);
$data = json_decode($output);
$topics = array_unique($data->query->results->Result);
echo join('</li><li>',$topics);
?>
</li></ul>

Summary

This article could only scratch the surface of YQL. You have not only read access to the web but you can also write to web services. For example you can update Twitter, post to your WordPress blog or shorten a URL with bit.ly. Using Open Tables you can add any web service to the YQL interface and you can even run server-side JavaScript which is for example useful to return Flickr photos as HTML or get the HTML content from a document that needs POST data.

The web of data is already here, and using YQL you don’t have to be a web services expert to use it and be part of it.


title: A New Year's Resolution
year: 2009
author: Mike Kus
author_slug: mikekus
published: 2009-12-10T00:00:00+00:00
url: https://24ways.org/2009/a-new-years-resolution/
topic: business
contents:
The end of 2009 is fast approaching.  Yet another year has passed in a split second. Our Web Designing careers are one year older and it’s time to reflect on the highs and lows of 2009. What was your greatest achievement and what could you have done better? Perhaps, even more importantly, what are your goals for 2010?

Something that I noticed in 2009 is that being a web designer 24/7; it’s easy to get consumed by the web. It’s easy to get caught up in the blog posts, CSS galleries, web trends and Twitter!  Living in this bubble can lead to one’s work becoming stale, boring and basically like everyone else’s work on the web. No designer wants this.

So, I say on 1st January 2010 let’s make it our New Year’s resolution to create something different, something special or even ground-breaking! Make it your goal to break the mold of current web design trends and light the way for your fellow web designer comrades!

Of course I wouldn’t let you embark on the New Year empty handed. To help you on your way I’ve compiled a few thoughts and ideas to get your brains ticking!

Don’t design for the web, just design

A key factor in creating something original and fresh for the web is to stop thinking in terms of web design. The first thing we need to do is forget the notion of headers, footers, side bars etc. A website doesn’t necessarily need any of these, so even before we’ve started we’ve already limited our design possibilities by thinking in these very conventional and generally accepted web terms. The browser window is a 2D canvas like any other and we can do with it what we like. 

With this in mind we can approach web design from a fresh perspective. We can take inspiration for web design from editorial design, packaging design, comics, poster design, album artwork, motion design, street signage and anything else you can think of. Web design is way more than the just the web and by taking this more wide angled view of what web design is and can be you’ll find there are a thousand more exiting design possibilities.

Note: Try leaving the wire framing till after you’ve gone to town with some initial design concepts. You might find it helps keep your head out of that ‘web space’ a little bit longer, thus enabling you to think more freely about your design. Really go crazy with these as you can always pull it back into line later. The key is to think big initially and then work backwards. There’s no point restricting your creativity early on because your technical knowledge can foresee problems down the line. You can always sort these problems out later on… let your creative juices flow!

 Inspiration can come from anywhere! (Photo: modomatic)

Try something new!

Progress in web design or in any design discipline is a sort of evolution. Design trends and solutions merge and mutate to create new design trends and hopefully better solutions. This is fine but the real leaps are made when someone has the guts to do something different. 

Don’t be afraid to challenge the status quo. To create truly original work you have to be prepared to get it wrong and that’s hard to do. When you’re faced with this challenge just remind yourself that in web design there is rarely a ‘best way to do something’, or why would we ever do it any other way? 

If you do this and get it right the pay off can be immense. Not only will you work stand out from the crowd by a mile, you will have become a trend setter as opposed to a trend follower.

Tell a story with your design

Great web design is way more than just the aesthetics, functionality or usability. Great web design goes beyond the pixels on the screen. For your website to make a real impact on it’s users it has to connect with them emotionally. So, whether your website is promoting your own company or selling cheese it needs to move people. You need to weave a story into your design. It’s this story that your users will connect with. 

To do this the main ingredients of your design need to be strongly connected. In my head those main ingredients are Copy, Graphic Design, Typography, imagery and colour. 

Copy

Strong meaningful copy is the backbone to most great web design work. Pay special attention to strap lines and headlines as these are often the sparks that start the fire. All the other elements can be inspired by this backbone of strong copy.

Graphic Design

Use the copy to influence how you treat the page with your graphic design. Let the design echo the words.

Typography

What really excites me about typography isn’t the general text presentation on a page, most half decent web designer have a grasp of this already. What excites me is the potential there is to base a whole design on words and letters. Using the strong copy you already have, one has the opportunity the customise, distort, build and arrange words and letters to create beautiful and powerful compositions that can be the basis for an entire site design.

 Get creative with Typography (Photo: Pam Sattler)

Imagery and Colour

With clever use of imagery (photographs or illustrations) and colour you further have the chance to deepen the story you are weaving into your design. The key is to use meaningful imagery, don’t to insert generic imagery for the sake of filling space… it’s just a wasted opportunity.

Remember, the main elements of your design combined are greater than the sum of their parts. Whatever design decisions you make on a page, make them for a good reason. It’s not good enough to try and seduce your users with slick and shiny web pages. For your site to leave a lasting impression on the user you need to make that emotional connection.

 Telling the Story (Advertising Agency: Tita, Milano, Italy, Art Director: Emanuele Basso)

Go one step further

So you’ve almost finished your latest website design. You’ve fulfilled the brief, you’re happy with the result and you’re pretty sure your client will be too. It’s at this point we should ask ourselves “Can I push this further”? What touches could you add to the site that’ll take it beyond what was required and into something exceptional? The truth is, to produce exceptional work we need to do more than is required of us. We need to answer the brief and then some!

Go back through your site and make a note of what enhancements could be made to make the site not just good but outstanding. It might be revisiting a couple of pages that were neglected in the design process, it might be adding some CSS 3 gloss for the users that can benefit from it or it might just be adding some clever little easter eggs to show that you care. These touches will soon add up and make a massive difference to the finished product.

So, go one step further… take it further than you anyone else will. Then your work will stand out for sure.

Parting message

I love being a designer for many of reasons but the main one being that with every new project we embark on we have the chance to express ourselves. We have the chance to create something special, something that people will talk about. It’s this chance that drives us onwards day after day, year after year. So in 2010 shout louder than you ever have before, take chances, try something new and above all design your socks off!


title: Don't Lose Your :focus
year: 2009
author: Patrick Lauke
author_slug: patricklauke
published: 2009-12-09T00:00:00+00:00
url: https://24ways.org/2009/dont-lose-your-focus/
topic: code
contents:
For many web designers, accessibility conjures up images of blind users with screenreaders, and the difficulties in making sites accessible to this particular audience. Of course, accessibility covers a wide range of situations that go beyond the extreme example of screenreader users. And while it’s true that making a complex site accessible can often be a daunting prospect, there are also many small things that don’t take anything more than a bit of judicious planning, are very easy to test (without having to buy expensive assistive technology), and can make all the difference to certain user groups.

In this short article we’ll focus on keyboard accessibility and how careless use of CSS can potentially make your sites completely unusable.

Keyboard Access

Users who for whatever reason can’t use a mouse will employ a keyboard (or keyboard-like custom interface) to navigate around web pages. By default, they will use TAB and SHIFT + TAB to move from one focusable element (links, form controls and area) of a page to the next.

Note: in OS X, you’ll first need to turn on full keyboard access under System Preferences > Keyboard and Mouse > Keyboard Shortcuts. Safari under Windows needs to have the option Press Tab to highlight each item on a webpage in Preferences > Advanced enabled. Opera is the odd one out, as it has a variety of keyboard navigation options – the most relevant here being spatial navigation via Shift+Down, Shift+Up, Shift+Left, and Shift+Right).

But I Don’t Like Your Dotted Lines…

To show users where they are within a page, browsers place an outline around the element that currently has focus. The “problem” with these default outlines is that some browsers (Internet Explorer and Firefox) also display them when a user clicks on a focusable element with the mouse. Particularly on sites that make extensive use of image replacement on links with “off left” techniques this can create very unsightly outlines that stretch from the replaced element all the way to the left edge of the browser.

 Outline bleeding off to the left (image-replacement example from carsonified.com)

There is a trivial workaround to prevent outlines from “spilling over” by adding a simple overflow:hidden, which keeps the outline in check around the clickable portion of the image-replaced element itself.

 Outline tamed with overflow:hidden

But for many designers, even this is not enough. As a final solution, many actively suppress outlines altogether in their stylesheets. Controversially, even Eric Meyer’s popular reset.css – an otherwise excellent set of styles that levels the playing field of varying browser defaults – suppresses outlines.

html, body, div, span, applet, object, iframe ... {
	...
	outline: 0;
	...
}
/* remember to define focus styles! */
:focus {
	outline: 0;
}

Yes, in his explanation (and in the CSS itself) Eric does remind designers to define relevant styles for :focus… but judging by the number of sites that seem to ignore this (and often remove the related comment from the stylesheet altogether), the message doesn’t seem to have sunk in.

Anyway… hurrah! No more unsightly dotted lines on our lovely design. But what about keyboard users? Although technically they can still TAB from one element to the next, they now get no default cue as to where they are within the page (one notable exception here is Opera, where the outline is displayed regardless of stylesheets)… and if they’re Safari users, they won’t even get an indication of a link’s target in the status bar, like they would if they hovered over it with the mouse.

Only Suppress outline For Mouse Users

Is there a way to allow users navigating with the keyboard to retain the standard outline behaviour they’ve come to expect from their browser, while also ensuring that it doesn’t show display for mouse users?

 Testing some convoluted style combinations

After playing with various approaches (see Better CSS outline suppression for more details), the most elegant solution also seemed to be the simplest: don’t remove the outline on :focus, do it on :active instead – after all, :active is the dynamic pseudo-class that deals explicitly with the styles that should be applied when a focusable element is clicked or otherwise activated.

a:active { outline: none; }

The only minor issues with this method: if a user activates a link and then uses the browser’s back button, the outline becomes visible. Oh, and old versions of Internet Explorer notoriously get confused by the exact meaning of :focus, :hover and :active, so this method fails in IE6 and below. Personally, I can live with both of these.

Note: at the last minute before submitting this article, I discovered a fatal flaw in my test. It appears that outline still manages to appear in the time between activating a link and the link target loading (which in hindsight is logical – after activation, the link does indeed receive focus). As my test page only used in-page links, this issue never came up before. The slightly less elegant solution is to also suppress the outline on :hover.

a:hover, a:active { outline: none; }

In Conclusion

Of course, many web designers may argue that they know what’s best, even for their keyboard-using audience. Maybe they’ve removed the default outline and are instead providing some carefully designed :focus styles. If they know for sure that these custom styles are indeed a reliable alternative for their users, more power to them… but, at the risk of sounding like Jakob “blue underlined links” Nielsen, I’d still argue that sometimes the default browser behaviours are best left alone. Complemented, yes (and if you’re already defining some fancy styles for :hover, by all means feel free to also make them display on :focus)… but not suppressed.


title: Ignorance Is Bliss
year: 2009
author: Andy Clarke
author_slug: andyclarke
published: 2009-12-23T00:00:00+00:00
url: https://24ways.org/2009/ignorance-is-bliss/
topic: business
contents:
This is a true story.

Meet Mike 

Mike’s a smart guy. He knows a great browser when he sees one. He uses Firefox on his Windows PC at work and Safari on his Mac at home. Mike asked us to design a Web site for his business. So we did.

We wanted to make the best Web site for Mike that we could, so we used all of the CSS tools that are available today. That meant using RGBa colour to layer elements, border-radius to add subtle rounded corners and (possibly most experimental of all new CSS), generated gradients.

 The home page Mike sees in Safari on his Mac

Mike loves what he sees.

Meet Sam

Sam works with Mike. She uses Internet Explorer 7 because it came on the Windows laptop that the company bought her when she joined. 

 The home page Sam sees in Internet Explorer 7 on her PC

Sam loves the new Web site too.

How could both of them be happy when they experienced the Web site differently?

The new WYSIWYG

When I first presented my designs to Mike and Sam, I showed them a Web page made with HTML and CSS in their respective browsers and not a picture of a Web page. By showing neither a static image of my design, I set none of the false expectations that, by definition, a static Photoshop or Fireworks visual would have established.

Mike saw rounded corners and subtle shadows in Firefox and Safari. Sam saw something equally as nice, just a little different, in Internet Explorer. Both were very happy because they saw something that they liked.

Neither knew, or needed to know, about the subtle differences between browsers. Their users don’t need to know either.

That’s because in the real world, people using the Web don’t find a Web site that they like, then open up another browser to check that it looks they same. They simply buy what they came to buy, read what what they came to read, do what they came to do, then get on with their lives in blissful ignorance of what they might be seeing in another browser.

Often when I talk or write about using progressive CSS, people ask me, “How do you convince clients to let you work that way? What’s your secret?” Secret? I tell them what they need to know, on a need-to-know basis.

Epilogue

Sam has a new iPhone that Mike bought for her as a reward for achieving her sales targets. She loves her iPhone and was surprised at just how fast and good-looking the company Web site appears on that. So she asked,


	“Andy, I didn’t know you optimised our site for mobile. I don’t remember seeing an invoice for that.”


I smiled.


	“That one was on the house.”


title: Self-Testing Pages with JavaScript
year: 2009
author: Ross Bruniges
author_slug: rossbruniges
published: 2009-12-12T00:00:00+00:00
url: https://24ways.org/2009/self-testing-pages-with-javascript/
topic: process
contents:
Working at an agency I am involved more and more on projects in which client side code is developed internally then sent out to a separate team for implementation. You provide static HTML, CSS and JavaScript which then get placed into the CMS and brought to life as an actual website. As you can imagine this can sometimes lead to frustrations. However many safeguards you include, handing over your code to someone else is always a difficult thing to do effectively.

In this article I will show you how you can create a JavaScript implementation checker and that will give you more time for drink based activity as your web site and apps are launched quicker and with less unwanted drama!

An all too frequent occurrence

You’ve been working on a project for weeks, fixed all your bugs and send it to be implemented. You hear nothing and assume all is going well then a few days before it’s meant to launch you get an email from the implementation team informing you of bugs in your code that you need to urgently fix.

 The 24ways website with a misspelt ID for the years menu

Being paranoid you trawl through the preview URL, check they have the latest files, check your code for errors then notice that a required HTML attribute has been omitted from the build and therefore CSS or JavaScript you’ve hooked onto that particular attribute isn’t being applied and that’s what is causing the “bug”.

It takes you seconds drafting an email informing them of this, it takes then seconds putting the required attribute in and low and behold the bug is fixed, everyone is happy but you’ve lost a good few hours of your life – this time could have been better spent in the pub.

I’m going to show you a way that these kind of errors can be alerted immediately during implementation of your code and ensure that when you are contacted you know that there actually is a bug to fix. You probably already know the things that could be omitted from a build and look like bugs so you’ll soon be creating tests to look for these and alert when they are not found on the rendered page. The error is reported directly to those who need to know about it and fix it. Less errant bug reports and less frantic emails ahoy!

 A page with an implementation issue and instant feedback on the problem

JavaScript selector engines to the rescue

Whether you’re using a library or indeed tapping into the loveliness of the new JavaScript Selector APIs looking for particular HTML elements in JavaScript is fairly trivial now. 

For instance this is how you look for a div element with the id attribute of year (the missing attribute from top image) using jQuery (the library I’ll be coding my examples in): 

if ($(‘div#year’).length) {
	alert(‘win’);
}

Using this logic you can probably imagine how you can write up a quick method to check for the existence of a particular element and alert when it’s not present — but assuming you have a complex page you’re going to be repeating yourself a fair bit and we don’t want to be doing that.

Test scripts

If you’ve got a lot of complex HTML patterns that need testing across a number of different pages it makes sense to keep your tests out of production code. Chances are you’ve already got a load of heavy JavaScript assets, and when it comes to file size saving every little helps.

I don’t think that tests should contain code inside of them so keep mine externally as JSON. This also means that you can use the one set of tests in multiple places. We already know that it’s a good idea to keep our CSS and JavaScript separate so lets continue along those lines here.

The test script for this example looks like this:

{
	"title": "JS tabs implementation test",
	"description": "Check that the correct HTML patterns has been used",
	"author": "Ross Bruniges",
	"created": "20th July 2009",
	"tests": [
		{
			"name": "JS tabs elements",
			"description": "Checking that correct HTML elements including class/IDs are used on the page for the JS to progressively enhance",
			"selector": "div.tabbed_content",
			"message": "We couldn't find VAR on the page - it's required for our JavaScript to function correctly",
			"check_for": {
				"contains": {
					"elements": [
						"div.tab_content", "h2" 
					],
					"message": "We've noticed some missing HTML:</p><ul><li>VAR</li></ul><p>please refer to the examples sent for reference" 
				} 
			} 
		} 
	]
}

The first four lines are just a little bit of meta data so we remember what this test was all about when we look at it again in the future, or indeed if it ever breaks. The tests are the really cool parts and firstly you’ll notice that it’s an array – we’re only going to show one example test here but there is no reason why you can’t place in as many as you want. I’ll explain what each of the lines in the example test means:


	name – short test name, I use this in pass/fail messaging later
	description – meta data for future reference
	selector – the root HTML element from which your HTML will be searched
	message – what the app will alert if the initial selector isn’t found
	check_for – a wrapper to hold inner tests – those run if the initial selector does match
	
		contains – the type of check, we’re checking that the selector contains specified elements
		
			elements – the HTML elements we are searching for
			message – a message for when these don’t match (VAR is substituted when it’s appended to the page with the name of any elements that don’t exist)
		
		
		

It’s very important to pass the function valid JSON (JSONLint is a great tool for this) otherwise you might get a console showing no tests have even been run. 

The JavaScript that makes this helpful

Again, this code should never hit a production server so I’ve kept it external. This also means that the only thing that’s needed to be done by the implementation team when they are ready to build is that they delete this code.

<script src="sleuth.js" type="text/javascript"></script>
<script type="text/javascript">
	$(document).ready(function() {
	  sleuth.test_page.init(‘js_tabs_test.js');
	}); 
</script>

“View the full JavaScript:/examples/self-testing-pages-with-javascript/js/tests/test_suite.js

The init function appends the test console to the page and inserts the CSS file required to style it (you don’t need to use pictures of me when tests pass and fail though I see no reason why you shouldn’t), goes and grabs the JSON file referenced and parses it. The methods to pass (tests_pass) and fail (haz_fail) the test I hope are pretty self-explanatory as is the one which creates the test summary once everything has been run (create_summary).

The two interesting functions are init_tests and confirm_html.

init_tests

init_tests:function(i,obj) {
	var $master_elm = $(obj.selector);
	sleuth.test_page.$logger.append("<div id='test_" + i + "' class='message'><p><em>" + obj.name + "</em></p></div>");
	var $container = $('#test_' + i);
	if (!$master_elm.length) {
		var err_sum = obj.message.replace(/VAR/gi, obj.selector);
		sleuth.test_page.haz_failed(err_sum, $container);
		return;
	}
	if (obj.check_for) {
		$.each(obj.check_for,function(key, value){
			sleuth.test_page.assign_checks($master_elm, $container, key, value);
		});
	} else {
		sleuth.test_page.tests_passed($container);
		return;
	}
}

The function gets sent the number of the current iteration (used to create a unique id for its test summary) and the current object that contains the data we’re testing against as parameters.

We grab a reference to the root element and this is used (pretty much in the example shown right at the start of this article) and its length is checked. If the length is positive we know we can continue to the inner tests (if they exist) but if not we fail the test and don’t go any further. We append the error to the test console for everyone to see.

If we pass the initial check we send the reference to the root element, message contains and the inner object to a function that in this example sends us on to confirm_html (if we had a more complex test suite it would do a lot more). 

confirm_html

confirm_html:function(target_selector, error_elm, obj) {
	var missing_elms = [];
	$.each(obj.elements, function(i, val) {
		if (!target_selector.find(val).length) {
			missing_elms.push(val);
		}	
	});
	if (missing_elms.length) {
		var file_list = missing_elms.join('</li><li>');
		var err_sum = obj.message.replace(/VAR/gi, file_list);
		sleuth.test_page.haz_failed(err_sum, error_elm);
		return;
	}
	sleuth.test_page.tests_passed(error_elm);
	return;
}

We’re again using an array to check for a passed or failed test and checking its length but this time we push in a reference to each missing element we find.

If the test does fail we’re providing even more useful feedback by informing what elements have been missed out. All the implementation team need do is look for them in the files we’ve sent and include them as expected.

No more silly implementation bugs!

Here is an example of a successful implementation.

Here are some examples of failed implementations – one which fails at finding the root node and one that has the correct root node but none of the inner HTML tests pass.

Is this all we can check for?

Certainly not!

JavaScript provides pretty easy ways to check for attributes, included files (if the files being checked for are being referenced correctly and not 404ing) and even applied CSS.

Want to check that those ARIA attributes are being implemented correctly or that all images contain an alt attribute well this simple test suite can be extended to include tests for this – the sky is pretty much up to your imagination.


title: CSS Animations
year: 2009
author: Tim Van Damme
author_slug: timvandamme
published: 2009-12-15T00:00:00+00:00
url: https://24ways.org/2009/css-animations/
topic: code
contents:
Friend: You should learn how to write CSS!
Me: …
Friend: CSS; Cascading Style Sheets. If you’re serious about web design, that’s the next thing you should learn.
Me: What’s wrong with <font> tags?

That was 8 years ago. Thanks to the hard work of Jeffrey, Andy, Andy, Cameron, Colly, Dan and many others, learning how to decently markup a website and write lightweight stylesheets was surprisingly easy. They made it so easy even a complete idiot (OH HAI) was able to quickly master it.

And then… nothing. For a long time, it seemed like there wasn’t happening anything in the land of CSS, time stood still. Once you knew the basics, there wasn’t anything new to keep up with. It looked like a great band split, but people just kept re-releasing their music in various “Best Of!” or “Remastered!” albums.

Fast forward a couple of years to late 2006. On the official WebKit blog Surfin’ Safari, there’s an article about something called CSS animations. Great new stuff to play with, but only supported by nightly builds (read: very, very beta) of WebKit. In the following months, they release other goodies, like CSS gradients, CSS reflections, CSS masks, and even more CSS animation sexiness. Whoa, looks like the band got back together, found their second youth, and went into overdrive! The problem was that if you wanted to listen to their new albums, you had to own some kind of new high-tech player no one on earth (besides some early adopters) owned.

Back in the time machine. It is now late 2009, close to Christmas. Things have changed. Browsers supporting these new toys are widely available left and right. Even non-techies are using these advanced browsers to surf the web on a daily basis!

Epic win? Almost, but at least this gives us enough reason to start learning how we could use all this new CSS voodoo. On Monday, Natalie Downe showed you a good tutorial on Going Nuts with CSS Transitions. Today, I’m taking it one step further…

Howto: A basic spinner

No matter how fast internet tubes or servers are, we’ll always need spinners to indicate something’s happening behind the scenes. Up until now, people would go to some site, pick one of the available templates, customize their foreground and background colors, and download a beautiful GIF image.

There are some downsides to this though:


	It’s only _semi_-transparent: If you change your mind and pick a slightly different background color, you need to go back to the site, set all the parameters again, and replace your current image. There isn’t even a way to pick an image or gradient as background.
	Limited number of frames, probable to keep the file-size as small as possible (don’t forget this thing needs to be loaded before whatever process is finished in the background), and you don’t have that 24 frames per second smoothness.
	This is just too fucking easy. As a front-end code geek, there must be a “cooler” way to do this!


What do we need to make a spinner with CSS animations? One image, and one element on our webpage we can hook on to. Yes, that’s it. I created a simple transparent PNG that looks it might be a spinner, and for the element on the page, I wrote this piece of genius HTML:

<p id="spinner">Please wait while we do what we do best.</p>

Looks semantic enough to me! Here’s the basic HTML I’m using to position the element in the center of the screen, and make the text inside it disappear:

#spinner {
	position: absolute;
	top: 50%;
	left: 50%;
	margin: -100px 0 0 -100px;
	height: 200px;
	width: 200px;
	text-indent: 250px;
	white-space: nowrap;
	overflow: hidden;
}

Cool, but now we don’t see anything. Let’s pull rabbit number one out of the hat: -webkit-mask-image (accompanied by the previously mentioned transparent PNG image):

#spinner {
	...
	-webkit-mask-image: url(../img/spinner.png);
}

By now you should be feeling like a magician already. Oh, wait, we still have a blank screen, looks like we left something in the hat (tip: not rabbit droppings):

#spinner {
	...
	-webkit-mask-image: url(../img/spinner.png);
	background-color: #000;
}

Nice! What we’ve done right here is telling the element to clip onto the PNG. It’s a lot like clipping layers in Photoshop. So, spinners, they move, right? Into the hat again, and look what we pull out this time: CSS animations!

#spinner {
	...
	-webkit-mask-image: url(../img/spinner.png);
	background-color: #000;
	-webkit-animation-name: spinnerRotate;
	-webkit-animation-duration: 2s;
	-webkit-animation-iteration-count: infinite;
	-webkit-animation-timing-function: linear;
}

Some explanation:


	-webkit-animation-name: Name of the animation we’ll be defining later.
	-webkit-animation-duration: The timespan of the animation.
	-webkit-animation-iteration-count: Repeat once, a defined number of times or infinitely?
	-webkit-animation-timing-function: Linear is the one you’ll be using mostly. Other options are ease-in, ease-out, ease-in-out…


Let’s define spinnerRotate:

@-webkit-keyframes spinnerRotate {
	from {
		-webkit-transform:rotate(0deg);
	}
	to {
		-webkit-transform:rotate(360deg);
	}
}

En Anglais: Rotate #spinner starting at 0 degrees, ending at 360 degrees, over a timespan of 2 seconds, at a constant speed, and keep repeating this animation forever.

That’s it! See it in action on the demo page.

Note: these examples only work when you’re using a WebKit-based browser like Safari, Mobile Safari or Google Chrome. I’m confident though that Mozilla and Opera will try their very best catching up with all this new CSS goodness soon.

When looking at this example, you see the possibilities are endless. Another advantage is you can change the look of it entirely by only changing a couple of lines of CSS, instead of re-creating and re-downloading the image from some website smelling like web 2.0 gone bad. I made another demo that shows how great it is to be able to change background and foreground colors (even on the fly!).

So there you have it, a smoothly animated, fully transparent and completely customizable spinner. Cool? I think so. (Ladies?)

But you can do a lot more with CSS animations than just create pretty spinners. Since I was fooling around with it anyway, I decided to test how far you can push this, space is the final limit, right?

Conclusion

CSS has never been more exciting than it is right now. I’m even prepared to say CSS is “cool” again, both for the more experienced front-end developers as for the new designers discovering CSS every day now.

But…

Remember when Javascript became popular? Remember when Flash became popular? Every time we’re been given new toys, some people aren’t ashamed to use it in a way you can barely call constructive. I’m thinking of Geocities websites, loaded with glowing blocks of text, moving images, bad color usage… In the wise words of Stan Lee: With great power there must also come great responsibility! A sprinkle of CSS animations is better than a bucket load. Apply with care.


title: Cleaner Code with CSS3 Selectors
year: 2009
author: Rachel Andrew
author_slug: rachelandrew
published: 2009-12-20T00:00:00+00:00
url: https://24ways.org/2009/cleaner-code-with-css3-selectors/
topic: code
contents:
The parts of CSS3 that seem to grab the most column inches on blogs and in articles are the shiny bits. Rounded corners, text shadow and new ways to achieve CSS layouts are all exciting and bring with them all kinds of possibilities for web design. However what really gets me, as a developer, excited is a bit more mundane.  

In this article I’m going to take a look at some of the ways our front and back-end code will be simplified by CSS3, by looking at the ways we achieve certain visual effects now in comparison to how we will achieve them in a glorious, CSS3-supported future. I’m also going to demonstrate how we can use these selectors now with a little help from JavaScript – which can work out very useful if you find yourself in a situation where you can’t change markup that is being output by some server-side code.

The wonder of nth-child

So why does nth-child get me so excited? Here is a really common situation, the designer would like the tables in the application to look like this:



Setting every other table row to a different colour is a common way to enhance readability of long rows. The tried and tested way to implement this is by adding a class to every other row. If you are writing the markup for your table by hand this is a bit of a nuisance, and if you stick a row in the middle you have to change the rows the class is applied to. If your markup is generated by your content management system then you need to get the server-side code to add that class – if you have access to that code.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Striping every other row - using classes</title>
<style type="text/css">
	body {
		padding: 40px;
		margin: 0;
		font: 0.9em Arial, Helvetica, sans-serif;
	}
	table {
		border-collapse: collapse;
		border: 1px solid #124412;
		width: 600px;
	}
	th {
		border: 1px solid #124412;
		background-color: #334f33;
		color: #fff;
		padding: 0.4em;
		text-align: left;
	}
	td {
		padding: 0.4em;
	}
	tr.odd td {
		background-color: #86B486;
	}
</style>
</head>
<body>
	<table>
		<tr>
			<th>Name</th>
			<th>Cards sent</th>
			<th>Cards received</th>
			<th>Cards written but not sent</th>
		</tr>
		<tr>
			<td>Ann</td>
			<td>40</td>
			<td>28</td>
			<td>4</td>
		</tr>
		<tr class="odd">
			<td>Joe</td>
			<td>2</td>
			<td>27</td>
			<td>29</td>
		</tr>
		<tr>
			<td>Paul</td>
			<td>5</td>
			<td>35</td>
			<td>2</td>
		</tr>
		<tr class="odd">
			<td>Louise</td>
			<td>65</td>
			<td>65</td>
			<td>0</td>
		</tr>
	</table>
</body>
</html>

View Example 1

This situation is something I deal with on almost every project, and apart from being an extra thing to do, it just isn’t ideal having the server-side code squirt classes into the markup for purely presentational reasons. This is where the nth-child pseudo-class selector comes in. The server-side code creates a valid HTML table for the data, and the CSS then selects the odd rows with the following selector:

tr:nth-child(odd) td {
	background-color: #86B486;
}

View Example 2

The odd and even keywords are very handy in this situation – however you can also use a multiplier here. 2n would be equivalent to the keyword ‘odd’ 3n would select every third row and so on.

Browser support

Sadly, nth-child has pretty poor browser support. It is not supported in Internet Explorer 8 and has somewhat buggy support in some other browsers. Firefox 3.5 does have support. In some situations however, you might want to consider using JavaScript to add this support to browsers that don’t have it. This can be very useful if you are dealing with a Content Management System where you have no ability to change the server-side code to add classes into the markup.

I’m going to use jQuery in these examples as it is very simple to use the same CSS selector used in the CSS to target elements with jQuery – however you could use any library or write your own function to do the same job. In the CSS I have added the original class selector to the nth-child selector:

tr:nth-child(odd) td, tr.odd td {
	background-color: #86B486;
}

Then I am adding some jQuery to add a class to the markup once the document has loaded – using the very same nth-child selector that works for browsers that support it. 

<script src="http://code.jquery.com/jquery-latest.js"></script> 
 <script>
  $(document).ready(function(){
	$("tr:nth-child(odd)").addClass("odd");
  });
 </script>

View Example 3

We could just add a background colour to the element using jQuery, however I prefer not to mix that information into the JavaScript as if we change the colour on our table rows I would need to remember to change it both in the CSS and in the JavaScript.

Doing something different with the last element

So here’s another thing that we often deal with. You have a list of items all floated left with a right hand margin on each element constrained within a fixed width layout. If each element has the right margin applied the margin on the final element will cause the set to become too wide forcing that last item down to the next row as shown in the below example where I have used a grey border to indicate the fixed width.



Currently we have two ways to deal with this. We can put a negative right margin on the list, the same width as the space between the elements. This means that the extra margin on the final element fills that space and the item doesn’t drop down. 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>The last item is different</title>
<style type="text/css">
	body {
		padding: 40px;
		margin: 0;
		font: 0.9em Arial, Helvetica, sans-serif;
	}
	div#wrapper {
		width: 740px;
		float: left;
		border: 5px solid #ccc;
	}
	ul.gallery {
		margin: 0 -10px 0 0;
		padding: 0;
		list-style: none;
	}
	ul.gallery li {
		float: left;
		width: 240px;
		margin: 0 10px 10px 0;
	}
</style>
</head>
<body>
	<div id="wrapper">
		<ul class="gallery">
			<li><img src="xmas1.jpg" alt="baubles" /></li>
			<li><img src="xmas2.jpg" alt="star" /></li>
			<li><img src="xmas3.jpg" alt="wreath" /></li>
		</ul>
	</div>
</body>
</html>

View Example 4

The other solution will be to put a class on the final element and in the CSS remove the margin for this class. 

ul.gallery li.last {
	margin-right: 0;
}

This second solution may not be easy if the content is generated from server-side code that you don’t have access to change.

It could all be so different. In CSS3 we have marvellously common-sense selectors such as last-child, meaning that we can simply add rules for the last list item. 

ul.gallery li:last-child {
	margin-right: 0;
}

View Example 5

This removed the margin on the li which is the last-child of the ul with a class of gallery. No messing about sticking classes on the last item, or pushing the width of the item out wit a negative margin.

If this list of items repeated ad infinitum then you could also use nth-child for this task. Creating a rule that makes every 3rd element margin-less.

ul.gallery li:nth-child(3n) {
	margin-right: 0;
}

View Example 6



A similar example is where the designer has added borders to the bottom of each element – but the last item does not have a border or is in some other way different. Again, only a class added to the last element will save you here if you cannot rely on using the last-child selector.

Browser support for last-child

The situation for last-child is similar to that of nth-child, in that there is no support in Internet Explorer 8. However, once again it is very simple to replicate the functionality using jQuery. Adding our .last class to the last list item.

$("ul.gallery li:last-child").addClass("last");

We could also use the nth-child selector to add the .last class to every third list item.

$("ul.gallery li:nth-child(3n)").addClass("last");

View Example 7

Fun with forms

Styling forms can be a bit of a trial, made difficult by the fact that any CSS applied to the input element will effect text fields, submit buttons, checkboxes and radio buttons. As developers we are left adding classes to our form fields to differentiate them. In most builds all of my text fields have a simple class of text whereas I wouldn’t dream of adding a class of para to every paragraph element in a document.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Syling form fields</title>
<style type="text/css">
	body {
		padding: 40px;
		margin: 0;
		font: 0.9em Arial, Helvetica, sans-serif;
	}
	form div {
		clear: left;
		padding: 0 0 0.8em 0;
	}
	form label {
		float: left;
		width: 120px;
	}
	form .text, form textarea {
		border:1px solid #333;
		padding: 0.2em;
		width: 400px;
	}
	form .button {
		border: 1px solid #333;
		background-color: #eee;
		color: #000;
		padding: 0.1em;
	} 
	</style>
</head>
<body>
	<h1>Send your Christmas list to Santa</h1>
	<form method="post" action="" id="christmas-list">
		<div><label for="fName">Name</label>
		<input type="text" name="fName" id="fName" class="text" /></div>
		<div><label for="fEmail">Email address</label>
		<input type="text" name="fEmail" id="fEmail" class="text" /></div>
		<div><label for="fList">Your list</label>
		<textarea name="fList" id="fList" rows="10" cols="30"></textarea></div>
		<div><input type="submit" name="btnSubmit" id="btnSubmit" value="Submit" class="button" ></div>
	</form>
</body>
</html>

View Example 8

Attribute selectors provide a way of targeting elements by looking at the attributes of those elements. Unlike the other examples in this article which are CSS3 selectors, the attribute selector is actually a CSS2.1 selector – it just doesn’t get much use because of lack of support in Internet Explorer 6. Using attribute selectors we can write rules for text inputs and form buttons without needing to add any classes to the markup. For example after removing the text and button classes from my text and submit button input elements I can use the following rules to target them:

form input[type="text"] {
    border: 1px solid #333;
    padding: 0.2em;
    width: 400px;
}
form input[type="submit"]{
    border: 1px solid #333;
    background-color: #eee;
    color: #000;
    padding: 0.1em;
} 

View Example 9

Another problem that I encounter with forms is where I am using CSS to position my labels and form elements by floating the labels. This works fine as long as I want all of my labels to be floated, however sometimes we get a set of radio buttons or a checkbox, and I don’t want the label field to be floated. As you can see in the below example the label for the checkbox is squashed up into the space used for the other labels, yet it makes more sense for the checkbox to display after the text.



I could use a class on this label element however CSS3 lets me to target the label attribute directly by looking at the value of the for attribute.

label[for="fOptIn"] {
    float: none;
    width: auto;
}



Being able to precisely target attributes in this way is incredibly useful, and once IE6 is no longer an issue this will really help to clean up our markup and save us from having to create all kinds of special cases when generating this markup on the server-side.

Browser support

The news for attribute selectors is actually pretty good with Internet Explorer 7+, Firefox 2+ and all other modern browsers all having support. As I have already mentioned this is a CSS2.1 selector and so we really should expect to be able to use it as we head into 2010! Internet Explorer 7 has slightly buggy support and will fail on the label example shown above however I discovered a workaround in the Sitepoint CSS reference comments. Adding the selector label[htmlFor="fOptIn"] to the correct selector will create a match for IE7.

IE6 does not support these selector but, once again, you can use jQuery to plug the holes in IE6 support. The following jQuery will add the text and button classes to your fields and also add a checks class to the label for the checkbox, which you can use to remove the float and width for this element.

$('form input[type="submit"]').addClass("button");
$('form input[type="text"]').addClass("text");
$('label[for="fOptIn"]').addClass("checks");

View Example 10

The selectors I’ve used in this article are easy to overlook as we do have ways to achieve these things currently. As developers – especially when we have frameworks and existing code that cope with these situations – it is easy to carry on as we always have done. 

I think that the time has come to start to clean up our front and backend code and replace our reliance on classes with these more advanced selectors. With the help of a little JavaScript almost all users will still get the full effect and, where we are dealing with purely visual effects, there is definitely a case to be made for not worrying about the very small percentage of people with old browsers and no JavaScript. They will still receive a readable website, it may just be missing some of the finesse offered to the modern browsing experience.


title: Web Content Accessibility Guidelines—for People Who Haven't Read Them
year: 2017
author: Alan Dalton
author_slug: alandalton
published: 2017-12-03T00:00:00+00:00
url: https://24ways.org/2017/wcag-for-people-who-havent-read-them/
topic: code
contents:
I’ve been a huge fan of the Web Content Accessibility Guidelines 2.0 since the World Wide Web Consortium (W3C) published them, nine years ago. I’ve found them practical and future-proof, and I’ve found that they can save a huge amount of time for designers and developers. You can apply them to anything that you can open in a browser. My favourite part is when I use the guidelines to make a website accessible, and then attend user-testing and see someone with a disability easily using that website.
Today, the United Nations International Day of Persons with Disabilities, seems like a good time to re-read Laura Kalbag’s explanation of why we should bother with accessibility. That should motivate you to devour this article.
If you haven’t read the Web Content Accessibility Guidelines 2.0, you might find them a bit off-putting at first. The editors needed to create a single standard that countries around the world could refer to in legislation, and so some of the language in the guidelines reads like legalese. The editors also needed to future-proof the guidelines, and so some terminology—such as “time-based media” and “programmatically determined”—can sound ambiguous. The guidelines can seem lengthy, too: printing the guidelines, the Understanding WCAG 2.0 document, and the Techniques for WCAG 2.0 document would take 1,200 printed pages.
This festive season, let’s rip off that legalese and ambiguous terminology like wrapping paper, and see—in a single article—what gifts the Web Content Accessibility Guidelines 2.0 editors have bestowed upon us.
Can your users perceive the information on your website?
The first guideline has criteria that help you prevent your users from asking “What the **** is this thing here supposed to be?”
1.1.1 Text is the most accessible format for information. Screen readers—such as the “VoiceOver” setting on your iPhone or the “TalkBack” app on your Android phone—understand text better than any other format. The same applies for other assistive technology, such as translation apps and Braille displays. So, if you have anything on your webpage that’s not text, you must add some text that gives your user the same information. You probably know how to do this already; for example:

for images in webpages, put some alternative text in an alt attribute to tell your user what the image conveys to the user;
for photos in tweets, add a description to make the images accessible;
for Instagram posts, write a caption that conveys the photo’s information.

The alternative text should allow the user to get the same information as someone who can see the image. For websites that have too many images for someone to add alternative text to, consider how machine learning and Dynamically Generated Alt Text might—might—be appropriate.
You can probably think of a few exceptions where providing text to describe an image might not make sense. Remember I described these guidelines as “practical”? They cover all those exceptions:

User interface controls such as buttons and text inputs must have names or labels to tell your user what they do.
If your webpage has video or audio (more about these later on!), you must—at least—have text to tell the user what they are.
Maybe your webpage has a test where your user has to answer a question about an image or some audio, and alternative text would give away the answer. In that case, just describe the test in text so your users know what it is.
If your webpage features a work of art, tell your user the experience it evokes.
If you have to include a Captcha on your webpage—and please avoid Captchas if at all possible, because some users cannot get past them—you must include text to tell your user what it is, and make sure that it doesn’t rely on only one sense, such as vision.
If you’ve included something just as decoration, you must make sure that your user’s assistive technology can ignore it. Again, you probably know how to do this. For example, you could use CSS instead of HTML to include decorative images, or you could add an empty alt attribute to the img element. (Please avoid that recent trend where developers add empty alt attributes to all images in a webpage just to make the HTML validate. You’re better than that.)

(Notice that the guidelines allow you to choose how to conform to them, with whatever technology you choose. To make your website conform to a guideline, you can either choose one of the techniques for WCAG 2.0 for that guideline or come up with your own. Choosing a tried-and-tested technique usually saves time!)
1.2.1 If your website includes a podcast episode, speech, lecture, or any other recorded audio without video, you must include a transcription or some other text to give your user the same information. In a lot of cases, you might find this easier than you expect: professional transcription services can prove relatively inexpensive and fast, and sometimes a speaker or lecturer can provide the speech or lecture notes that they read out word-for-word. Just make sure that all your users can get the same information and the same results, whether they can hear the audio or not. For example, David Smith and Marco Arment always publish episode transcripts for their Under the Radar podcast. 
Similarly, if your website includes recorded video without audio—such as an animation or a promotional video—you must either use text to detail what happens in the video or include an audio version. Again, this might work out easier then you perhaps fear: for example, you could check to see whether the animation started life as a list of instructions, or whether the promotional video conveys the same information as the “About Us” webpage. You want to make sure that all your users can get the same information and the same results, whether they can see that video or not.
1.2.2 If your website includes recorded videos with audio, you must add captions to those videos for users who can’t hear the audio. Professional transcription services can provide you with time-stamped text in caption formats that YouTube supports, such as .srt and .sbv. You can upload those to YouTube, so captions appear on your videos there. YouTube can auto-generate captions, but the quality varies from impressively accurate to comically inaccurate. If you have a text version of what the people in the video said—such as the speech that a politician read or the bedtime story that an actor read—you can create a transcript file in .txt format, without timestamps. YouTube then creates captions for your video by synchronising that text to the audio in the video. If you host your own videos, you can ask a professional transcription service to give you .vtt files that you can add to a video element’s track element—or you can handcraft your own. (A quick aside: if your website has more videos than you can caption in a reasonable amount of time, prioritise the most popular videos, the most important videos, and the videos most relevant to people with disabilities. Then make sure your users know how to ask you to caption other videos as they encounter them.)
1.2.3 If your website has recorded videos that have audio, you must add an “audio description” narration to the video to describe important visual details, or add text to the webpage to detail what happens in the video for users who cannot see the videos. (I like to add audio files from videos to my Huffduffer account so that I can listen to them while commuting.) Maybe your home page has a video where someone says, “I’d like to explain our new TPS reports” while “Bill Lumbergh, division Vice President of Initech” appears on the bottom of the screen. In that case, you should add an audio description to the video that announces “Bill Lumbergh, division Vice President of Initech”, just before Bill starts speaking. As always, you can make life easier for yourself by considering all of your users, before the event: in this example, you could ask the speaker to begin by saying, “I’m Bill Lumbergh, division Vice President of Initech, and I’d like to explain our new TPS reports”—so you won’t need to spend time adding an audio description afterwards. 
1.2.4 If your website has live videos that have some audio, you should get a stenographer to provide real-time captions that you can include with the video. I’ll be honest: this can prove tricky nowadays. The Web Content Accessibility Guidelines 2.0 predate YouTube Live, Instagram live Stories, Periscope, and other such services. If your organisation creates a lot of live videos, you might not have enough resources to provide real-time captions for each one. In that case, if you know the contents of the audio beforehand, publish the contents during the live video—or failing that, publish a transcription as soon as possible.
1.2.5 Remember what I said about the recorded videos that have audio? If you can choose to either add an audio description or add text to the webpage to detail what happens in the video, you should go with the audio description.
1.2.6 If your website has recorded videos that include audio information, you could provide a sign language version of the audio information; some people understand sign language better than written language. (You don’t need to caption a video of a sign language version of audio information.)
1.2.7 If your website has recorded videos that have audio, and you need to add an audio description, but the audio doesn’t have enough pauses for you to add an “audio description” narration, you could provide a separate version of that video where you have added pauses to fit the audio description into.
1.2.8 Let’s go back to the recorded videos that have audio once more! You could add text to the webpage to detail what happens in the video, so that people who can neither read captions nor hear dialogue and audio description can use braille displays to understand your video.
1.2.9 If your website has live audio, you could get a stenographer to provide real-time captions. Again, if you know the contents of the audio beforehand, publish the contents during the live audio or publish a transcription as soon as possible.
(Congratulations on making it this far! I know that seems like a lot to remember, but keep in mind that we’ve covered a complex area: helping your users to understand multimedia information that they can’t see and/or hear. Grab a mince pie to celebrate, and let’s keep going.)
1.3.1 You must mark up your website’s content so that your user’s browser, and any assistive technology they use, can understand the hierarchy of the information and how each piece of information relates to the rest. Once again, you probably know how to do this: use the most appropriate HTML element for each piece of information. Mark up headings, lists, buttons, radio buttons, checkboxes, and links with the most appropriate HTML element. If you’re looking for something to do to keep you busy this Christmas, scroll through the list of the elements of HTML. Do you notice any elements that you didn’t know, or that you’ve never used? Do you notice any elements that you could use on your current projects, to mark up the content more accurately? Also, revise HTML table advanced features and accessibility, how to structure an HTML form, and how to use the native form widgets—you might be surprised at how much you can do with just HTML! Once you’ve mastered those, you can make your website much more usable for your all of your users.
1.3.2 If your webpage includes information that your user has to read in a certain order, you must make sure that their browser and assistive technology can present the information in that order. Don’t rely on CSS or whitespace to create that order visually. Check that the order of the information makes sense when CSS and whitespace aren’t formatting it. Also, try using the Tab key to move the focus through the links and form widgets on your webpage. Does the focus go where you expect it to? Keep this in mind when using order in CSS Grid or Flexbox.
1.3.3 You must not presume that your users can identify sensory characteristics of things on your webpage. Some users can’t tell what you’ve positioned where on the screen. For example, instead of asking your users to “Choose one of the options on the left”, you could ask them to “Choose one of our new products” and link to that section of the webpage.
1.4.1 You must not rely on colour as the only way to convey something to your users. Some of your users can’t see, and some of your users can’t distinguish between colours. For example, if your webpage uses green to highlight the products that your shop has in stock, you could add some text to identify those products, or you could group them under a sub-heading.
1.4.2  If your webpage automatically plays a sound for more than 3 seconds, you must make sure your users can stop the sound or change its volume. Don’t rely on your user turning down the volume on their computer; some users need to hear the screen reader on their computer, and some users just want to keep listening to whatever they were listening before your webpage interrupted them!
1.4.3 You should make sure that your text contrasts enough with its background, so that your users can read it. Bookmark Lea Verou’s Contrast Ratio calculator now. You can enter the text colour and background colour as named colours, or as RGB, RGBa, HSL, or HSLa values. You should make sure that:

normal text that set at 24px or larger has a ratio of at least 3:1;
bold text that set at 18.75px or larger has a ratio of at least 3:1;
all other text has a ratio of at least 4½:1.

You don’t have to do this for disabled form controls, decorative stuff, or logos—but you could!
1.4.4 You should make sure your users can resize the text on your website up to 200% without using their assistive technology—and still access all your content and functionality. You don’t have to do this for subtitles or images of text.
1.4.5 You should avoid using images of text and just use text instead. In 1998, Jeffrey Veen’s first Hot Design Tip said, “Text is text. Graphics are graphics. Don’t confuse them.” Now that you can apply powerful CSS text-styling properties, use CSS Grid to precisely position text, and choose from thousands of web fonts (Jeffrey co-founded Typekit to help with this), you pretty much never need to use images of text. The guidelines say you can use images of text if you let your users specify the font, size, colour, and background of the text in the image of text—but I’ve never seen that on a real website. Also, this doesn’t apply to logos.
1.4.6 Let’s go back to colour contrast for a second. You could make your text contrast even more with its background, so that even more of your users can read it. To do that, use Lea Verou’s Contrast Ratio calculator to make sure that:

normal text that is 24px or larger has a ratio of at least 4½:1;
bold text that 18.75px or larger has a ratio of at least 4½:1;
all other text has a ratio of at least 7:1.

1.4.7 If your website has recorded speech, you could make sure there are no background sounds, or that your users can turn off any background sounds. If that’s not possible, you could make sure that any background sounds that last longer than a couple of seconds are at least four times quieter than the speech. This doesn’t apply to audio Captchas, audio logos, singing, or rapping. (Yes, these guidelines mention rapping!)
1.4.8 You could make sure that your users can reformat blocks of text on your website so they can read them better. To do this, make sure that your users can:

specify the colours of the text and the background, and
make the blocks of text less than 80-characters wide, and 
align text to the left (or right for right-to-left languages), and 
set the line height to 150%, and 
set the vertical distance between paragraphs to 1½ times the line height of the text, and 
resize the text (without using their assistive technology) up to 200% and still not have to scroll horizontally to read it.

By the way, when you specify a colour for text, always specify a colour for its background too. Don’t rely on default background colours!
1.4.9 Let’s return to images of text for a second. You could make sure that you use them only for decoration and logos.
Can users operate the controls and links on your website?
The second guideline has criteria that help you prevent your users from asking, “How the **** does this thing work?”
2.1.1 You must make sure that you users can carry out all of your website’s activities with just their keyboard, without time limits for pressing keys. (This doesn’t apply to drawing or anything else that requires a pointing device such as a mouse.) Again, if you use the most appropriate HTML element for each piece of information and for each form element, this should prove easy.
2.1.2 You must make sure that when the user uses the keyboard to focus on some part of your website, they can then move the focus to some other part of your webpage without needing to use a mouse or touch the screen. If your website needs them to do something complex before they can move the focus elsewhere, explain that to your user. These “keyboard traps” have become rare, but beware of forms that move focus from one text box to another as soon as they receive the correct number of characters.
2.1.3 Let’s revisit making sure that you users can carry out all of your website’s activities with just their keyboard, without time limits for pressing keys. You could make sure that your user can do absolutely everything on your website with just the keyboard.
2.2.1 Sometimes people need more time than you might expect to complete a task on your website. If any part of your website imposes a time limit on a task, you must do at least one of these: 

let your users turn off the time limit before they encounter it; or
let your users increase the time limit to at least 10 times the default time limit before they encounter it; or
warn your users before the time limit expires and give them at least 20 seconds to extend it, and let them extend it at least 10 times.

Remember: these guidelines are practical. They allow you to enforce time limits for real-time events such as auctions and ticket sales, where increasing or extending time limits wouldn’t make sense. Also, the guidelines allow you to enforce a maximum time limit of 20 hours. The editors chose 20 hours because people need to go to sleep at some stage. See? Practical!
2.2.2 In my experience, this criterion remains the least well-known—even though some users can only use websites that conform to it. If your website presents content alongside other content that can distract users by automatically moving, blinking, scrolling, or updating, you must make sure that your users can:

pause, stop, or hide the other content if it’s not essential and lasts more than 5 seconds; and
pause, stop, hide, or control the frequency of the other content if it automatically updates.

It’s OK if your users miss live information such as stock price updates or football scores; you can’t do anything about that! Also, this doesn’t apply to animations such as progress bars that you put on a website to let all users know that the webpage isn’t frozen.
(If this one sounds complex, just add a pause button to anything that might distract your users.)
2.2.3 Let’s go back to time limits on tasks on your website. You could   make your website even easier to use by removing all time limits except those on real-time events such as auctions and ticket sales. That would mean your user wouldn’t need to interact with a timer at all.
2.2.4 You could let your users turn off all interruptions—server updates, promotions, and so on—apart from any emergency information.
2.2.5 This is possibly my favourite of these criteria! After your website logs your user out, you could make sure that when they log in again, they can continue from where they were without having lost any information. Do that, and you’ll be on everyone’s Nice List this Christmas.
2.3.1 You must make sure that nothing flashes more than three times a second on your website, unless you can make sure that the flashes remain below the acceptable general flash and red flash thresholds…
2.3.2 …or you could just make sure that nothing flashes more than three times per second on your website. This is usually an easier goal.
2.4.1 You must make sure that your users can jump past any blocks of content, such as navigation menus, that are repeated throughout your website. You know the drill here: using HTML’s sectioning elements such as header, nav, main, aside, and footer allows users with assistive technology to go straight to the content they need, and adding “Skip Navigation” links allows everyone to get to your main content faster.
2.4.2 You must add a proper title to describe each webpage’s topic. Your webpage won’t even validate without a title element, so make it a useful one.
2.4.3 If your users can focus on links and native form widgets, you must make sure that they can focus on elements in an order that makes sense.
2.4.4 You must make sure that your users can understand the purpose of a link when they read:

the text of the link; or
the text of the paragraph, list item, table cell, or table header for the cell that contains the link; or
the heading above the link.

You don’t have to do that for games and quizzes.
2.4.5 You should give your users multiple ways to find any webpage within a set of webpages. Add site-wide search and a site map and you’re done!
This doesn’t apply for a webpage that is part of a series of actions (like a shopping cart and checkout flow) or to a webpage that is a result of a series of actions (like a webpage confirming that the user has bought what was in the shopping cart).
2.4.6 You should help your users to understand your content by providing:

headings that describe the topics of you content;
labels that describe the purpose of the native form widgets on the webpage.

2.4.7 You should make sure that users can see which element they have focussed on. Next time you use your website, try hitting the Tab key repeatedly. Does it visually highlight each item as it moves focus to it? If it doesn’t, search your CSS to see whether you’ve applied outline: 0; to all elements—that’s usually the culprit. Use the :focus pseudo-element to define how elements should appear when they have focus.
2.4.8 You could help your user to understand where the current webpage is located within your website. Add “breadcrumb navigation” and/or a site map and you’re done.
2.4.9 You could make links even easier to understand, by making sure that your users can understand the purpose of a link when they read the text of the link. Again, you don’t have to do that for games and quizzes.
2.4.10 You could use headings to organise your content by topic. 
Can users understand your content?
The third guideline has criteria that help you prevent your users from asking, “What the **** does this mean?”
3.1.1 Let’s start this section with the criterion that possibly takes the least time to implement; you must make sure that the user’s browser can identify the main language that your webpage’s content is written in. For a webpage that has mainly English content, use <html lang="en">. 
3.1.2 You  must specify when content in another language appears in your webpage, like so: <q>I wish you a <span lang="fr">Joyeux Noël</span>.</q>. You don’t have to do this for proper names, technical terms, or words that you can’t identify a language for. You also don’t have to do it for words from a different language that people consider part of the language around those words; for example, <q>Come to our Christmas rendezvous!</q> is OK.
3.1.3 You could make sure that your users can find out the meaning of any unusual words or phrases, including idioms like “stocking filler” or “Bah! Humbug!” and jargon such as “VoiceOver” and “TalkBack”. Provide a glossary or link to a dictionary.
3.1.4 You could make sure that your users can find out the meaning of any    abbreviation. For example, VoiceOver pronounces “Xmas” as “Smas” instead of “Christmas”. Using the abbr element and linking to a glossary can help. (Interestingly, VoiceOver pronounces “abbr” as “abbreviation”!)
3.1.5 Do your users need to be able to read better than a typically educated nine-year-old, to read your content (apart from proper names and titles)? If so, you could provide a version that doesn’t require that level of reading ability, or you could provide images, videos, or audio to explain your content. (You don’t have to add captions or audio description to those videos.)
3.1.6 You could make sure that your users can access the pronunciation of any word in your content if that word’s meaning depends on its pronunciation. For example, the word “close” could have one of two meanings, depending on pronunciation, in a phrase such as, “Ready for Christmas? Close now!”
3.2.1 Some users need to focus on elements to access information about them. You must make sure that focusing on an element doesn’t trigger any major changes, such as opening a new window, focusing on another element, or submitting a form.
3.2.2 Webpages are easier for users when the controls do what they’re supposed to do. Unless you have warned your users about it, you must make sure that changing the value of a control such as a text box, checkbox, or drop-down list doesn’t trigger any major changes, such as opening a new window, focusing on another element, or submitting a form.
3.2.3 To help your users to find the content they want on each webpage, you should put your navigation elements in the same place on each webpage. (This doesn’t apply when your user has changed their preferences or when they use assistive technology to change how your content appears.) 
3.2.4 When a set of webpages includes things that have the same functionality on different webpages, you should name those things consistently. For example, don’t use the word “Search” for the search box on one webpage and “Find” for the search box on another webpage within that set of webpages.
3.2.5 Let’s go back to major changes, such as a new window opening, another element taking focus, or a form being submitted. You could make sure that they only happen when users deliberately make them happen, or when you have warned users about them first. For example, you could give the user a button for updating some content instead of automatically updating that content. Also, if a link will open in a new window, you could add the words “opens in new window” to the link text.
3.3.1 Users make mistakes when filling in forms. Your website must identify each mistake to your user, and must describe the mistake to your users in text so that the user can fix it. One way to identify mistakes reliably to your users is to set the aria-invalid attribute to true in the element that has a mistake. That makes sure that users with assistive technology will be alerted about the mistake. Of course, you can then use the [aria-invalid="true"] attribute selector in your CSS to visually highlight any such mistakes. Also, look into how certain attributes of the input element such as required, type, and list can help prevent and highlight mistakes.
3.3.2 You must include labels or instructions (and possibly examples) in your website’s forms, to help your users to avoid making mistakes. 
3.3.3 When your user makes a mistake when filling in a form, your webpage should suggest ways to fix that mistake, if possible. This doesn’t apply in scenarios where those suggestions could affect the security of the content.
3.3.4 Whenever your user submits information that:

has legal or financial consequences; or
affects information that they have previously saved in your website; or
is part of a test

…you should make sure that they can:

undo it; or
correct any mistakes, after your webpage checks their information; or
review, confirm, and correct the information before they finally submit it.

3.3.5 You could help prevent your users from making mistakes by providing obvious, specific help, such as examples, animations, spell-checking, or extra instructions.
3.3.6 Whenever your user submits any information, you could make sure that they can:

undo it; or
correct any mistakes, after your webpage checks their information; or
review, confirm, and correct the information before they finally submit it.

Have you made your website robust enough to work on your users’ browsers and assistive technologies?
The fourth and final guideline has criteria that help you prevent your users from asking, “Why the **** doesn’t this work on my device?”
4.1.1 You must make sure that your website works as well as possible with current and future browsers and assistive technology. Prioritise  complying with web standards instead of relying on the capabilities of currently popular devices and browsers. Web developers didn’t expect their users to be unwrapping the Wii U Browser five years ago—who knows what browsers and assistive technologies our users will be unwrapping in five years’ time? Avoid hacks, and use the W3C Markup Validation Service to make sure that your HTML has no errors.
4.1.2 If you develop your own user interface components, you must make their name, role, state, properties, and values available to your user’s browsers and assistive technologies. That should make them almost as accessible as standard HTML elements such as links, buttons, and checkboxes.
“…and a partridge in a pear tree!”
…as that very long Christmas song goes. We’ve covered a lot in this article—because your users have a lot of different levels of ability. Hopefully this has demystified the Web Content Accessibility Guidelines 2.0 for you. Hopefully you spotted a few situations that could arise for users on your website, and you now know how to tackle them. 
To start applying what we’ve covered, you might like to look at Sarah Horton and Whitney Quesenbery’s personas for Accessible UX. Discuss the personas, get into their heads, and think about which aspects of your website might cause problems for them. See if you can apply what we’ve covered today, to help users like them to do what they need to do on your website.
How to know when your website is perfectly accessible for everyone
LOL! There will never be a time when your website becomes perfectly accessible for everyone. Don’t aim for that. Instead, aim for regularly testing and making your website more accessible.
Web Content Accessibility Guidelines (WCAG) 2.1
The W3C hope to release the Web Content Accessibility Guidelines (WCAG) 2.1 as a “recommendation” (that’s what the W3C call something that we should start using) by the middle of next year. Ten years may seem like a long time to move from version 2.0 to version 2.1, but consider the scale of the task: the editors have to update the guidelines to cover all the new ways that people interact with new technologies, while keeping the guidelines backwards-compatible. Keep an eye out for 2.1!
You’ll go down in history
One last point: I’ve met a surprising number of web designers and developers who do great work to make their websites more accessible without ever telling their users about it. Some of your potential customers have possibly tried and failed to use your website in the past. They probably won’t try again unless you let them know that things have improved. A quick Twitter search for your website’s name alongside phrases like “assistive technology”, “doesn’t work”, or “#fail” can let you find frustrated users—so you can tell them about how you’re making your website more accessible. Start making your websites work better for everyone—and please, let everyone know.


title: Design Systems and Hybrids
year: 2017
author: Jina Anne
author_slug: jina
published: 2017-12-22T00:00:00+00:00
url: https://24ways.org/2017/design-systems-and-hybrids/
topic: process
contents:
The other day on Twitter, I saw a thread started by Dorian Taylor about why design systems are so hot right now. In the thread, he made the case that they’ve been around for ages and some folks were just slow to catch up. It was an interesting thread, and not the first time I’ve seen folks discuss this. “Design systems are so hot right now” was even used recently in this very publication.
And yes it’s true that they’ve been around for ages. Design artefact collectors’ obsession with reprints of old graphic standards manuals of the past are a reminder. Sometimes old things become new again, either through a rediscovery or awakening (wow, that sounds really deep). But I think that’s definitely what happened here.
Some very opinionated answers that come to mind for me are:

The need for them has increased with the needs of software development. With the increasing number of devices (phones, tablets, watches, etc.), scaling design has required the need to double down on systems thinking and processes.
Investments with huge cost-saving returns. The time investment it takes to onboard new people as you staff up large teams (and the time it takes to fix bugs and inconsistencies) could be better spent building up a system that lets you ship at a faster pace. It also gives you more time to focus on the bigger picture instead of what color a button border is.
If you do have to onboard new designers, the design system is a great educational resource to get up to speed quickly on your organization’s design principles, materials/tools, and methods.


“Here’s the simple truth: you can’t innovate on products without first innovating the way you build them.”
— Alex Schleifer, The Way We Build

These are just some of the reasons. But there is another answer, and a personal conclusion that I’ve reached. It relates to the way I work and what I love working on, but I don’t see it talked about much.
Hybrids Have a Home
I’m a hybrid designer. I code in HTML & CSS (with a preference for Sass). But I don’t call myself a frontend developer. I used to back in the day (I was a UI frontend developer at Apple over a decade ago, but all I wrote was HTML & CSS). I identify with designer because that’s my training and interest, but the ideas of what a frontend developer can do has changed quite a ton over the years. Setting things up in build tools and processes are not my skill. And I know a lot of designers who share this experience with me.
There are also hybrid developers who identify as developers, but have excellent design skills. Buddies like my pal Brandon Ferrua who was on my team at Salesforce is a great example of this. And we worked fantastically together.
Sometimes, companies don’t know how to deal with hybrids. I’ve been told to choose a side, and have even been made to join a development team simply because I could code my designs (and then when I couldn’t deliver the same type of code my teammates could, and I felt like I wasn’t able to use my talents in the most effective way).
There are a lot more folks out there I know of who identify as a hybrid, and many have found ourselves working on design systems. Una Kravets recently had a thread discussing this as well. At Clarity, this came up a lot in hallway conversations, breaks, and the after parties. I think that this job is a haven for folks who often find themselves in the middle.
For companies that get it, these people find joy in getting to use a wider variety of skills and being bridges; advocates that can speak to designers and developers, helping bring  unity to an organization. They can wireframe, throw together a prototype, create color systems, architect naming conventions for design tokens. Design systems are their perfect home. I think this has contributed to the uptick in discussions and interest on this subject (in addition to the team- and company-focused reasons).
Keep Design Systems Teams Cross-Functional
Speaking of teams, something some larger companies fall prey to is creating walls and silos where they need not be. If you place all your visual designers in one place, all your coders in another, and so on, you’re not doing yourselves any favors. Meanwhile, your hybrids are caught in the middle not knowing exactly where they belong. Design systems teams should have representatives (whether on a core team, or a virtual/federated team) that bring different skillsets. Design, code, writing, accessibility, product management, and so on. You’ll have a stronger vision on where to take your design system and to make it succeed. Siloing defeats the whole purpose of what design systems are meant for.
Happy holidays, and may the force be with you.
Further Reading

Why Design Systems Fail
Design Systems are for People
Design Systems Handbook


title: Levelling Up for Junior Developers
year: 2017
author: Dean Hume
author_slug: deanhume
published: 2017-12-05T00:00:00+00:00
url: https://24ways.org/2017/levelling-up-for-junior-developers/
topic: code
contents:
If you are a junior developer starting out in the web industry, things can often seem a little daunting. There are so many things to learn, and as soon as you’ve learnt one framework or tool, there seems to be something new out there.
I am lucky enough to lead a team of developers building applications for the web. During a recent One to One meeting with one of our junior developers, he asked me about a learning path and the basic fundamentals that every developer should know. After a bit of digging around, I managed to come up with a (not so exhaustive) list of principles that was shared with him.

In this article, I will share the list with you, and hopefully help you level up from junior developer and become a better developer all round. This list doesn’t focus on an particular programming language, but rather coding concepts as a whole. The idea behind this list is that whether you are a front-end developer, back-end developer, full stack developer or just a curious one, these principles apply to everyone that writes code. 
I have tried to be technology agnostic, so that you can use these tips to guide you, whatever your tech stack might be.
Without any further ado and in no particular order, let’s get started.
Refactoring code like a boss
The Boy Scouts have a rule that goes “always leave the campground cleaner than you found it.” This rule can be applied to code too and ensures that you leave code cleaner than you found it. As a junior developer, it’s almost certain that you will either create or come across older code that could be improved. The resources below are a guide that will help point you in the right direction.

My favourite book on this subject has to be Clean Code by Robert C. Martin. It’s a must read for anyone writing code as it helps you identify bad code and shows you techniques that you can use to improve existing code.
If you find that in your day to day work you deal with a lot of legacy code, Improving Existing Technology through Refactoring is another useful read.
Design Patterns are a general repeatable solution to a commonly occurring problem in software design. My friend and colleague Ranj Abass likes to refer to them as a “common language” that helps developers discuss the way that we write code as a pattern. My favourite book on this subject is Head First Design Patterns which goes right back to the basics. Another great read on this topic is Refactoring to Patterns.
Working Effectively With Legacy Code is another one that I found really valuable.

Improving your debugging skills
A solid understanding of how to debug code is a must for any developer. Whether you write code for the web or purely back-end code, the ability to debug will save you time and help you really understand what is going on under the hood.

If you write front-end code for the web, one of my favourite resources to help you understand how to debug code in Chrome can be found on the Chrome Dev Tools website. While some of the tips are specific to Chrome, these techniques apply to any modern browser of your choice.
At Settled, we use Node.js for much of our server side code. Without a doubt, our most trusted IDE has to be Visual Studio Code and the built-in debuggers are amazing. Regardless of whether you use Node.js or not, there are a number of plugins and debuggers that you can use in the IDE. I recommend reading the website of your favourite IDE for more information. 
As a side note, it is worth mentioning that Chrome Developer Tools actually has functionality that allows you to debug Node.js code too. This makes it a seamless transition from front-end code to server-side code debugging.
The Debugging Mindset is an informative online article by Devon H. O’Dell and discusses the the psychology of learning strategies that lead to effective problem-solving skills. 

A good understanding of relational databases and NoSQL databases
Almost all developers will need to persist data at some point in their career. Even if you don’t write SQL queries in your day to day job, a solid understanding of how they work will help you become a better developer.

If you are a complete newbie when it comes to databases, I recommend checking out Code Academy. They offer a free online course that can help you get your head around how relational databases work. The course is quite basic, but is a useful hands-on approach to learning this topic.
This article provides a great explainer for the difference between the SQL and NoSQL databases, and this  Stackoverflow answer goes a little deeper into the subject of the two database types.
If you’d like to learn more about NoSQL queries, I would recommend starting with this article on MongoDB queries. Unfortunately, there isn’t one overall course as most NoSQL databases have their own syntax. 

You may also have noticed that I haven’t included other types of databases such as Graph or In-memory; it’s worth focussing on the basics before going any deeper.
Performance on the web
If you build for the web today, it is important to understand how the browser receives and renders the content that you send it. I am pretty passionate about Web Performance, and hope that everyone can learn how to make websites faster and more efficient. It can be fun at the same time!

Steve Souders High Performance Websites is the godfather of web performance books. While it was created a few years ago and many of the techniques might have changed slightly, it is the original book on the subject and set up many of the ground rules that we know about web performance today.
A free online resource on this topic is the Google Developers website. The site is an up to date guide on the best web performance techniques for your site. It is definitely worth a read.
The network plays a key role in delivering data to your users, and it plays a big role in performance on the web. A fantastic book on this topic is Ilya Grigorik’s High Performance Browser Networking. It is also available to read online at hpbn.co.

Understand the end to end architecture of your software project
I find that one of the best ways to improve my knowledge is to learn about the architecture of the software at the company I work at. It gives you a good understanding as to why things are designed the way they are, why certain decisions were made, and gives you an understanding of how you might do things differently with hindsight.
Try and find someone more senior, such as a Technical Lead or Software Architect, at your company and ask them to explain the overall architecture and draw a few high-level diagrams for you. Not to mention that they will be impressed with your willingness to learn.

I recommend reading Clean Architecture: A Craftsman’s Guide to Software Structure and Design for more detail on this subject.
Far too often, software projects can be over-engineered and over-architected, it is worth reading Just Enough Software Architecture. The book helps developers understand how the smallest of changes can affect the outcome of your software architecture.

How are things deployed
A big part of creating software is actually shipping it! How is the software at your company released into the wild? Does your company do Continuous Integration? Continuous Deployment?

Even if you answered no to any of these questions, it is worth finding someone with the knowledge in your company to explain these things to you. If it is not already documented, perhaps you could start a wiki to document everything you’re learning about the system - this is a great way to level up and be appreciated and invaluable.
A streamlined deployment process is a beautiful thing, and understanding how they work can help you grow your knowledge as a developer. 
Continuous Integration is a practical read on the ins and outs of implementing this deployment technique.
Docker is another great tool to use when it comes to software deployment. It can be tricky at first to wrap your head around, but it is definitely worth learning about this great technology. The documentation on the website will teach and guide you on how to get started using Docker.

Writing Tests
Testing is an essential tool in the developer bag of skills. They help you to make big refactoring changes to your code, and feel a lot more confident knowing that your changes haven’t broken anything. There are so many benefits to testing, which make it so important for developers at every level to become acquainted with it/them.

The book that started it all for me was Roy Osherove’s The Art of Unit Testing. The code in the book is written in C#, but the principles apply to every language. It’s a great, easy-to-understand read.
Another great read is How Google Tests Software and covers exactly what it says on the tin. It covers many different testing techniques such as exploratory, black box, white box, and acceptance testing and really helps you understand how large organisations test their code.

Soft skills
Whilst reading through this article, you’ve probably noticed that a large chunk of it focusses on code and technical ability. Without a doubt, I’d say that it is even more important to be a good teammate. If you look up the definition of soft skills in the dictionary, it is defined as “personal attributes that enable someone to interact effectively and harmoniously with other people” and I think that it sums this up perfectly. Working on your “soft skills” is something that can truly help you level up in your career. You may be the world’s greatest coder, but if you colleagues can’t get along with you, your coding skills won’t matter!
While you may not learn how to become the perfect co-worker overnight, I really try and live by the motto “don’t be an arsehole”. Think about how you like to be treated and then try and treat your co-workers with the same courtesy and respect. The next time you need to make a decision at work, ask yourself “is this something an arsehole would do”? If you answered yes to that question, you probably shouldn’t do it!
Summary
Levelling up as a junior developer doesn’t have to be scary. Focus on the fundamentals and they should hold you in good stead, regardless of the new things that come along. Software engineering is built on these great principles that have stood the test of time.
Whilst researching for this article, I came across a useful Github repo that is worth mentioning. Things Every Programmer Should Know is packed with useful information. I have to admit, I didn’t know everything on there!
I hope that you have found this list helpful. Some of the topics I have mentioned might not be relevant for you at this stage in your career, but should give a nudge in the right direction. After all, knowledge is power!
If you are a junior developer reading this article, what would you add to it?


title: Designing a Remote Project
year: 2017
author: Suzanna Haworth
author_slug: suzannahaworth
published: 2017-12-06T00:00:00+00:00
url: https://24ways.org/2017/designing-a-remote-project/
topic: business
contents:
I came across an article recently, which I have to admit made my blood boil a little. Yes, I know it’s the season of goodwill and all that, and I’m going to risk sounding a little Scrooge-like, but I couldn’t help it. It was written by someone who’d tried out ‘telecommuting’ (big sigh) a.k.a. remote or distributed working. They’d tested it in their company and decided it didn’t work. 
Why did it enrage me so much? Well, this person sounded like they’d almost set it up to fail. To them, it was the latest buzzword, and they wanted to offer their employees a ‘perk’. But it was going to be risky, because, well, they just couldn’t trust their employees not to be lazy and sit around in their pyjamas at home, watching TV, occasionally flicking their mousepad to ‘appear online’. Sounds about right, doesn’t it?
Well, no. This attitude towards remote working is baked in the past, where working from one office and people all sitting around together in a cosy circle singing kum-by-yah* was a necessity not an option. We all know the reasons remote working and flexibility can happen more easily now: fast internet, numerous communication channels, and so on. But why are companies like Yahoo! and IBM backtracking on this? Why is there still such a negative perception of this way of working when it has so much real potential for the future?
*this might not have ever really happened in an office.
So what is remote working? It can come in various formats. It’s actually not just the typical office worker, working from home on a specific day. The nature of digital projects has been changing over a number of years. In this era where organisations are squeezing budgets and trying to find the best value wherever they can, it seems that the days of whole projects being tackled by one team, in the same place, is fast becoming the past. What I’ve noticed more recently is a much more fragmented way of putting together a project – a mixture of in-house and agency, or multiple agencies or organisations, or working with an offshore team. In the past we might have done the full integrated project from beginning to end, now, it’s a piece of the pie. 
Which means that everyone is having to work with people who aren’t sat next to them even more than before. Whether that’s a freelancer you’re working with who’s not in the office, an offshore agency doing development or a partner company in another city tackling UX… the future is looking more and more like a distributed workplace.
So why the negativity, man?
As I’ve seen from this article, and from examples of large corporations changing their entire philosophy away from remote working, there’s a lot of negativity towards this way of working. Of course if you decide to let everyone work from home when they want, set them off and then expect them all to check in at the right time or be available 24/7 it’s going to be a bit of a mess.  Equally if you just jump into work with a team on the other side of the world without any setup, should you expect anything less than a problematic project?
Okay, okay so what about these people who are going to sit on Facebook all day if we let them work from home? It’s the age old response to the idea of working from home. I can’t see the person, so how do I know what they are doing?
This comes up regularly as one of the biggest fears of letting people work remotely. There’s also the perceived lack of productivity and distractions at home. The limited collaboration and communication with distributed workers. The lack of availability. The lower response times.  
Hang on a second, can’t these all still be problems even if you’ve got your whole team sat in the same place? “They won’t focus on work.” How many people will go on Facebook or Twitter whilst sat in an office? “They won’t collaborate as much.” How many people sit in the office with headphones on to block out distractions? I think we have to move away from the idea that being sat next to people automatically makes them work harder. If the work is satisfying, challenging, and relevant to a person – surely we should trust them to do it, wherever they are sat?
There’s actually a lot of benefits to remote working, and having distributed teams. Offering this as a way of working can attract and retain employees, due to the improved flexibility. There can actually be fewer distractions and disruptions at home, which leads to increased productivity. To paraphrase Jason Fried in his talk ‘Why work doesn’t happen at work’, at home there are voluntary distractions where you have to choose to distract yourself with something. At the office these distractions become involuntary. Impromptu meetings and people coming to talk to you all the time are actually a lot more disruptive. Often, people find it easier to focus away from the office environment. 
There’s also the big benefit for a lot of people of the time saved commuting. The employee can actually do a lot that’s beneficial to them in this time, rather than standing squeezed into people’s armpits on public transport. Hence increased job satisfaction. With a distributed team, say if you’re working with an off-shore team, there could be a wider range of talent to pick from and it also encourages diversity. There can be a wider range of cultural differences and opinions brought to a project, which encourages more diverse ways of thinking.
Tackling the issues - or, how to set up a project with a remote team
But that isn’t to say running projects with a distributed team or being a remote worker is easy, and can just happen, like that. It needs work – and good groundwork – to ensure you don’t set it up to fail. So how do you help create a smoother remote project?
Start with trust
First of all, the basis of the team needs to be trust. Yes I’m going to sound a little like a cheesy, self-help guru here (perhaps in an attempt to seem less Scrooge-like and inject some Christmas cheer) but you do need to trust the people working remotely as well as them trusting you. This extends to a distributed team. You can’t just tell the offshore team what to do, and micromanage them, scared they won’t do what you want, how you want it because you can’t see them. You need to give them ownership and let them manage the tasks. Remember, people are less likely to criticise their own work. Make them own the work and they are more likely to be engaged and productive.
Set a structure
Distributed teams and remote workers can fail when there is no structure – just as much as teams sitting together fail without it too. It’s not so much setting rules, as having a framework to work within. Eliminate blockers before they happen. Think about what could cause issues for the team, and think of ways to solve this. For example, what do you do if you won’t be able to get hold of someone for a few hours because of a time difference? Put together a contingency, e.g. is there someone else on your time zone you could go to with queries after assessing the priority? Would it be put aside until that person is back in? Define team roles and responsibilities clearly. Sit down at the beginning of the project and clearly set out expectations. Also ask the team, what are their expectations of you?
There won’t be a one size fits all framework either. Think about your team, the people in it, the type of project you’re working with, the type of client and stakeholder. This should give you an idea of what sort of communications you’ll need on the project. Daily calls, video calls, Slack channels, the choice is yours.
Decide on the tools
To be honest, I could spend hours talking about the different tools you can use for communication. But you know them, right? And in the end it’s not the tool that’s important here - it’s the communication that’s being done on the tool. Tools need to match the type of communications needed for your team. One caveat here though, never rely solely on email! Emails are silos, and can become beasts to manage communications on.
Transparency in communication
Good communication is key. Make sure there are clear objectives for communication. Set up one time during the week where those people meet together, discuss all the work during that week that they’ve done. If decisions are made between team members who are together, make sure everyone knows what these are. But try to make collective decisions where you can, when it doesn’t impact on people’s time.
Have a face-to-face kick off
Yes, I know this might seem to counter my argument, but face-to-face comms are still really important. If it’s feasible, have an in-person meeting to kick off your project, and to kick off your team working together. An initial meeting, to break the ice, discuss ways of working, set the goals, can go a long way to making working with distributed teams successful. If this is really not viable, then hold a video call with the team. Try to make this a little more informal. I know, I know, not the dreaded cringey icebreakers… but something to make everyone relax and get to know each other is really important. Bring everybody together physically on a regular basis if you can, for example with quarterly meetings. You’ve got to really make sure people still feel part of a team, and it often takes a little more work with a remote team. Connect with new team members, one-on-one first, then you can have more of a ‘remote’ relationship. 
Get visual
Visual communication is often a lot better tool to use than just a written sentence, and can help bring ideas to life. Encourage people to sketch things, take a photo and add this to your written communications. Or use a mockup tool to sketch ideas.
But what about Agile projects?
The whole premise of Agile projects is to have face-to-face contact I hear you cry. The Agile Manifesto itself states “The most efficient and effective method of conveying information to and within a development team is face-to-face conversation”. However, this doesn’t mean the death of remote working. In fact loads of successful companies still run Agile projects, whilst having a distributed team. With all the collaborative tools you can use for centralising code, tracking tasks, visualising products, it’s not difficult to still communicate in a way that works. Just think about how to replicate the principles of Agile remotely - working together daily, a supportive environment, trust, and simplicity. How can you translate these to your remote or distributed team? 
One last thought to leave you with before you run off to eat your mince pies (in your pyjamas, whilst working). A common mistake in working with a remote project team or working remotely yourself, is replacing distance with time. If you’re away from the office you think you need to always be ‘on’ – messaging, being online, replying to requests. If you have a distributed team, you might think a lot of meetings, calls, and messages will be good to foster communication. But don’t overload these meetings, calls, and communication. This can be disruptive in itself. Give people the gift of some uninterrupted time to actually do some work, and not feel like they have to check in every second.


title: Designing for Mobile Performance
year: 2017
author: Mustafa Kurtuldu
author_slug: mustafakurtuldu
published: 2017-12-18T00:00:00+00:00
url: https://24ways.org/2017/designing-for-mobile-performance/
topic: ux
contents:
Last year, some colleagues at Google ran a research study titled “The Need for Mobile Speed” to find out what the impact of performance and perception of speed had on the way people use the web on their mobile devices. 
That’s not a trivial distinction; when considering performance, how fast something feels is often more important than how fast it actually is. When dealing with sometimes underpowered mobile devices and slow mobile networks, designing experiences that feel fast is exceptionally important.
One of the most startling numbers we found in the study was that 53% of mobile site visits are abandoned if pages take longer than 3 seconds to load.
We wanted to find out more, so following on from this study, we conducted research to define what the crucial elements of speed are. We took into consideration the user experience (UX), overall perception of speed, and how differing contexts the user finds themselves in can alter how fast a user thinks something loaded.
To understand speed and load times first we must understand that user mobile web behaviour is broken down into three buckets;

Intention
Location
State of mind

Let’s look at each of those in turn.
Intention
Users browse sites on a mobile device for many different reasons. To be able to effectively design a performant user experience for them, it’s important to understand what those reasons might be. When asked to describe their reason for visiting a site, approximately 30% of people asked by the study claimed that they were simply browsing without a particular purpose in mind. Looking deeper, we found that this number increased slightly (34%) for retail sites. 30% said they were just there to find out some information for a future task or action, such as booking a flight.
Interestingly, the research shows that users are actually window shopping using their mobile browser. Only 29% actually said they had a specific goal or intent in mind, and this number increases significantly for financial services like banking sites (57%). This goes against a traditionally held view of users wanting to perform simple actions efficiently on their mobile device. Sure, some users are absolutely doing that, but many are just browsing around without a goal in mind, just like they would on a desktop browser.
This gives great insight into the user’s intentions. It tells us that users are actively using sites on their mobile, but a large majority do not intend to do anything instantly. There’s no goal they’re under pressure to achieve. If a site’s performance is lousy or janky, this will only reaffirm to the user to that they can hold off on completing a task, so they might just give up. 
However, if a site is quick to load, sophisticated in expressing its value proposition quickly, and enables the user to perform their actions seamlessly, then turning that “browsing user” into a “buying user” becomes all that much easier. When the user has no goal, there’s more opportunity to convert, and you stand a greater chance of doing that if the performance is good enough so they stick around.
Location
Obviously, mobile devices by their nature can be used in many different locations. This is an interesting consideration, because it’s not something we traditionally need to take into account designing experiences for static platforms like desktop computers.
The in the study, we found that 82% of users browse the web on their mobile phone while in their home. In contrast, only 7% do the same while at work. This might come across as a bit of a shock, but when you look at mobile usage – in particular app usage – most of the apps being used are either a social network or some sort of entertainment or media app. Due to the unreliability of network connections, users will often alternate between these two types of apps.
The consequence being that if a site doesn’t work offline, or otherwise compensate for bad network connectivity in some way by providing opportunities to allow users to browse their site, then it becomes a self-fulfilling prophecy as to why users mostly view the mobile web from the comfort of their homes where there is a strong WiFi connection. They’re using mobile devices, but they’re not actually mobile themselves.
Another thing to bear in mind is how users alternate between devices, a study by comScore found that 80% of transactions take place on desktop while 69% of the browsing takes place on mobile. Any given user might access from more than one location - they might visit one day from a bus queue on their phone, and then next day from a laptop at home.
State of mind
One more thing we need to take into consideration is the user’s state of mind. Whilst browsing at home, users tend to be more relaxed, and in the research 76% stated they were generally calmer at home. The user’s state of mind can have quite a big impact on how they perceive things. The calmer they are, the quicker a site might appear to load. If the user is anxious and impatiently drumming their fingers on the table, things seem to take longer, and even a small wait can feel like an eternity.
This is quite key. Over 40% of sites take longer than 4 seconds to load for users who are are out and about and using a mobile data connection. Coupled with our perception, and amplified by a potentially less-than-calm state of mind, this can seem like an age.
What does this all mean?
I think we can all agree that users prefer strong, steady connections and comfort when completing transactions. It seems like common sense when we say it out loud. Recreating these feelings and sensations of comfort and predictability under all circumstances therefore becomes paramount. Equally, when asked in the study, users all claimed that speed was the most important factor impacting their mobile web usage. Over 40%, in fact, said it was the most important UX feature of a site, and nobody asked considered it to be of no importance at all.

The meaning of speed
When it comes to performance, speed is measured in two ways – real speed; as measured on a clock, and perceived speed; how responsive an interaction feels.  We can, of course, improve how quickly a site loads by simply making files smaller. Even then, the study showed that 32% of users felt a site can feel slow even when it loads in less than 4 seconds. This gets even worse when you look at it by age group, with 50% if young people (18-24 year olds) thinking a site was slower than it actually was. When you add to the mix that users think a site loaded faster when they are sitting compared to when they are standing up, then you are in a world of trouble if your site doesn’t have any clear indicators to let the user know the loading state of you website or app.
So what can we do about this to improve our designs?
How to fix / hack user perception
There are some golden rules of speed, the first thing is hacking response time. If a page takes more than 3 seconds to load, you will certainly start to lose your users. However, if that slowness is part of a UX flow such as processing information, the user understands it might take a little time. Under those circumstances, a load time of under 5 seconds is acceptable, but even then, you should take caution. Anything above 8 seconds and you are in very real danger of losing your audience completely.  



Load time
User impression




200 ms
Feels instant


1 s
Feels it is performing smoothly


5 s
Part of user flow


8 s
Lose attention



Remove the tap delay
Mobile browsers often use a 300-350ms delay between the triggering of the touchend and click events. This delay was added so the browser could determine if there was going to be a double-tap triggered or not, since double-tap is a common gesture used to zoom into text. This delay can have the side effect of making interactions feel laggy, and therefore giving the user the impression that the site is slow, even if it’s their own browser causing the problem.
Fortunately there’s a way to remove the delay. Add following in the <head> of your page, and the delay no longer takes effect:
<meta name="viewport" content="width=device-width">
You can also use touch-action: manipulation in newer browsers to eliminate click delay. For old browsers, FastClick by FT Labs uses touch events to trigger clicks faster and remove the double-tap gesture.
Make use of Skeleton Screens
A skeleton layout is a wireframe version of your app that displays while content is being loaded. This demonstrates to the user that content is about to be loaded, giving the impression that something is happening more quickly than it really is. Consider also using a preloader UI as well, with a text label informing the user that the app is loading. One example would be to pulsate the wireframe content giving the app the feeling that it is alive and loading. This reassures the user that something is happening and helps prevent resubmissions or refreshes of your app. Razvan Caliman created a Codepen example of how to create this effect in purely CSS. 
One thing to consider though, if data doesn’t load then you might need to create a fallback 404 or error page to let the user know what happened.  

Example by Owen-Campbell Moore
Responsive Touch Feedback
Carefully designing the process by which items load is one aspect of increasing the perceived speed of your page, but reassuring the user that an action they have taken is in process is another. At Google we use something called a Ripple, which is is animating dot that expands or ripples in order to confirm to the user that their input has been triggered. This happens immediately, expanding outward from the point of touch. This reaffirms to the user that their input has been received and is being acted on, even before the site has had a chance to process or respond to the action. From the user’s point of view, they’ve tapped and the page has responded immediately, so it feels really quick and satisfying.
You can mimic this same behavior using our Material Design Components Web GitHub repo.

Progress bars
These UI elements have existed for a very long time, but research conducted by Chris Harrison and published in New Scientist found that the style of a progress bar can alter the perception of speed drastically. As a matter of fact, progress bars with ripples that animate towards the left appear like they are loading faster by at least 11% percent. So when including them in your site, take into consideration that ripples and progress bars that pulsate faster as they get to the end will make your sites seem quicker.

    
  
  Faster Progress Bars: Manipulating Perceived Duration with Visual Augmentations
Navigation
The speed with which a user can locate navigational items or call to actions adds to their perceived performance of a site. If the user’s next action is quick to spot on the screen, they don’t spend time hunting around the interface with their eyes and fingers. So no matter how quickly your code runs, hiding items behind a nav bar will make a site feel slower than it actually is. 
Facebook found that switching to using bottom navigation saw an increase in engagement, satisfaction, revenue, speed, and importantly, perception of speed. If the user sees the navigation items they’re looking for quickly, the interaction feels fast. What’s more, end-to-end task completion is quicker too, as the interface not only feels quicker, but actually measures quicker as well. Similar reactions were found with Spotify and Redbooth.
Luke Wroblewski gave a talk last year in Ireland titled “Obvious Always Wins” which he demonstrated through the work he did with Google+. Luke’s message is that by making the core features of your app obvious to your user, you will see engagement go up. This again seems obvious, right? However, it is important to note that adding bottom navigation doesn’t just mean a black bar at the bottom of your screen like some kind of performance magic bullet. The goal is to make the items clear to the user so they know what they need to be doing, and how you achieve that could be different from one interface to the next. Google keeps experimenting with different navigation styles, but finally settled with the below when they conducted user research and testing.

Conclusion
By utilizing a collection of UI patterns and speed optimisation techniques, you can improve not only the actual speed of a site, but the perception of how quickly a user thinks your site is loading. It is critical to remember that users will not always be using your site in a calm and relaxed manner and that even their age can impact how they will use or not use your site. By improving your site’s stability, you increase the likelihood of positive user engagement and task completion.
You can learn more about techniques to hack user perception and improve user speed by taking a look at an E-Book we published with Awwwards.com called Speed Matters: Design for Mobile Performance.


title: Is Your Website Accidentally Sexist?
year: 2017
author: Suw Charman-Anderson
author_slug: suwcharmananderson
published: 2017-12-20T00:00:00+00:00
url: https://24ways.org/2017/is-your-website-accidentally-sexist/
topic: content
contents:
Women make up 51% of the world’s population. More importantly, women make 85% of all purchasing decisions about consumer goods, 75% of the decisions about buying new homes, and 81% of decisions about groceries. The chances are, you want your website to be as attractive to women as it is to men. But we are all steeped in a male-dominated culture that subtly influences the design and content decisions we make, and some of those decisions can result in a website that isn’t as welcoming to women as it could be.  
Typography tells a story
Studies show that we make consistent judgements about whether a typeface is masculine or feminine: Masculine typography has a square or geometric form with hard corners and edges, and is emphatically either blunt or spiky. Serif fonts are also considered masculine, as is bold type and capitals.
Feminine typography favours slim lines, curling or flowing shapes with a lot of ornamentation and embellishment, and slanted letters. Sans-serif, cursive and script fonts are seen as feminine, as are lower case letters. 
The effect can be so subtle that even choosing between bold and regular styles within a single font family can be enough to indicate masculinity or femininity.
If you want to appeal to both men and women, search for fonts that are gender neutral, or at least not too masculine. When you’re choosing groups of fonts that need to work harmoniously together, consider which fonts you are prioritising in your design. Is the biggest word on the page in a masculine or feminine font? What about the smallest words? Is there an imbalance between the prominence of masculine and feminine fonts, and what does this imply? 
Typography is a language in and of itself, so be careful what you say with it. 
Colour me unsurprised
Colour also has an obvious gender bias. We associate pinks and purples, especially in combination, with girls and women, and a soft pink has become especially strongly related to breast cancer awareness campaigns. On the other hand, pale blue is strongly associated with boys and men, despite the fact that pastels are usually thought of as more feminine. 
These associations are getting stronger and stronger as more and more marketers use them to define products as “for girls” and “for boys”, setting expectations from an incredibly young age — children as young as four understand gender stereotypes. It should be obvious that using these highly gender-associated colours sends an incredibly strong message to your visitors about who you think your target audience is. If you want to appeal to both men and women, then avoid pinks and pale blues.
But men and women also have different colour preferences. Men tend to prefer intense primary colours and deeper colours (shades), and tolerate greys better, whilst women prefer pastels (tints). When choosing colours, consider not just the hue itself, but also tint, tone and shade.
Slightly counterintuitively, everyone likes blue, but no one seems to particularly like brown or orange. 
A picture is worth a thousand words, or none
Stock photos are the quickest and easiest way to add a little humanity to your website, directly illustrating the kind of people you believe are in your audience. But the wrong photo can put a woman off before she’s even read your text. 
A website about a retirement home will, for example, obviously include photos of older people, and a baby clothes retailer will obviously show photos of babies. But, in the latter case, should they also show only photographs of mothers with their children, or should they include fathers too? It’s true that women take on the majority of childcare responsibilities, but that’s a cultural holdover from a previous era, rather than some rule of law. We are seeing increasing number of stay at home dads as well as single dads, so showing only photographs of women both enforces the stereotype that only women can care, as well as marginalising male carers.  
Equally, featuring prominent photographs of women on sites about male-dominated topics such as science, technology or engineering help women feel welcomed and appreciated in those fields. Photos really do speak volumes, so make sure that you also represent other marginalised groups, especially ethnic groups. If people do not see themselves represented on your site, they are not going to engage with it as much as they might. 
Another form of picture that we often ignore is the icon. When you do use icons, make sure that they are gender neutral. For example, avoid using a icon of a man to denote engineers, or of a woman to denote nurses. Avoid overly masculine or feminine metaphors, such as a hammer to denote DIY or a flower to denote gardens. Not only are these gendered, they’re also trite and unappealing, so come up with more exciting and novel metaphors. 
Use gender-neutral language
Last, but not least, be very careful in your use of gender in language. 
Pronouns are an obvious pitfall. A lot of web content is written in the second person, using the cleary gender neutral ‘you’, but if you have to write in the third person, which uses ‘she’, ‘he’, ‘it’, and ‘they’, then be very careful which pronouns you use. The singular ‘they’ is becoming more widely acceptable, and is a useful gender-neutral option. If you must use generic ‘he’ and ‘she’, (as opposed to talking about a specific person), then vary the order that they come in, so don’t always put the male pronoun first. 
When you are talking about people, make sure that you use the same level of formality for both men and women. The tendency is to refer to men by their surname and women by their first name so, for example, when people are talking about Ada Lovelace and Charles Babbage, they often talk about “Ada and Babbage”, rather than “Lovelace and Babbage” or “Ada and Charles”. As a rule, it’s best to use people’s surnames in formal and semi-formal writing, and their first names only in very informal writing. 
It’s also very important to make sure that you respect people’s honorifics, especially academic titles such as Dr or Professor, and that you use titles consistently. Studies show that women and people of colour are the most likely to have their honorifics dropped, which is not only disrespectful, it gives readers the idea that women and people of colour are less qualified than white men.
If you mention job titles, avoid old-fashioned gendered titles such as ‘chairman’, and instead look for a neutral version, like ‘chair’ or ‘chairperson’. Where neutral terms have strong gender associations, such as nurse or engineer, take special care that the surrounding text, especially pronouns, is diverse and/or neutral. Do not assume engineers are male and nurses female. 
More subtle intimations of gender can be found in the descriptors people use. Military metaphors and phrases, out-sized claims, competitive words, and superlatives are masculine, such as ‘ground-breaking’, ‘best’, ‘genius’, ‘world-beating’, or ‘killer’. Excessive unnecessary factual detail is also very masculine. 
Women tend to relate to more cooperative, non-competitive, future-focused, and warmer language, paired with more general information. Women’s language includes word like ’global’, ‘responsive’, ‘support’, ‘include’, ‘engage’ and ‘imagine’. Focus more on the kind of relationship you can build with your customers, how you can help make their lives easier, and less on your company or product’s status. 
Smash the patriarchy, one assumption at a time
We’re all brought up in a cultural stew that prioritises men’s needs, feelings and assumptions over women’s. This is the patriarchy, and it’s been around for thousands of years. But given women’s purchasing power, adhering to the patriarchy’s norms is unlikely to be good for your business. If you want to tap into the female market, pay attention to the details of your design and content, and make sure that you’re not inadvertently putting women off. A gender neutral website that designs away gender stereotypes will attract both men and women, expanding your market and helping your business flourish.


title: Knowing the Future - Tips for a Happy Launch Day
year: 2017
author: Phil Hawksworth
author_slug: philhawksworth
published: 2017-12-21T00:00:00+00:00
url: https://24ways.org/2017/knowing-the-future/
topic: process
contents:
You’ve chosen your frameworks and libraries. You’ve learned how to write code which satisfies the buzzword and performance gods. Now you need to serve it to a global audience, and make things easy to preview, to test, to sign-off, and to evolve.
But infrastructure design is difficult and boring for most of us. We just want to get our work out into the wild.
If only we had tools which would let us go, “Oh yeah! It all deploys perfectly every time” and shout, “You need another release? BAM! What’s next?”
A truth that can be hard to admit is that very often, the production environment and its associated deployment processes are poorly defined until late into a project. This can be a problem.
It makes my palms sweaty just thinking about it.
If like me, you have spent time building things for clients, you’ll probably have found yourself working with a variety of technical partners and customers who bring different constraints and opportunities to your projects. Knowing and proving the environments and the deployment processes is often very difficult, but can be a factor which profoundly impacts our ability to deliver what we promised. To say nothing of our ability to sleep at night or leave our fingernails un-chewed.
Let’s look at this a little, and see if we can’t set you up for a good night’s sleep, with dry palms and tidy fingernails.
A familiar problem
You’ve been here too, right? The project development was tough, but you’re pleased with what you are running in your local development environments. Now you need to get the client to see and approve your build, and hopefully indicate with a cheery thumbs up that it can “go live”.

Chances are that we have a staging environment where the client can see the build. But be honest, is this exactly the same as the production environment? It should be, but often it’s not. Often the staging environment is nothing more than a visible server with none of the optimisations, security, load balancing, caching, and other vital bits of machinery that we’ll need (and need to test) in “prod”.
Often the production environment is still being “set up” and you’ll have to wait and see.
In development, “wait and see” is the enemy.
Instead of waiting to see, we need to make the provisioning of, and deployment to our different environments one of the very first jobs of our project. I’ve often needed to be the unpopular voice in the room who makes a big fuss when this is delayed. I’ve described it as being a “critical blocker” during project meetings and suggested that everything should halt until it is fixed. 
It is that important.
Clients don’t often like hearing a wary, disruptive voice saying “whoa there Nelly!”, because the development should be able to continue while the production environment gets sorted out, right? 
Sure. But if it is not seen as a blocker, it is seen as something that can just happen later. And if it happens later, all the ugly surprises and unknowns surface later too. And later is when we’ll need to be thinking about other things. Not the plumbing. Trust me, it pays to face up to the issue right away rather than press on optimistically. The client will thank you later.
Attitudes and expectations
We should, I think, exhibit these four attitudes towards production deployment:

Make it scripted
Make it automated
Make it real
Make it first

Make it scripted
Let’s face it, we are going to need to deploy more than once over the course of the project. We are not going to get things perfect on our first shot. Nor should we expect to. And if we are going to repeat something, we want to be able to do it identically and predictably every time without needing to rely on our memories.
Developers are great at scripting things which they would otherwise need to repeat. It makes us faster and it also helps us keep track of the steps we need to take.
I’m not crazy enough to try suggest the best technology to script your builds or deployments (holy wars lie down that path). A lot will depend on your languages and your tastes. Some will like Fabric, others will prefer Gulp, you might prefer Make or NPM. It doesn’t really matter as long as you can script the process of building, packaging and deploying your project.
Wait. Won’t we need to know everything about the build from the start in order to do this? Aren’t our dependencies likely to change over time?
Yes. That would be ideal. But it’s ok. Like our code, our deployment script will evolve over the life of a project. So evolve it. Start by scripting what is needed to support the first iteration of the project, and then maintain that script. It will become a valuable “source of truth”, providing a form of documentation of what your project needs for a successful deployment. Another bonus.
Make it automated
If we have a scripted deployment which we can run by executing a single command, then we are in great shape to automate that process by triggering the build and deployment via suitable events.
Again, I prefer not to offer one single suggestion of when this should occur. That will depend on your approach to the project, how your development team is organised, and how your QA team operate. You can tune this to suit.
For one project I worked on, we chose to trigger the build and deployment to our production environment every time we used Git to tag the master branch of our version control repository. There were a few moving parts, and we needed to do some upfront work to get everything working, but that upfront effort was repaid many fold as we deployed time and time again, and exposed some issues with our environment long before we got to “launch day”.
With a scripted and automated process, we can make deployments “cheap”. This is our goal. When there are minimal cognitive or time overheads associated with deploying, we’re likely to do it all the more often and become more confident that it will behave as expected.
Make it real
Alright, we have written scripts to build and deploy our projects. Anyone tagging our repo will trigger things to happen as if by magic, but where are we pushing things to?  We need to target a real environment if this is to have any value.
A useful pattern is to have all activity on our develop branch trigger deployments to our staging server. Meanwhile tagging master will deploy a version to the production environment. How we organise this will depend on our git branching approach. (I’ve seen as many ways of approaching Git Flow as I have seen ways of approaching “Agile”).
It’s vital though, that we ensure that we are deploying to, and testing against, our real infrastructure. We want to see real results. That’s the best way to learn real lessons.
Make it first
Building our site to run in an environment not yet fully defined or available to test is like climbing without ropes – it’s possible, but we put ourselves at risk. And the higher we climb the greater the risk. So it is important to do this as early as we possibly can.
Don’t have a certificate for our HTTPS yet? Fine, but let’s still deploy to this evolving production environment and introduce HTTPS as soon as we can.
Before we know it we’ll be proving that this is set up correctly and we’ll not be surprised by mixed security alerts or other nasties further down the line.

Mailchimp perfectly capture the anxiety of sending emails to gazillions of people for a campaign. But we’re lucky. Launching a site doesn’t need to be like performing a mailshot. We can do things to banish that sweaty hand.
Doing preparation work upfront means that by the time we need to launch the site into the wild, we have exercised the deployment mechanics, and tested the production environment so rigorously that this task will be boring.
(It won’t be boring. Launching should always be exciting because the world will finally get to see our beautiful, painstaking work. But nor should it be terrifying. Especially as a result of not knowing for certain if our processes and environments are going to work or burst into flames on the big day.)
What tools exist?
Well this all sounds lovely. But how should we tackle this? Where are the tools for us to use? As it happens, there are many service and tools that we can use to work this way.
Hosting
All of the big players like Amazon, Azure and Google offer tools which can help us here. Google for example, can host multiple deployed versions of your project in parallel and you can manage them via their App Engine console. Each build receives its own URL which you can use to access any deployed version of your site.
Having immutable deployments which stick around in perpetuity (or until you bin them) is a key feature which unlocks the ability to confidently direct your traffic to any version of your site. With that comes the capacity to test any version or feature in its real environment, and then promote a version, or rollback to a previous version whenever you want.
A liberating power to have.
Continuous integration
In order to create all of those different versions, we’ll need somewhere to run our build and deployment scripts. Jenkins has been a popular Continuous Integration (CI) option for some time, and can be configured to perform all sorts of tasks, giving you extensive control over your deployment pipeline.
You need to host Jenkins yourself, but it provides some simple ways to do that.
The landscape for CI is getting richer and richer. With many hosted services like Circle CI providing this kind of automation up in the cloud.
One stop shop
Netlify combines both hosting and continuous integration services. It monitors your git repositories and automatically runs your build in a container on its servers when it finds changes. Each branch and pull request in your git repository will result in an immutable version of your site with its own URL.
Netlify is unlike Google Cloud, AWS or Azure in that it cannot host a dynamic server-side application for you. Instead it specialises in hosting static, or so called JAMstack sites.
Personally, I find that its simplicity makes it an approachable option, and a good place to learn and adopt some of these valuable habits.
Full disclosure: I’m a Netlify employee. But before I was, I was an avid customer, and it was through using Netlify that I first encountered some of these principles in practice.
Conclusion. It’s all about the approach
No matter what tools or services you use (and there are many which can support these practices), the most important thing is to adopt an approach which lets you prove your environments as quickly as possible.
Front-loading this effort will cast light onto the issues that you’ll need to address early and often, leaving no infrastructure surprises to spoil things for you on launch day.
Automating the process will mean that when you do find things that you need to fix or to improve later (and you will), issuing another release will be trivial. It is a lovely feeling when you have confidence that releasing v1.0.0 will be no more stressful v0.0.1. In fact it should actually be less stressful, as you’ll have been down this road many times by then. Fixing the potholes and smoothing the way as you went.
From here, it should be a smooth ride.


title: Care and Feeding of Burnout
year: 2017
author: Jessica Rose
author_slug: jessicarose
published: 2017-12-16T00:00:00+00:00
url: https://24ways.org/2017/care-and-feeding-of-burnout/
topic: process
contents:
You’ve been doing too much for too long. And it’s broken you. You’re burned out. You’re done.
Illustration by Kate Holden
Occupational burnout is a long-documented effect of stretching yourself further than the limits of your mental and physical health can carry you. And when it finally catches up with you, it can feel like the end of the world. But things can get better. With focused self care, reworking your priorities and lots of time, you can slog through burnout.
What is burnout? The Tl;dr linkdump tour
In this article, we’ll be looking at what you can do when you’re burned out. We’ll be skipping past a lot of information on what burnout is, what causes it and how it impacts the tech industry. We’re able to skip past this because many technologists have already created valuable content targeted to our industry. The videos and writing below may be helpful for readers who are less familiar with burnout.
A Wikipedia article may be a great starting point for learning about occupational burnout.

  

Understanding burnout: Brandon West
This conference talk by Brandon West covers a lot of burnout 101, from the perspective of a developer relations/community professional.
April Wensel writes about the need for the tech industry to move from the Valley’s burnout culture to a more sustainable model.
Catching Burnout [as] early [as possible]
One of the most challenging things about burnout is that it develops slowly and gradually. Many impacted don’t notice the water warming around them until it’s been brought to a boil, causing a crisis that can’t be overlooked. Catching burnout and taking steps to deal with it as early as possible can help limit the length and severity of your burnout.
Getting in the habit of checking in with yourself regularly about your stress and energy levels can be an effective habit for assessing burnout and for general wellness. The Mayo Clinic recommends asking yourself the following questions to determine if you might be suffering from burnout.

Have you become cynical or critical at work?
Do you drag yourself to work and have trouble getting started once you arrive?
Have you become irritable or impatient with co-workers, customers or clients?
Do you lack the energy to be consistently productive?
Do you lack satisfaction from your achievements?
Do you feel disillusioned about your job?
Are you using food, drugs or alcohol to feel better or to simply not feel?
Have your sleep habits or appetite changed?
Are you troubled by unexplained headaches, backaches or other physical complaints?

According to the Mayo Clinic, answering yes to more than one of these questions can be a sign that you need to take corrective action. We’ll look in more detail about the corrective actions you can take in the rest of this article. 
Do less. Now.
To start getting things back on track, you’ll need to start doing less. Less work, less stress, less everything. Many technologists impacted by burnout have written or spoken on taking months or even years off work to give themselves time to recover. This can be a fantastic route back to wellness for those fortunate enough to have the professional and financial security to allow them to take large stretches of time off work. For the much larger group of burned out workers that need to balance earning a paycheck with their wellness, this can be more challenging.
For those of us who need to stay in the cycle of work to fund our daily needs, finding ways to do less can feel like adding another daunting task to the pile. To properly assess where and how you can cut back on your commitments, you’ll need to find a short stretch of time clear of stressors and responsibilities to take stock of what can be scaled back. A long weekend, weekend or even a few hours of time dedicated to looking only at how you can cut back on work and stress can be an effective way to take stock of your responsibilities.
Make a list of stressors and activities to begin to triage. Anything that would damage or seriously disrupt your life if not attended to (doing your taxes, showing up at work, paying rent) should be marked as essential. Grade other activities in your life, marking the ones that aren’t essential and working to temporarily reduce these or remove them from your life. It can feel difficult to let go of things while recovering from burnout. This process can benefit from a second opinion, if you’re working with a coach, therapist or trusted friend to manage your burnout.
Reducing your workload and stressors can let you begin to recover from burnout. You can reintroduce things back into your schedule and life. Reintroduce stressors and activities back into your life slowly, to minimize risk of relapse. Keeping a journal will let you keep tabs on how different activities are impacting your energy levels and state of mind.
Remove toxicity
Toxic people or settings can drain you faster than overwork alone can. While you work to reduce your workload and stress, coworkers, friends, family or bosses who are toxic influences can act as a multiplier for the stressors that remain. Identifying these people and limiting your interactions with them during your recovery can help you get back on track faster and happier. A journal can be an important tool in tracking how interactions with different people impact your wellness and state of mind. If the toxic presence in your life is someone you can avoid or cut out without penalty, burnout is a great reason to finally replace them with healthier relationships.
If you can’t remove them from your life, minimizing the impact toxic people have on your wellness is vital. Work to identify what aspect of the relationship is draining or damaging and create interventions around damaging interactions. While a chronically complaining coworker’s negativity can be stopped short with setting firm conversational boundaries and redirection, a combative boss can be a harder challenge. Seeking allies and advice can make you feel less alone in your battles and provide healthy emotional support. 
Ask for help
Trying to find your way back to health and wellness after burning out can be a daunting task. Seeking help from health care professionals, trusted peers or both can give you backup on your journey back to feeling better. With symptoms that can mirror those of depression, burnout can be the precursor to a number of mental and physical ailments. Talk to your doctor immediately if you’re experiencing symptoms of depression or any other health concerns.
Being open with your trusted friends about burnout can let you access valuable support and help explain why you may need extra care and consideration while you recover. Many suffering from burnout report finding maintaining relationships a challenge. Letting your loved ones know what you’re going through and why you may be less available invites them to be more understanding of cancelled plans or other issues while you’re recovering. Burnout can impact memory and cognitive function. Letting your support network assist in decision making during burnout can help add perspective to counterbalance these deficits.
Talking to your friends and peers about your health and needs can offer valuable support. But those who are pushed to a mental or physical health crisis by burnout should work with healthcare professionals to plan their recovery. Sufferers of mild to moderate burnout can also benefit from planning their return to wellness with an experienced practitioner. Medical or counseling professionals may prescribe medicines, talk therapy, group sessions or other therapeutic intervention.  
Go easy on yourself
Recovering from burnout is a process that takes energy, time and compassion for yourself. In the same way that toxic people or workplaces can set you back, negative repetitive thoughts will harm your recovery. Recognizing that burnout’s impact on you is a temporary state that isn’t your fault can help you begin to manage your feelings and expectations for yourself. Sufferers often report feeling stupid, lazy or that they lack the skills to do their job. This is natural, as burnout can severely limit your cognitive function, your energy levels and resilience while dramatically increasing your cognitive load. Working with a counselor may help if you’re finding it difficult to be patient with your progress back to health or are troubled by persistent intrusive thoughts.
Burnout can seriously limit the amount of energy you have. Spend as little of the energy you have left beating yourself up as possible. You’re going to be ok. It’s all going to be ok.
This article doesn’t offer one-size-fits all fixes for burnout or overwork, but aims to provide a framework with points to consider that may help shape your wellness. No article can act as a substitute for professionally administered healthcare or robust self care.


title: Lint the Web Forward With Sonarwhal
year: 2017
author: Stephanie Drescher
author_slug: stephaniedrescher
published: 2017-12-02T00:00:00+00:00
url: https://24ways.org/2017/lint-the-web-forward-with-sonarwhal/
topic: code
contents:
Years ago, when I was in a senior in college, much of my web development courses focused on two things: the basics like HTML and CSS (and boy, do I mean basic), and Adobe Flash. I spent many nights writing ActionScript 3.0 to build interactions for the websites that I would add to my portfolio. A few months after graduating, I built one website in Flash for a client, then never again. Flash was dying, and it became obsolete in my résumé and portfolio. 
That was my first lesson in the speed at which things change in technology, and what a daunting realization that was as a new graduate looking to enter the professional world. Now, seven years later, I work on the Microsoft Edge team where I help design and build a tool that would have lessened my early career anxieties: sonarwhal. 
Sonarwhal is a linting tool, built by and for the web community. The code is open source and lives under the JS Foundation. It helps web developers and designers like me keep up with the constant change in technology while simultaneously teaching how to code better websites. 
Introducing sonarwhal’s mascot Nellie
Good web development is hard. It is more than HTML, CSS, and JavaScript: developers are expected to have a grasp of accessibility, performance, security, emerging standards, and more, all while refreshing this knowledge every few months as the web evolves. It’s a lot to keep track of.
 
Web development is hard 
Staying up-to-date on all this knowledge is one of the driving forces for developing this scanning tool. Whether you are just starting out, are a student, or you have over a decade of experience, the sonarwhal team wants to help you build better websites for all browsers. 
Currently sonarwhal checks for best practices in five categories: Accessibility, Interoperability, Performance, PWAs, and Security. Each check is called a “rule”. You can configure them and even create your own rules if you need to follow some specific guidelines for your project (e.g. validate analytics attributes, title format of pages, etc.). 
You can use sonarwhal in two ways:

An online version, that provides a quick and easy way to scan any public website.
A command line tool, if you want more control over the configuration, or want to integrate it into your development flow.

The Online Scanner
The online version offers a streamlined way to scan a website; just enter a URL and you will get a web page of scan results with a permalink that you can share and revisit at any time.
The online version of sonarwal
When my team works on a new rule, we spend the bulk of our time carefully researching each subject, finding sources, and documenting it rather than writing the rule’s code. Not only is it important that we get you the right results, but we also want you to understand why something is failing. Next to each failing rule you’ll find a link to its detailed documentation, explaining why you should care about it, what exactly we are testing, examples that pass and examples that don’t, and useful links to even more in-depth documentation if you are interested in the subject.
We hope that between reading the documentation and continued use of sonarwhal, developers can stay on top of best practices. As devs continue to build sites and identify recurring issues that appear in their results, they will hopefully start to automatically include those missing elements or fix those pieces of code that are producing errors. This also isn’t a one-way communication: the documentation is not only available on the sonarwhal site, but also on GitHub for editing so you can help us make it even better!
A results report
The current configuration for the online scanner is very strict, so it might hurt your feelings (it did when I first tested it on my personal website). But you can configure sonarwhal to any level of strictness as well as customize the command line tool to your needs!  
Sonarwhal’s CLI 
The CLI gives you full control of sonarwhal: what rules to use, tweaks to them, domains that are out of your control, and so on. You will need the latest node LTS (v8) or Stable (v9) and your favorite package manager, such as npm:
npm install -g sonarwhal
You can now run sonarwhal from anywhere via:
sonarwhal https://example.com
Using the CLI
The configuration is done via a .sonarwhalrc file. When analyzing a site, if no file is available, you will be prompted to answer a series of questions:

What connector do you want to use? Connectors are what sonarwhal uses to access a website and gather all the information about the requests, resources, HTML, etc. Currently it supports jsdom, Microsoft Edge, and Google Chrome.
What formatter? This is how you want to see the results: summary, stylish, etc. Make sure to look at the full list. Some are concise for, perfect for a quick build assessment, while others are more verbose and informative.
Do you want to use the recommended rules configuration? Rules are the things we are validating. Unless you’ve read the documentation and know what you are doing, first timers should probably use the recommended configuration.
What browsers are you targeting? One of the best features of sonarwhal is that rules can adapt their feedback depending on your targeted browsers, suggesting to add or remove things. For example, the rule “Highest Document Mode” will tell you to add the “X-UA-Compatible” header if IE10 or lower is targeted or remove if the opposite is true. 

sonarwhal configuration generator questions
Once you answer all these questions the scan will start and you will have a .sonarwhalrc file similar to the following:
{
    "connector": {
        "name": "jsdom",
        "options": {
            "waitFor": 1000
        }
    },
    "formatters": "stylish",
    "rulesTimeout": 120000,
    "rules": {
        "apple-touch-icons": "error",
        "axe": "error",
        "content-type": "error",
        "disown-opener": "error",
        "highest-available-document-mode": "error",
        "validate-set-cookie-header": "warning",
        // ...
    }
}
You should see the scan initiate in the command line and within a few seconds the results should start to appear. Remember, the scan results will look different depending on which formatter you selected so try each one out to see which one you like best. 
sonarwhal results on my website and hurting my feelings 💔
Now that you have a list of errors, you can get to work improving the site! Note though, that when you scan your website, it scans all the resources on that page and if you’ve added something like analytics or fonts hosted elsewhere, you are unable to change those files. You can configure the CLI to ignore files from certain domains so that you are only getting results for files you are in control of.
The documentation should give enough guidance on how to fix the errors, but if it’s insufficient, please help us and suggest edits or contribute back to it. This is a community effort and chances are someone else will have the same question as you.
When I scanned both my websites, sonarwhal alerted me to not having an Apple Touch Icon. If I search on the web as opposed to using the sonarwhal documentation, the first top 3 results give me outdated information: I need to include many different icon sizes. I don’t need to include all the different size icons that target different devices. Declaring one icon sized 180px x 180px will provide a large enough icon for devices and it will scale down as appropriate for people on older devices. 
The information at the top of the search results isn’t always the correct answer to an issue and we don’t want you to have to search through outdated documentation. As sonarwhal’s capabilities expand, the goal is for it to be the one stop shop for helping preflight your website. 
The journey up until now and looking forward

On the Microsoft Edge team, we’re passionate about empowering developers to build great websites. Every day we see so many sites come through our issue tracker. (Thanks for filing those bugs, they help us make Microsoft Edge better and better!) Some issues we see over and over are honest mistakes or outdated ‘best practices’ that could be avoided, so we built this tool to help everyone help make the web a better place.
When we decided to create sonarwhal, we wanted to create a tool that would help developers write better and more up-to-date code for their websites. We want sonarwhal to be useful to anyone so, early on, we defined three guiding principles we’ve used along the way:

Community Driven. We build for the community’s best interests. The web belongs to everyone and this project should too. Not only is it open source, we’ve also donated it to the JS Foundation and have an inclusive governance model that welcomes the collaboration of anyone, individual or company.
User Centric. We want to put the user at the center, making sonarwhal configurable for your needs and easy to use no matter what your skill level is.
Collaborative. We didn’t want to reinvent the wheel, so we collaborated with existing tools and services that help developers build for the web. Some examples are aXe, snyk.io, Cloudinary, etc.

This is just the beginning and we still have lots to do. We’re hard at work on a backlog of exciting features for future releases, such as:

New rules for a variety of areas like performance, accessibility, security, progressive web apps, and more.
A plug-in for Visual Studio Code: we want sonarwhal to help you write better websites, and what better moment than when you are in your editor.
Configuration options for the online service: as we fine tune the infrastructure, the rule configuration for our scanner is locked, but we look forward to adding CLI customization options here in the near future.

This is a tool for the web community by the web community so if you are excited about sonarwhal, making a better web, and want to contribute, we have a few issues where you might be able to help. Also, don’t forget to check the rest of the sonarwhal GitHub organization. PRs are always welcome and appreciated! 
Let us know what you think about the scanner at @NarwhalNellie on Twitter and we hope you’ll help us lint the web forward!


title: Design Systems and CSS Grid
year: 2017
author: Stuart Robson
author_slug: stuartrobson
published: 2017-12-12T00:00:00+00:00
url: https://24ways.org/2017/design-systems-and-css-grid/
topic: code
contents:
Recently, my client has been looking at creating a few new marketing pages for their website. They currently have a design system in place but they’re looking to push this forward into 2018 with some small and possibly some larger changes.
To start with we are creating a couple of new marketing pages. As well as making use of existing components within the design systems component library there are a couple of new components. Looking at the first couple of sketch files I felt this would be a great opportunity to use CSS Grid, to me the newer components need to be laid out on that page and grid would help with this perfectly.

As well as this layout of the new components and the text within it, imagery would be used that breaks out of the grid and pushes itself into the spaces where the text is aligned.
The existing grid system
When the site was rebuilt in 2015 the team decided to make use of Sass and Susy, a “lightweight grid-layout engine using Sass”.  It was built separating the grid system from the components that would be laid out on the page with a container, a row, an optional column, and a block.
To make use of the grid system on a page for a component that would take the full width of the row you would have to write something like this:
<div class="grid-container">
  <div class="grid-row">
    <div class="grid-column-4">
      <div class="grid-block">
        <!-- component code here -->
      </div>
    </div>
  </div>
</div>
Using a grid system similar to this can easily create quite the tag soup. It could fill the HTML full of divs that may become complex to understand and difficult to edit.
Although there is this reliance on several <div>s to lay out the components on a page it does allow a tidy way to place the component code within that page. It abstracts the layout of the page to its own code, its own system, so the components can ‘fit’ where needed.
The requirements of the new grid system
Moving forward I set myself some goals for what I’d like to have achieved in this new grid system:
It needs to behave like the existing grid systems
We are not ripping up the existing grid system, it would be too much work, for now,  to retrofit all of the existing components to work in a grid that has a different amount of columns, and spacing at various viewport widths.
Allow full-width components
Currently the grid system is a 14 column grid that becomes centred on the page when viewport is wide enough. We have, in the past, written some CSS that would allow for a full-width component, but his had always felt like a hack. We want the option to have a full-width element as part of the new grid system, not something that needs CSS to fight against.
Less of a tag soup
Ideally we want to end up writing less HTML to layout the page. Although the existing system can be quite clear as to what each element is doing, it can also become a little laborious in working out what each grid row or block is doing where.
I would like to move the layout logic to CSS as much as is possible, potentially creating some utility classes or additional ‘layout classes’ for the components.
Easier for people to use and author
With many people using the existing design systems codebase  we need to create a new grid system that is as easy or easier to use than the existing one. I think and hope this would be helped by removing as many <div>s as needed and would require new documentation and examples, and potentially some initial training.
Separating layout from style
There still needs to be a separation of layout from the styles for the component. To allow for the component itself to be placed wherever needed in the page we need to make sure that the CSS for the layout is a separate entity to the CSS for that styling.
With these base requirements I took to CodePen and started working on some throwaway code to get started.
Making the new grid(s)
The Full-Width Grid
To start with I created a grid that had three columns, one for the left, one for the middle, and one for the right. This would give the full-width option to components.
Thankfully, one of Rachel Andrew’s many articles on Grid discussed this exact requirement of the new grid system to break out with Grid.
I took some of the code in the examples and edited to make grid we needed.
.container {
  display: grid;
  grid-template-columns:
    [full-start]
      minmax(.75em, 1fr)
        [main-start]
          minmax(0, 1008px)
        [main-end]
      minmax(.75em, 1fr)
    [full-end];
}
We are declaring a grid, we have four grid column lines which we name and we define how the three columns they create react to the viewport width. We have a left and right column that have a minimum of 12px, and a central column with a maximum width of 1008px.
Both left and right columns fill up any additional space if the viewport is wider that 1032px wide. We are also not declaring any gutters to this grid, the left and right columns would act as gutters at smaller viewports.
At this point I noticed that older versions of Sass cannot parse the brackets in this code. To combat this I used Sass’ unquote method  to wrap around the value of the grid-template-column.
.container {
  display: grid;
  grid-template-columns:
  unquote("
    [full-start]
      minmax(.75em, 1fr)
        [main-start]
          minmax(0, 1008px)
        [main-end]
      minmax(.75em, 1fr)
    [full-end]
  ");
}
The existing codebase makes use of Sass variables, mixins and functions so to remove that would be a problem, but luckily the version of Sass used is up-to-date (note: example CodePens will be using CSS).
The initial full-width grid displays on a webpage as below:

The 14 column grid
I decided to work out the 14 column grid as a separate prototype before working out how it would fit within the full-width grid. This grid is very similar to the 12 column grids that have been used in web design. Here we need 14 columns with a gutter between each one.
Along with the many other resources on Grid, Mozilla’s MDN site had a page on common layouts using CSS Grid. This gave me the perfect CSS I needed to create my grid and I edited it as required:
.inner {
  display: grid;
  grid-template-columns: repeat(14, [col-start] 1fr);
  grid-gap: .75em;
}
We, again, are declaring a grid, and we are splitting up the available space by creating 14 columns with 1 fr-unit and giving each one a starting line named col-start.
This grid would display on web page as below:

Bringing the grids together
Now that we have got the two grids we need to help fulfil our requirements we need to put them together so that they are actually we we need.
The subgrid
There is no subgrid in CSS, yet. To workaround this for the new grid system we could nest the 14 column grid inside the full-width grid.
In the HTML we nest the 14 column inner grid inside the full-width container.
<div class="container">
  <div class="inner">
  </div>
</div>
So that the inner knows where to be laid out within the container we tell it what column to start and end with, with this code it would be the start and end of the main column.
.inner {
  display: grid;
  grid-column: main-start / main-end;
  grid-template-columns: repeat(14, [col-start] 1fr);
  grid-gap: .75em;
}
The CSS for the container remains unchanged.

This works, but we have added another div to our HTML. One of our requirements is to try and remove the potential for tag soup.
The faux subgrid subgrid
I wanted to see if it would be possible to place the CSS for the 14 column grid within the CSS for the full-width grid. I replaced the CSS for the main grid and added the grid-column-gap to the .container.
.container {
  display: grid;
  grid-gap: .75em;
  grid-template-columns:
    [full-start]
      minmax(.75em, 1fr)
        [main-start]
          repeat(14, [col-start] 1fr)
        [main-end]
      minmax(.75em, 1fr)
    [full-end];
}
What this gave me was a 16 column grid. I was unable to find a way to tell the main grid, the grid betwixt main-start and main-end to be a maximum of 1008px as required.

I trawled the internet to find if it was possible to create our main requirement, a 14 column grid which also allows for full-width components. I found that we could not reverse minmax to minmax(1fr, 72px) as 1fr is not allowed as a minimum if there is a maximum. I tried working out if we could make the min larger than its max but in minmax it would be ignored.
I was struggling, I was hoping for a cleaner version of the grid system we currently use but getting to the point where needing that extra <div> would be a necessity.
At 3 in the morning, when I was failing to get to sleep, my mind happened upon an question: “Could you use calc?”
At some point I drifted back to sleep so the next day I set upon seeing if this was possible. I knew that the maximum width of the central grid needed to be 1008px. The left and right columns needed to be however many pixels were left in the viewport divided by 2. In CSS it looked like I would need to use calc twice. The first time to takeaway 1008px from 100% of the viewport width and the second to divide that result by 2.
calc(calc(100% - 1008px) / 2)
The CSS above was part of the value that I would need to include in the declaration for the grid.
.container {
  display: grid;
  grid-gap: .75em;
  grid-template-columns:
    [full-start]
      minmax(calc(calc(100% - 1008px) / 2), 1fr)
        [main-start]
          repeat(14, [col-start] 1fr)
        [main-end]
      minmax(calc(calc(100% - 1008px) / 2), 1fr)
    [full-end];
}
We have created the grid required. A full-width grid, with a central 14 column grid, using fewer <div> elements.

See the Pen Design Systems and CSS Grid, 6 by Stuart Robson (@sturobson) on CodePen.

Success!
Progressive enhancement
Now that we have created the grid system required we need to back-track a little.
Not all browsers support Grid, over the last 9 months or so this has gotten a lot better. However there will still be browsers that visit that potentially won’t have support. The effort required to make the grid system fall back for these browsers depends on your product or sites browser support.

To determine if we will be using Grid or not for a browser we will make use of  feature queries. This would mean that any version of Internet Explorer will not get Grid, as well as some mobile browsers and older versions of other browsers.
@supports (display: grid) {
 /* Styles for browsers that support Grid */
}
If a browser does not pass the requirements for @supports we will fallback to using flexbox where possible, and if that is not supported we are happy for the page to be laid out in one column.
A website doesn’t have to look the same in every browser after all.
A responsive grid
We started with the big picture, how the grid would be at a large viewport and the grid system we have created gets a little silly when the viewport gets smaller.
At smaller viewports we have a single column layout where every item of content, every component stacks atop each other. We don’t start to define a grid before we the viewport gets to 700px wide. At this point we have an 8 column grid and if the viewport gets to 1100px or wider  we have our 14 column grid.
/*
 * to start with there is no 'grid' just a single column
 */
.container {
  padding: 0 .75em;
}

/*
 * when we get to 700px we create an 8 column grid with
 * a left and right area to breakout of the grid.
 */
@media (min-width: 700px) {
  .container {
    display: grid;
    grid-gap: .75em;
    grid-template-columns:
      [full-start]
        minmax(calc(calc(100% - 1008px) / 2), 1fr)
          [main-start]
            repeat(8, [col-start] 1fr)
          [main-end]
        minmax(calc(calc(100% - 1008px) / 2), 1fr)
      [full-end];
    padding: 0;
  }
}

/*
 * when we get to 1100px we create an 14 column grid with
 * a left and right area to breakout of the grid.
 */
@media (min-width: 1100px) {
  .container {
    grid-template-columns:
    [full-start]
      minmax(calc(calc(100% - 1008px) / 2), 1fr)
        [main-start]
          repeat(14, [col-start] 1fr)
        [main-end]
      minmax(calc(calc(100% - 1008px) / 2), 1fr)
    [full-end];
  }
}
Being explicit in creating this there is some repetition that we could avoid, we will define the number of columns for the inner grid by using a Sass variable or CSS custom properties (more commonly termed as CSS variables).
Let’s use CSS custom properties. We need to declare the variable first by adding it to our stylesheet.
:root {
  --inner-grid-columns: 8;
}
We then need to edit a few more lines. First make use of the variable for this line.
repeat(8, [col-start] 1fr)
/* replace with */
repeat(var(--inner-grid-columns), [col-start] 1fr)
Then at the 1100px breakpoint we would only need to change the value of the —inner-grid-columns value.
@media (min-width: 1100px) {
  .container {
    grid-template-columns:
    [full-start]
      minmax(calc(calc(100% - 1008px) / 2), 1fr)
        [main-start]
          repeat(14, [col-start] 1fr)
        [main-end]
      minmax(calc(calc(100% - 1008px) / 2), 1fr)
    [full-end];
  }
}
/* replace with */
@media (min-width: 1100px) {
  .container {
    --inner-grid-columns: 14;
  }
}
See the Pen Design Systems and CSS Grid, 8 by Stuart Robson (@sturobson) on CodePen.

The final grid system
We have finally created our new grid for the design system. It stays true to the existing grid in place, adds the ability to break-out of the grid, removes a <div> that could have been needed for the nested 14 column grid.
We can move on to the new component.
Creating a new component
Back to the new components we are needing to create.

To me there are two components one of which is a slight variant of the first. This component contains a title, subtitle, a paragraph (potentially paragraphs) of content, a list, and a call to action.
To start with we should write the HTML for the component, something like this:
<article class="features">
  <h3 class="features__title"></h3>
  <p class="features__subtitle"></p>
  <div class="features__content">
    <p class="features__paragraph"></p>
  </div>
  <ul class="features__list">
    <li></li>
    <li></li>
  </ul>
  <a href="" class="features__button"></a>
</article>
To place the component on the existing grid is fine, but as child elements are not affected by the container grid we need to define another grid for the features component.
As the grid doesn’t get invoked until 700px it is possible to negate the need for a media query.
.features {
  grid-column: col-start 1 / span 6;
}

@supports (display: grid) {
  @media (min-width: 1100px) {
    .features {
      grid-column-end: 9;
    }
  }
}
We can also avoid duplication of declarations by making use of the grid-column shorthand and longhand. We need to write a little more CSS for the variant component, the one that will sit on the right side of the page too.
.features:nth-of-type(even) {
  grid-column-start: 4;
  grid-row: 2;
}

@supports (display: grid) {
  @media (min-width: 1100px) {
    .features:nth-of-type(even) {
      grid-column-start: 9;
      grid-column-end: 16;
    }
  }
}
We cannot place the items within features on the container grid as they are not direct children. To make this work we have to define a grid for the features component.
We can do this by defining the grid at the first breakpoint of 700px making use of CSS custom properties again to define how many columns there will need to be.
.features {
  grid-column: col-start 1 / span 6;
  --features-grid-columns: 5;
}

@supports (display: grid) {
  @media (min-width: 700px) {
    .features {
      display: grid;
    grid-gap: .75em;
      grid-template-columns: repeat(var(--features-grid-columns), [col-start] 1fr);
    }
  }
}

@supports (display: grid) {
  @media (min-width: 1100px) {
    .features {
      grid-column-end: 9;
      --features-grid-columns: 7;
    }
  }
}
See the Pen Design Systems and CSS Grid, 10 by Stuart Robson (@sturobson) on CodePen.

Laying out the parts
Looking at the spec and reading several articles I feel there are two ways that I could layout the text of this component on the grid.
We could use the grid-column shorthand that incorporates grid-column-start and grid-column-end or we can make use of grid-template-areas.
grid-template-areas allow for a nice visual way of representing how the parts of the component would be laid out. We can take the the mock of the features on the grid and represent them in text in our CSS.

Within the .features  rule we can add the relevant grid-template-areas value to represent the above.
.features {
  display: grid;
  grid-template-columns: repeat(var(--features-grid-columns), [col-start] 1fr);
  grid-template-areas:
   ". title     title     title     title     title    title"
   ". subtitle  subtitle  subtitle  subtitle  subtitle .    "
   ". content   content   content   content   .        .    "
   ". list      list      list      .         .        .    "
   ". .         .         .         link      link     link ";
}

In order to make the variant of the component we would have to create the grid-template-areas for that component too.
We then need to tell each element of the component in what grid-area it should be placed within the grid.
.features__title { grid-area: title; }
.features__subtitle { grid-area: subtitle; }
.features__content { grid-area: content; }
.features__list { grid-area: list; }
.features__link { grid-area: link; }
See the Pen Design Systems and CSS Grid, 12 by Stuart Robson (@sturobson) on CodePen.

The other way would be to use the grid-column shorthand and the grid-column-start and grid-column-end we have used previously.
.features .features__title {
  grid-column: col-start 2 / span 6;
}
.features .features__subtitle {
  grid-column: col-start 2 / span 5;
}
.features .features__content {
  grid-column: col-start 2 / span 4;
}
.features .features__list {
  grid-column: col-start 2 / span 4;
}
.features .features__link {
  grid-column: col-start 5 / span 3;
}
For the variant of the component we can use the grid-column-start property as it will inherit the span defined in the grid-column shorthand.
.features:nth-of-type(even) .features__title {
  grid-column-start: col-start 1;
}
.features:nth-of-type(even) .features__subtitle {
  grid-column-start: col-start 1;
}
.features:nth-of-type(even) .features__content {
  grid-column-start: col-start 3;
}
.features:nth-of-type(even) .features__list {
  grid-column-start: col-start 3;
}
.features:nth-of-type(even) .features__link {
  grid-column-start: col-start 1;
}
See the Pen Design Systems and CSS Grid, 14 by Stuart Robson (@sturobson) on CodePen.

I think, for now, we will go with using grid-column properties rather than grid-template-areas. The repetition needed for creating the variant feels too much where we can change the grid-column-start instead, keeping the components elements layout properties tied a little closer to the elements rather than the grid.
Some additional decisions
The current component library has existing styles for titles, subtitles, lists, paragraphs of text and calls to action. These are name-spaced so that they shouldn’t clash with any other components. Looking forward there will be a chance that other products adopt the component library, but they may bring their own styles for titles, subtitles, etc.
One way that we could write our code now for that near future possibility is to make sure our classes are working hard. Using class-attribute selectors we can target part of the class attributes that we know the elements in the component will have using *=.
.features [class*="title"]  {
  grid-column: col-start 2 / span 6;
}
.features [class*="subtitle"] {
  grid-column: col-start 2 / span 5;
}
.features [class*="content"] {
  grid-column: col-start 2 / span 4;
}
.features [class*="list"] {
  grid-column: col-start 2 / span 4;
}
.features [class*="link"]  {
  grid-column: col-start 5 / span 3;
}
See the Pen Design Systems and CSS Grid, 15 by Stuart Robson (@sturobson) on CodePen.

Although the component we have created have a title, subtitle, paragraphs, a list, and a call to action there may be a time where one ore more of these is not required or available. One thing I found out is that if the element doesn’t exist then grid will not create space for it. This may be obvious, but it can be really helpful in making a nice malleable component.
We have only looked at columns, as existing components have their own spacing for the vertical rhythm of the page we don’t really want to have them take up equal space in the component and just take up the space as needed. We can do this by adding grid-auto-rows: min-content; to our .features. This is useful if you also need your component to take up a height that is more than the component itself.
The grid of the future
From prototyping this new grid and components in CSS Grid, I’ve found it a fantastic way to reimagine how we can create a layout or grid system for our sites. It gives us options to create the same layouts in differing ways that could suit a project and its needs.
It allows us to carry on – if we choose to – using a <div>-based grid but swapping out floats for CSS Grid or to tie it to our components so they have specific places to go depending on what component is being used. Or we could have several ‘grid components’ in our design system that we could use to layout various components throughout a page.
If you find yourself tasked with creating some new components for your design system try it. If you are starting from scratch I believe you really should start with CSS Grid for your layout.
It really feels like the possibilities are endless in terms of layout for the web.
Resources
Here are just a few resources I have pawed over these last few weeks whilst getting acquainted with CSS Grid.

A collection of CodePens from this article
Grid by Example from Rachel Andrew
A Complete Guide to CSS Grid on Codrops from Hui Jing Chen
Rachel Andrew’s Blog Archive tagged: cssgrid
CSS Grid Layout Examples
MDN’s CSS Grid Layout
A Complete Guide to Grid from CSS-Tricks
CSS Grid Layout Module Level 1 Specification


title: Jobs-to-Be-Done in Your UX Toolbox
year: 2017
author: Steph Troeth
author_slug: stephtroeth
published: 2017-12-04T00:00:00+00:00
url: https://24ways.org/2017/jobs-to-be-done-in-your-ux-toolbox/
topic: ux
contents:
Part 1: What is JTBD?
The concept of a “job” in “Jobs-To-Be-Done” is neatly encapsulated by a oft-quoted line from Theodore Levitt:

“People want a quarter-inch hole, not a quarter inch drill”.

Even so, Don Norman pointed out that perhaps Levitt “stopped too soon” at what the real customer goal might be. In the “The Design of Everyday Things”, he wrote:

“Levitt’s example of the drill implying that the goal is really a hole is only partially correct, however. When people go to a store to buy a drill, that is not their real goal. But why would anyone want a quarter-inch hole? Clearly that is an intermediate goal. Perhaps they wanted to hang shelves on the wall. Levitt stopped too soon. Once you realize that they don’t really want the drill, you realize that perhaps they don’t really want the hole, either: they want to install their bookshelves. Why not develop methods that don’t require holes? Or perhaps books that don’t require bookshelves.”

In other words, a “job” in JTBD lingo is a way to express a user need or provide a customer-centric problem frame that’s independent of a solution. As Tony Ulwick says:

“A job is stable, it doesn’t change over time.”

An example of a job is “tiding you over from breakfast to lunch.” You could hire a donut, a flapjack or a banana for that mid-morning snack—whatever does the job. If you can arrive at a clearly identified primary job (and likely some secondary ones too), you can be more creative in how you come up with an effective solution while keeping the customer problem in focus.
The team at Intercom wrote a book on their application of JTBD. In it, Des Traynor cleverly characterised how JTBD provides a different way to think about solutions that compete for the same job:                                

“Economy travel and business travel are both capable candidates applying for [the job: Get me face-to-face with my colleague in San Francisco], though they’re looking for significantly different salaries. Video conferencing isn’t as capable, but is willing to work for a far smaller salary. I’ve a hiring choice to make.”

So far so good: it’s relatively simple to understand what a job is, once you understand how it’s different from a “task”.  Business consultant and Harvard professor Clay Christensen talks about the concept of “hiring” a product to do a “job”, and firing it when something better comes along. If you’re a company that focuses solutions on the customer job, you’re more likely to succeed. You’ll find these concepts often referred to as “Jobs-to-be-Done theory”. But the application of Jobs-to-Be-Done theory is a little more complicated; it comprises several related approaches.
I particularly like Jim Kalbach’s description of how JTBD is a “lens through which to understand value creation”. But it is also more. In my view, it’s a family of frameworks and methods—and perhaps even a philosophy.
Different facets in a family of frameworks
JTBD has its roots in market research and business strategy, and so it comes to the research table from a slightly different place compared to traditional UX or design research—we have our roots in human-computer interaction and ergonomics. I’ve found it helpful to keep in mind is that the application of JTBD theory is an evolving beast, so it’s common to find contradictions across different resources. My own use of it has varied from project to project. In speaking to others who have adopted it in different measures, it seems that we have all applied it in somewhat multifarious ways. As we like to often say in interviews: there are no wrong answers.
Outcome Driven Innovation
Tony Ulwick’s version of the JTBD history began with Outcome Driven Innovation (ODI), and this approach is best outlined in his seminal article published in the Harvard Business Review in 2002.  To understand his more current JTBD approach in his new book “Jobs to Be Done: Theory to Practice”, I actually found it beneficial to read his approach in the original 2002 article for a clearer reference point.
In the earlier article, Ulwick presented a rigorous approach that combines interviews, surveys and an “opportunity” algorithm—a sequence of steps to determine the business opportunity. ODI centres around working with “desired outcome statements” that you unearth through interviews, followed by a means to quantify the gap between importance and satisfaction in a survey to different types of customers.  
Since 2008, Ulwick has written about using job maps to make sense of what the customer may be trying to achieve. In a recent article, he describes the aim of the activity is “to discover what the customer is trying to get done at different points in executing a job and what must happen at each juncture in order for the job to be carried out successfully.”
A job map is not strictly a journey map, however tempting it is to see it that way. From a UX perspective, is one of many models we can use—and as our research team at Clearleft have found, how we use model can depend on the nature of the jobs we’ve uncovered in interviews and the characteristics of the problem we’re attempting to solve.
Figure 1. Universal job map
Ulwick’s current methodology is outlined in his new book, where he describes a complete end-to-end process: from customer and competitor research to framing market and product strategy.
The Jobs-To-Be-Done Interview
Back in 2013, I attended a workshop by Chris Spiek and Bob Moesta from the ReWired Group on JTBD at the behest of a then-MailChimp colleague, and I came away excited about their approach to product research. It felt different from anything I’d done before and for the first time in years, I felt that I was genuinely adding something new to my research toolbox.
A key idea is that if you focus on the stories of those who switched to you, and those who switch away from you, you can uncover the core jobs through looking at these opposite ends of engagement.
This framework centres around the JTBD interview method, which harnesses the power of a narrative framework to elicit the real reasons why someone “hired” something to do a job—be it something physical like a new coffee maker, or a digital service, such as a to-do list app. As you interview, you are trying to unearth the context around the key moments on the JTBD timeline (Figure 2). A common approach is to begin from the point the customer might have purchased something, back to the point where the thought of buying this thing first occurred to them.
Figure 2. JTBD Timeline
Figure 3. The Four Forces
The Forces Diagram (Figure 3) is a post-interview analysis tool where you can map out what causes customers to switch to something new and what holds them back.
The JTBD interview is effective at identifying core and secondary jobs, as well as some context around the user need. Because this method is designed to extract the story from the interviewee, it’s a powerful way to facilitate recall. Having done many such interviews, I’ve noticed one interesting side effect: participants often remember more details later on after the conversation has formally ended. It is worth scheduling a follow-up phone call or keep the channels open.
Strengths aside, it’s good to keep in mind that the JTBD interview is still primarily an interview technique, so you are relying on the context from the interviewee’s self-reported perspective. For example, a stronger research methodology combines JTBD interviews with contextual research and quantitative methods.  
Job Stories
Alan Klement is credited for coming up with the term “job story” to describe the framing of jobs for product design by the team at Intercom:

“When … I want to … so I can ….”

Figure 4. Anatomy of a Job Story
Unlike a user story that traditionally frames a requirement around personas, job stories frame the user need based on the situation and context. Paul Adams, the VP of Product at Intercom, wrote:

“We frame every design problem in a Job, focusing on the triggering event or situation, the motivation and goal, and the intended outcome. […] We can map this Job to the mission and prioritise it appropriately. It ensures that we are constantly thinking about all four layers of design. We can see what components in our system are part of this Job and the necessary relationships and interactions required to facilitate it. We can design from the top down, moving through outcome, system, interactions, before getting to visual design.”

Systems of Progress
Apart from advocating using job stories, Klement believes that a core tenet of applying JTBD revolves around our desire for “self-betterment”—and that focusing on everyone’s desire for self-betterment is core to a successful strategy.
In his book, Klement takes JTBD further to being a tool for change through applying systems thinking. There, he introduces the systems of progress and how it can help focus product strategy approach to be more innovative.
Coincidentally, I applied similar thinking on mapping systemic change when we were looking to improve users’ trust with a local government forum earlier this year. It’s not just about capturing and satisfying the immediate job-to-be-done, it’s about framing the job so that you can a clear vision forward on how you can help your users improve their lives in the ways they want to.
This is really the point where JTBD becomes a philosophy of practice.
Part 2: Mixing It Up
There has been some misunderstanding about how adopting JTBD means ditching personas or some of our existing design tools or research techniques. This couldn’t have been more wrong.
Figure 5: Jim Kalbach’s JTBD model
Jim Kalbach has used Outcome-Driven Innovation for around 10 years. In a 2016 article, he presents a synthesised model of how to think about that has key elements from ODI, Christensen’s theories and the structure of the job story.
More interestingly, Kalbach has also combined the use of mental models with JTBD.
Claire Menke of UDemy has written a comprehensive article about using personas, JTBD and customer journey maps together in order to communicate more complete story from the users’ perspective. Claire highlights an especially interesting point in her article as she described her challenges:
“After much trial and error, I arrived at a foundational research framework to suit every team’s needs — allowing everyone to share the same holistic understanding, but extract the type of information most applicable to their work.”
In other words, the organisational context you are in likely can dictate what works best—after all the goal is to arrive at the best user experience for your audiences. Intercom can afford to go full-on on applying JTBD theory as a dominant approach because they are a start-up, but a large company or organisation with multiple business units may require a mix of tools, outputs and outcomes.
JTBD is an immensely powerful approach on many fronts—you’ll find many different references that lists the ways you can apply JTBD. However, in the context of this discussion, it might also be useful to we examine where it lies in our models of how we think about our UX and product processes.
JTBD in the UX ecosystem
Figure 6. The Elements of User Experience (source)
There are many ways we have tried to explain the UX discipline but I think Jesse James Garrett’s Elements of User Experience is a good place to begin.
I sometimes also use little diagram to help me describe the different levels you might work at when you work through the complexity of designing and developing a product. A holistic UX strategy needs to address all the different levels for a comprehensive experience: your individual product UI, product features, product propositions and brand need to have a cohesive definition.
Figure 7. Which level of product focus?
We could, of course, also think about where it fits best within the double diamond.
Again, bearing in mind that JTBD has its roots in business strategy and market research, it is excellent at clarifying user needs, defining high-level specifications and content requirements. It is excellent for validating brand perception and value proposition —all the way down to your feature set. In other words, it can be extremely powerful all the way through to halfway of the second diamond. You could quite readily combine the different JTBD approaches because they have differences as much as overlaps. However, JTBD generally starts getting a little difficult to apply once we get to the details of UI design.
The clue lies in JTBD’s raison d’être: a job statement is solution independent. Hence, once we get to designing solutions, we potentially fall into a existential black hole.
That said, Jim Kalbach has a quick case study on applying JTBD to content design tucked inside the main article on a synthesised JTBD model. Alan Klement has a great example of how you could use UI to resolve job stories. You’ll notice that the available language of “jobs” drops off at around that point.
Job statements and outcome statements provide excellent “mini north-stars” as customer-oriented focal points, but purely satisfying these statements would not necessarily guarantee that you have created a seamless and painless user experience.
Playing well with others
You will find that JTBD plays well with Lean, and other strategy tools like the Value Proposition Canvas. With every new project, there is potential to harness the power of JTBD alongside our established toolbox.
When we need to understand complex contexts where cultural or socioeconomic considerations have to be taken into account, we are better placed with combining JTBD with more anthropological approaches. And while we might be able to evaluate if our product, website or app satisfies the customer jobs through interviews or surveys, without good old-fashioned usability testing we are unlikely to be able to truly validate why the job isn’t being represented as it should. In this case, individual jobs solved on the UI can be set up as hypotheses to be proven right or wrong. 
The application of Jobs-to-be-Done is still evolving. I’ve found it to be very powerful and I struggle to remember what my UX professional life was like before I encountered it—it has completely changed my approach to research and design.
The fact JTBD is still evolving as a practice means we need to be watchful of dogma—there’s no right way to get a UX job done after all, it nearly always depends. At the end of the day, isn’t it about having the right tool for the right job?


title: Cascading Web Design with Feature Queries
year: 2017
author: Chen Hui Jing
author_slug: chenhuijing
published: 2017-12-01T00:00:00+00:00
url: https://24ways.org/2017/cascading-web-design/
topic: code
contents:
Feature queries, also known as the @supports rule, were introduced as an extension to the CSS2 as part of the CSS Conditional Rules Module Level 3, which was first published as a working draft in 2011. It is a conditional group rule that tests if the browser’s user agent supports CSS property:value pairs, and arbitrary conjunctions (and), disjunctions (or), and negations (not) of them.
The motivation behind this feature was to allow authors to write styles using new features when they were supported but degrade gracefully in browsers where they are not. Even though the nature of CSS already allows for graceful degradation, for example, by ignoring unsupported properties or values without disrupting other styles in the stylesheet, sometimes we need a bit more than that.
CSS is ultimately a holistic technology, in that, even though you can use properties in isolation, the full power of CSS shines through when used in combination. This is especially evident when it comes to building web layouts. Having native feature detection in CSS makes it much more convenient to build with cutting-edge CSS for the latest browsers while supporting older browsers at the same time.
Browser support
Opera first implemented feature queries in November 2012, both Chrome and Firefox had it since May 2013. There have been several articles about feature queries written over the years, however, it seems that awareness of its broad support isn’t that well-known. Much of the earlier coverage on feature queries was not written in English, and perhaps that was a limiting factor.

@supports ― CSSのFeature Queries by Masataka Yakura, August 8 2012
Native CSS Feature Detection via the @supports Rule by Chris Mills, December 21 2012
CSS @supports by David Walsh, April 3 2013
Responsive typography with CSS Feature Queries by Aral Balkan, April 9 2013
How to use the @supports rule in your CSS by Lea Verou, January 31 2014
CSS Feature Queries by Amit Tal, June 2 2014
Coming Soon: CSS Feature Queries by Adobe Web Platform Team, August 21 2014
CSS feature queries mittels @supports by Daniel Erlinger, November 27 2014

As of December 2017, all current major browsers and their previous 2 versions support feature queries. Feature queries are also supported on Opera Mini, UC Browser and Samsung Internet. The only browsers that do not support feature queries are Internet Explorer and Blackberry Mobile, but that may be less of an issue than you might think.

  Can I Use css-featurequeries? Data on support for the css-featurequeries feature across the major browsers from caniuse.com.

Granted, there is still a significant number of organisations that require support of Internet Explorer. Microsoft still continues to support IE11 for the life-cycle of Windows 7, 8 and 10. They have, however, stopped supporting older versions since January 12, 2016. It is inevitable that there will be organisations that, for some reason or another, make it mandatory to support IE, but as time goes on, this number will continue to shrink.
Jen Simmons wrote an extensive article called Using Feature Queries in CSS which discussed a matrix of potential situations when it comes to the usage of feature queries. The following image is a summary of the aforementioned matrix.

The most tricky situation we have to deal with is the box in the top-left corner, which are “browsers that don’t support feature queries, yet do support the feature in question”. For cases like those, it really depends on the specific CSS feature you want to use and a subsequent evaluation of the pros and cons of not including that feature in spite of the fact the browser (most likely Internet Explorer) supports it.
The basics of feature queries
As with any conditional, feature queries operate on boolean logic, in other words, if the query resolves to true, apply the CSS properties within the block, or else just ignore the entire block altogether. The syntax of a simple feature query is as follows:
.selector {
  /* Styles that are supported in old browsers */
}

@supports (property:value) {
  .selector {
    /* Styles for browsers that support the specified property */
  }
}
Note that the parentheses around the property:value pair are mandatory and the rule is invalid without them. Styles that apply to older browsers, i.e. fallback styles, should come first, followed by the newer properties, which are contained within the @supports conditional. Because of the cascade, fallback styles will be overridden by the newer properties in the modern browsers that support them.
main {
  background-color: red;
}

@supports (display:grid) {
  main {
    background-color: green;
  }
}
In this example, browsers that support CSS grid will have a main element with a green background colour because the conditional resolves to true, while browsers that do not support grid will have a main element with a red background colour.
The implication of such behaviour means that we can layer on enhanced styles based on the features we want to use and these styles will show up in browsers that support them. But for those that do not, they will get a more basic look that still works anyway. And that will be our approach moving forward.
Boolean operators for feature queries
The and operator allows us to test for support of multiple properties within a single conditional. This would be useful for cases where the desired output requires multiple cutting-edge features to be supported at the same time to work. All the property:value pairs listed in the conditional must resolve to true for the styles within the rule to be applied.
@supports (transform: rotate(45deg)) and
          (writing-mode: vertical-rl) {
  /* Some CSS styles */
}
The or operator allows us to list multiple property:value pairs in the conditional and as long as one of them resolves to true, the styles within the block will be applied. A relevant use-case would be for properties with vendor-prefixes.
@supports (background: -webkit-gradient(linear, left top, left bottom, from(white), to(black))) or
          (background: -o-linear-gradient(top, white, black)) or
          (background: linear-gradient(to bottom, white, black)) {
  /* Some CSS styles */
}
The not operator negates the resolution of the property:value pair in the conditional, resolving to false when the property is supported and vice versa. This is useful when there are two distinct sets of styles to be applied depending on the support of a specific feature. However, we do need to keep in mind the case where a browser does not support feature queries, and handle the styles for those browsers accordingly.
@supports not (shape-outside: polygon(100% 80%,20% 0,100% 0)) {
  /* Some CSS styles */
}
To avoid confusion between and and or, these operators must be explicitly declared as opposed to using commas or spaces. To prevent confusion caused by precedence rules, and, or and not operators cannot be mixed without a layer of parentheses.
This rule is not valid and the styles within the block will be ignored.
@supports (transition-property: background-color) or
          (animation-name: fade) and
          (transform: scale(1.5)) {
  /* Some CSS styles */
}
To make it work, parentheses must be added either around the two properties adjacent to the or or the and operator like so:
@supports ((transition-property: background-color) or
          (animation-name: fade)) and
          (transform: scale(1.5)) {
  /* Some CSS styles */
}
@supports (transition-property: background-color) or
          ((animation-name: fade) and
          (transform: scale(1.5))) {
  /* Some CSS styles */
}
The current specification states that whitespace is required after a not and on both sides of an and or or, but this may change in a future version of the specification. It is acceptable to add extra parentheses even when they are not needed, but omission of parentheses is considered invalid.
Cascading web design
I’d like to introduce the concept of cascading web design, an approach made possible with feature queries. Browser update cycles are much shorter these days, so new features and bug fixes are being pushed out a lot more frequently as compared to the early days of the web.
With the maturation of web standards, browser behaviour is less unpredictable than before, but each browser will still have their respective quirks. Chances are, the latest features will not ship across all browsers at the same time. But you know what? That’s perfectly fine. If we accept this as a feature of the web, instead of a bug, we’ve just opened up a lot more web design possibilities.
The following example is a basic, responsive grid layout of items laid out with flexbox, as viewed on IE11.

We can add a block of styles within an @supports rule to apply CSS grid properties for browsers that support them to enhance this layout, like so:

The web is not a static medium. It is dynamic and interactive and we manipulate this medium by writing code to tell the browser what we want it to do. Rather than micromanaging the pixels in our designs, maybe it’s time we cede control of our designs to the browsers that render them. This means being okay with your designs looking different across browsers and devices.
As mentioned earlier, CSS works best when various properties are combined. It’s one of those things whose whole is greater than the sum of its parts. So feature queries, when combined with media queries, allow us to design layouts that are most effective in the environment they have to perform in.
Such an approach requires interpolative thinking, on multiple levels. As web designers and developers, we don’t just think in one fixed dimension, we get to think about how our design will morph on a narrow screen, or on an older browser, in addition to how it will appear on a browser with the latest features.
In the following example, the layout on the left is what IE11 users will see, the one in the middle is what Firefox users will see, because Firefox doesn’t support CSS shapes yet, but once it does, it will then look like the layout on the right, which is what Chrome users see now.

With the release of CSS Grid this year, we’ve hit another milestone in the evolution of the web as a medium. The beauty of the web is its backwards compatibility and generous fault tolerance. Browser features are largely additive, holding onto the good parts and building on top of them, while deprecating the bits that didn’t work well.
Feature queries allow us to progressively enhance our CSS, establishing a basic level of user experience across the widest range of browsers, while building in more advanced functionality for browsers who can use them. And hopefully, this will allow more of us to create designs that truly embrace the nature of the web.


title: Why Design Systems Fail
year: 2017
author: Una Kravets
author_slug: unakravets
published: 2017-12-14T00:00:00+00:00
url: https://24ways.org/2017/why-design-systems-fail/
topic: process
contents:
Design systems are so hot right now, and for good reason. They promote a modular approach to building a product, and ensure organizational unity and stability via reusable code snippets and utility styles. They make prototyping a breeze, and provide a common language for both designers and developers.
A design system is a culmination of several individual components, which can include any or all of the following (and more):

Style guide or visual pattern library
Design tooling (e.g. Sketch Library)
Component library (where the components live in code)
Code usage guidelines and documentation
Design usage documentation
Voice and tone guideline
Animation language guideline

Design systems are standalone (internal or external) products, and have proven to be very effective means of design-driven development. However, in order for a design system to succeed, everyone needs to get on board.
I’d like to go over a few considerations to ensure design system success and what could hinder that success.
Organizational Support
Put simply, any product, including internal products, needs support. Something as cross-functional as a design system, which spans every vertical project team, needs support from the top and bottom levels of your organization. 
What I mean by that is that there needs to be top-level support from project managers up through VP’s to see the value of a design system, to provide resources for its implementation, and advocate for its use company-wide. This is especially important in companies where such systems are being put in place on top of existing, crufty codebases, because it may mean there needs to be some time and effort put in the calendar for refactoring work.
Support from the bottom-up means that designers and engineers of all levels also need to support this system and feel responsibility for it. A design system is an organization’s product, and everyone should feel confident contributing to it. If your design system supports external clients as well (such as contractors), they too can become valuable teammates.
A design system needs support and love to be nurtured and to grow. It also needs investment.
Investment
To have a successful design system, you need to make a continuous effort to invest resources into it. I like to compare this to working out.
You can work out intensely for 3 months and see some gains, but once you stop working out, those will slowly fade away. If you continue to work out, even if its less often than the initial investment, you’ll see yourself maintaining your fitness level at a much higher rate than if you stopped completely. 
If you invest once in a design system (say, 3 months of overhauling it) but neglect to keep it up, you’ll face the same situation. You’ll see immediate impact, but that impact will fade as it gets out of sync with new designs and you’ll end up with strange, floating bits of code that nobody is using. Your engineers will stop using it as the patterns become outdated, and then you’ll find yourself in for another round of large investment (while dreading going through the process since its fallen so far out of shape).

With design systems, small incremental investments over time lead to big gains overall.

With this point, I also want to note that because of how they scale, design systems can really make a large impact across the platform, making it extremely important to really invest in things like accessibility and solid architecture from the start. You don’t want to scale a brittle system that’s not easy to use.
Take care of your design systems, and keep working on them to ensure their effectiveness. One way to ensure this is to have a dedicated team working on this design system, managing tickets and styling updates that trickle out to the rest of your company.
Responsibility
With some kind of team to act as an owner of a design system, whether it be the design team, engineering team, or a new team
made of both designers and engineers (the best option), your company is more likely to keep a relevant, up-to-date system that doesn’t break.
This team is responsible for a few things:

Helping others get set up on the system (support)
Designing and building components (development)
Advocating for overall UI consistency and adherence (evangelism)
Creating a rollout plan and update system (product management)

As you can see, these are a lot of roles, so it helps to have multiple people on this team, at least part of the time, if you can. One thing I’ve found to be effective in the past is to hold office hours for coworkers to book slots within to help them get set up and to answer any questions about using the system. Having an open Slack channel also helps for this sort of thing, as well as for bringing up bugs/issues/ideas and being an channel for announcements like new releases.
Communication
Once you have resources and a plan to invest in a design system, its really important that this person or team acts as a bridge between design and engineering. Continuous communication is really important here, and the way you communicate is even more important.
Remember that nobody wants to be told what to do or prescribed a solution, especially developers, who are used to a lot of autonomy (usually they get to choose their own tools at work). Despite how much control the other engineers have on the process, they need to feel like they have input, and feel heard.
This can be challenging, especially since ultimately, some party needs to be making a final decision on direction and execution. Because it’s a hard balance to strike, having open communication channels and being as transparent as possible as early as possible is a good start.
Buy-in
For all of the reasons we’ve just looked over, good communication is really important for getting buy-in from your users (the engineers and designers), as well as from product management.

Building and maintaining a design system is surprisingly a lot of people-ops work.

To get buy-in where you don’t have a previous concensus that this is the right direction to take, you need to make people want to use your design system. A really good way to get someone to want to use a product is to make it the path of least resistance, to show its value.
Gather examples and usage wins, because showing is much more powerful than telling.
If you can, have developers use your product in a low-stakes situation where it provides clear benefits. Hackathons are a great place to debut your design system. Having a hackathon internally at DigitalOcean was a perfect opportunity to:

Evangelize for the design system
See what people were using the component library for and what they were struggling with (excellent user testing there)
Get user feedback afterward on how to improve it in future iterations
Let people experience the benefits of using it themselves

These kinds of moments, where people explore on their own are where you can really get people on your side and using the design system, because they can get their hands on it and draw their own conclusions (and if they don’t love it — listen to them on how to improve it so that they do). We don’t always get so lucky as to have this sort of instantaneous user feedback from our direct users.
Architecture
I briefly mentioned the scalable nature of design systems. This is exactly why it’s important to develop a solid architecture early on in the process. Build your design system with growth and scalability in mind. What happens if your company acquires a new product? What happens when it develops a new market segment? How can you make sure there’s room for customization and growth?
A few things we’ve found helpful include:
Namespacing
Use namespacing to ensure that the system doesn’t collide with existing styles if applying it to an existing codebase. This means prefixing every element in the system to indicate that this class is a part of the design system. To ensure that you don’t break parts of the existing build (which may have styled base elements), you can namespace the entire system inside of a parent class. Sass makes this easy with its nested structure. 
This kind of namespacing wouldn’t be necessary per se on new projects, but it is definitely useful when integrating new and old styles.
Semantic Versioning
I’ve used Semantic Versioning on all of the design systems I’ve ever worked on. Semantic versioning uses a system of Major.Minor.Patch for any updates. You can then tag released on Github with versioned updates and ensure that someone’s app won’t break unintentionally when there is an update, if they are anchored to a specific version (which they should be).
We also use this semantic versioning as a link with our design system assets at DigitalOcean (i.e. Sketch library) to keep them in sync, with the same version number corresponding to both Sketch and code.
Our design system is served as a node module, but is also provided as a series of built assets using our CDN for quick prototyping and one-off projects. For these built assets, we run a deploy script that automatically creates folders for each release, as well as a latest folder if someone wanted the always-up-to-date version of the design system. 
So, semantic versioning for the system I’m currently building is what links our design system node module assets, sketch library assets, and statically built file assets.
The reason we have so many ways of consuming our design system is to make adoption easier and to reduce friction.
Friction
A while ago, I posed the question of why design systems become outdated and unused, and a major conclusion I drew from the conversation was:

“If it’s harder for people to use than their current system, people just won’t use it”

You have to make your design system the path of least resistance, lowering cognitive overhead of development, not adding to it. This is vital. A design system is intended to make development much more efficient, enforce a consistent style across sites, and allow for the developer to not worry as much about small decisions like naming and HTML semantics. These are already sorted out for them, meaning they can focus on building product.
But if your design system is complicated and over-engineered, they may find it frustrating to use and go back to what they know, even if its not the best solution. If you’re a Sass expert, and base your system on complex mixins and functions, you better hope your user (the developer) is also a Sass expert, or wants to learn. This is often not the case, however. You need to talk to your audience.
With the DigitalOcean design system, we provide a few options:
Option 1
Users can implement the component library into a development environment and use Sass, select just the components they want to include, and extend the system using a hook-based system. This is the most performant and extensible output. Only the components that are called upon are included, and they can be easily extended using mixins.
But as noted earlier, not everyone wants to work this way (including Sass a dependency and potentially needing to set up a build system for it and learn a new syntax). There is also the user who just wants to throw a link onto their page and have it look nice, and thats where our versioned built assets come in.
Option 2
With Option 2, users pull in links that are served via a CDN that contain JS, CSS, and our SVG icon library. The code is a bit bigger than the completely customized version, but often this isn’t the aim when people are using Option 2.
Reducing friction for adoption should be a major goal of your design system rollout.
Conclusion
Having a design system is really beneficial to any product, especially as it grows. In order to have an effective system, it’s important to primarily always keep your user in mind and garner support from your entire company. Once you have support and acceptance, this system will flourish and grow. Make sure someone is responsible for it, and make sure its built with a solid foundation from the start which will be carefully maintained toward the future. Good luck, and happy holidays!


title: Getting Hardboiled with CSS Custom Properties
year: 2017
author: Andy Clarke
author_slug: andyclarke
published: 2017-12-13T00:00:00+00:00
url: https://24ways.org/2017/getting-hardboiled-with-css-custom-properties/
topic: code
contents:
Custom Properties are a fabulous new feature of CSS and have widespread support in contemporary browsers. But how do we handle browsers without support for CSS Custom Properties? Do we wait until those browsers are lying dead in a ditch before we use them? Do we tool up and prop up our CSS using a post-processor? Or do we get tough? Do we get hardboiled?
Previously only pre-processing tools like LESS and Sass enabled developers to use variables in their stylesheets, but now Custom Properties have brought variables natively to CSS.
How do you write a custom property? It’s hardly a mystery. Simply add two dashes to the start of a style rule. Like this:
--color-text-default : black;
If you’re more the underscore type, try this:
--color_text_default : black;
Hyphens or underscores are allowed in property names, but don’t be a chump and try to use spaces. 
Custom property names are also case-sensitive, so --color-text-default and --Color_Text_Default are two distinct properties.
To use a custom property in your style rules, var() tells a browser to retrieve the value of a property. In the next example, the browser retrieves the black colour from the color-text-default variable and applies it to the body element:
body {
    color : var(--color-text-default); 
}
Like variables in LESS or Sass, CSS Custom Properties mean you don’t have to be a dumb mug and repeat colour, font, or size values multiple times in your stylesheets. Unlike a preprocessor variable though, CSS Custom Properties use the cascade, can be modified by media queries and other state changes, and can also be manipulated by Javascript.
(Serg Hospodarets wrote a fabulous primer on CSS Custom Properties where he dives deeper into the code and possible applications.)
Browser support
Now it’s about this time that people normally mention browser support. So what about support for CSS Custom Properties? Current versions of Chrome, Edge, Firefox, Opera, and Safari are all good. Internet Explorer 11 and before? Opera Mini? Nasty.
Sound familiar?

  Can I Use css-variables? Data on support for the css-variables feature across the major browsers from caniuse.com.

Not to worry, we can manually check for Custom Property support in a browser by using an @support directive, like this:
--color-text-default : black;

body {
    color : black;  
}

@supports ((--foo : bar)) {
    body {
        color : var(--color-text-default); 
    }
}
In that example we first set body element text to black and then override that colour with a Custom Property value when the browser supports our fictitious foo bar variable.
Substitutions
If we reference a variable that hasn’t been defined, that won’t be a problem as browsers are smart enough to ignore the value altogether. If we need a cast iron alibi, use substitutions to specify a fall-back value.
body {
    color : var(--color-text-default, black); 
}
Substitutions are similar to font stacks in that they contain a comma separated list of values. If there’s no value associated with a property, a browser will ignore it and move onto the next value in the list.
Post-processing
Of course we could use a post-processor plugin to turn Custom Properties into plain CSS, but hang on one goddam minute kiddo.
Haven’t we been down this road before? Didn’t we engineer elaborate workarounds to enable us to use ‘advanced’ CSS3 properties like border-radius, CSS columns, and Flexbox in the past? We did what we had to do to get the job done, but came away feeling dirty.
I think there’s a better way, one that allows us to enjoy the benefits of CSS Custom Properties in browsers that support them, while providing an appropriate, but not identical experience, for people who use less capable browsers. Guess what, I’ve been down this road before too. 
2Tone Stuff & Nonsense
When Internet Explorer 6 was the big dumb browser everyone hated, I served two different designs on my website. 
For the modern browsers of the time, mod arrows and targets were everywhere in glorious red, white, and blue, and I implemented all of them using CSS attribute selectors which were considered advanced at the time:
[class="banner"] {
    background-colour : red; 
}
Internet Explorer 6 ignored any selectors it didn’t understand, so people using that browser saw a simpler black and white, 2Tone-based design that I’d implemented for them using class selectors:
.banner {
    background-colour : black; 
}

[class="banner"] {
    background-colour : red; 
}

You don’t have to be a detective to find out that most people thought I’d lost my wits, but Microsoft even used my website as a reference when they tested attribute selectors in Internet Explorer 7. They did, as I suggested, “Stomp to da betta browser.”
Dumb browsers look the other way
So how does this approach relate to tackling any lack of support for CSS Custom Properties? How can we take advantage of them without worrying about browsers with no support and having to implement complex workarounds, or spending hours specifying fallbacks that perfectly match our designs?
Turns out, the answer is built into CSS, and always has been, because when browsers don’t know what they’re looking at, they look away. 
All we have to do is first specify values for a simpler design first, and then follow that up with the values in our CSS Custom Properties:
body {
    color : black;
    color : var(--color-text-default, black); 
}
All browsers understand the first value (black,) and if they‘re smart enough to understand the second (var(--color-text-default)), they’ll use it and override the first. If they’re too damn stupid to understand the custom property value, they’ll ignore it. Nobody dies.
Repeat this for every style that contains a variable, baking an alternative, perhaps simpler design into your stylesheets for people who use less capable browsers, just like I did with Stuff & Nonsense.
Conclusion
I doubt that anyone agrees with presenting a design that looks broken or unloved—and I’m not advocating for that—but websites need not look the same in every browser. We can use substitutions to present a simpler design to people using less capable browsers.
The decision when to start using new CSS properties isn‘t always a technical one. Sometimes a change in attitude about browser support is all that’s required. So get tough with dumb browsers and benefit from all the advantages that CSS Custom Properties offer. Get hardboiled.
Resources:

It’s Time To Start Using CSS Custom Properties—Smashing Magazine
Using CSS variables correctly—Mike Riethmuller
Developing Inspired Guides with CSS Custom Properties (variables)—Andy Clarke


title: Want to Break Out of Comparison Syndrome? Do a Media Detox
year: 2017
author: Denise Jacobs
author_slug: denisejacobs
published: 2017-12-19T00:00:00+00:00
url: https://24ways.org/2017/do-a-media-detox/
topic: process
contents:
“Comparison is the thief of joy.”
—Theodore Roosevelt

I grew up in an environment of perpetual creativity and inventiveness. My father Dennis built and flew experimental aircraft as a hobby. During my entire childhood, there was an airplane fuselage in the garage instead of a car. My mother Deloria was a self-taught master artisan who could quickly acquire any skills that it took to work with fabric and weaving. She could sew any garment she desired, and was able to weave intricate wall hangings just by looking at a black and white photos in magazines. My older sister Diane blossomed into a consummate fine artist who drew portraits with uncanny likeness, painted murals, and studied art and architecture. In addition, she loved good food and had a genius for cooking and baking, which converged in her creating remarkable art pieces out of cake that were incredibly delicious to boot. Yes. This was the household in which I grew up.
While there were countless positives to being surrounded by people who were compelled to create, there was also a downside to it. I incessantly compared myself to my parents and older sister and always found myself lacking.
It wasn’t a fair comparison, but tell that to a sensitive kid who wanted to fit in to her family by being creative as well. From my early years throughout my teens, I convinced myself that I would never understand how to build an airplane or at least be as proficient with tools as my father, the aeronautical engineer. Even though my sister was six years older than I was, I lamented that I would never be as good a visual artist as she was. And I marveled at my mother’s seemingly magical ability to make and tailor clothes and was certain that I would never attain her level of mastery.
This habit of comparing myself to others grew over the years, continuing to subtly and effectively undermine my sense of self. I had almost reached an uneasy truce with my comparison habit when social media happened.
As an early adopter of Twitter, I loved staying connected to people I met at tech conferences. However, as I began to realize my aspirations of being an author and a speaker, Twitter became a dreaded hall of mirrors where I only saw distorted reflections of my lack of achievement in other people’s success. Every person announcing a publishing deal caused me to drown under waves of envy over the imagined size of her or his book advance as I struggled to pay my mortgage. Every announcement I read of someone speaking at a conference led to thoughts of, “I wish I were speaking at that conference – I must not be good enough to be invited.” Twitter was fertile ground for my Inner Critic to run rampant.
One day in 2011, my comparisons to people who I didn’t even know rose to a fever pitch. I saw a series of tweets that sparked a wave of self-loathing so profound that I spent the day sobbing and despondent, as I chastised myself for being a failure. I had fallen into the deep pit of Comparison Syndrome, and to return to anything close to being productive took a day or two of painstakingly clawing my way out.
Comparison Syndrome Takes Deficiency Anxiety to Eleven
Do any of these scenarios ring true?

You frequently feel like a failure when viewing the success of others.
You feel dispirited and paralyzed in moving forward with your own work because it will never measure up to what others have done.
You discount your ideas because you fear that they aren’t as good as those of your colleagues or industry peers.

Are you making yourself miserable by thinking thoughts like these?

“I’m surrounded by people who are so good at what they do, how can I possibly measure up?”
“Compared to my partner, my musical ability is childish – and music is no longer fun.”
“Why haven’t I accomplished more by now? My peers are so much more successful than I am.”

Unenviable Envy
Many people use the terms envy and jealousy interchangeably, but they are two distinct emotions. Jealousy is the fear of losing someone to a perceived rival: a threat to an important relationship and the parts of the self that are served by that relationship. Jealousy is always about the relationship between three people. Envy is wanting what another has because of a perceived shortcoming on your part. Envy is always based on a social comparison to another.1
Envy is a reaction to the feeling of lacking something. Envy always reflects something we feel about ourselves, about how we are somehow deficient in qualities, possessions, or success.2 It’s based on a scarcity mentality: the idea that there is only so much to go around, and another person got something that should rightfully be yours.3
A syndrome is a condition characterized by a set of associated symptoms. I call it Comparison Syndrome because a perceived deficiency of some sort – in talent, accomplishments, success, skills, etc. – is what initially sparks it. While at the beginning you may merely feel inadequate, the onset of the syndrome will bring additional symptoms. Lack of self-trust and feelings of low self-worth will fuel increased thoughts of not-enoughness and blindness to your unique brilliance. If left unchecked, Deficiency Anxieties can escalate to full-blown Comparison Syndrome: a form of the Inner Critic in which we experience despair from envy and define ourselves as failures in light of another’s success.
The irony is that when we focus so much on what we lack, we can’t see what we have in abundance that the other person doesn’t have. And in doing so, we block what is our birthright: our creative expression. Envy shackles our creativity, keeps us trapped in place, and prevents forward movement. The Inner Critic in the form of Comparison Syndrome caused by envy blocks us from utilizing our gifts, seeing our path clearly, and reveling in our creative power.
In order to keep a grip on reality and not fall into the abyss of Comparison Syndrome, we’ll quell the compulsion to compare before it happens: we will free the mental bandwidth to turn our focus inward so we can start to see ourselves clearly. 
Break the Compulsion to Compare

“Why compare yourself with others? No one in the entire world can do a better job of being you than you.”
— Krystal Volney, poet and author

At some point in time, many of us succumb to moments of feeling that we are lacking and comparing ourselves unfavorably to others. As social animals, much of our self-definition comes from comparison with others. This is how our personalities develop. We learn this behavior as children, and we grow up being compared to siblings, peers, and kids in the media. Because of this, the belief that somehow, someway, we aren’t good enough becomes deeply ingrained. The problem is that whenever we deem ourselves to be “less than,” our self-esteem suffers. This creates a negative feedback loop where negative thoughts produce strong emotions that result in self-defeating behaviors that beget more negative thoughts.
Couple this cycle with the messages we get from society that only “gifted” people are creative, and it’s no wonder that many of us will fall down the rabbit hole of Comparison Syndrome like I did on that fated day while reading tweets. Comparing ourselves to others is worse than a zero-sum game, it’s a negative-sum game. No one wins, our self-esteem deteriorates, and our creative spark dies out.
With effort, we can break the compulsion to compare and stop the decline into Comparison Syndrome by turning the focus of comparison inward to ourselves and appreciating who we’ve become. But first, we need to remove some of the instances that trigger our comparisons in the first place.
Arrest: Stop the Triggers

“Right discipline consists, not in external compulsion, but in the habits of mind which lead spontaneously to desirable rather than undesirable activities.”
— Bertrand Russell, philosopher

After my Twitter post meltdown, I knew had to make a change. While bolstering my sense of self was clearly a priority, I also knew that my ingrained comparison habit was too strong to resist and that I needed to instill discipline. I decided then and there to establish boundaries with social media.
First, to maintain my sanity, I took this on as my mantra:
“I will not compare myself to strangers on the Internet or acquaintances on Facebook.”
If you find yourself sliding down the slippery slope of social media comparison, you can do the same: repeat this mantra to yourself to help put on the brakes.
Second, in order to reduce my triggers, I stopped reading the tweets of the people I followed. However, I continued to be active on Twitter through sharing information, responding to mentions, crowdsourcing, and direct messaging people. It worked! The only time I’d start to slip into darkness were the rare instances when I would break my rules and look at my Twitstream.
But we can do even more than calm ourselves with helpful mantras. Just like my example of modifying my use of Twitter, and more recently, of separating myself from Facebook, you can get some distance from the media that activates your comparison reflex and start creating the space for other habits that are more supportive to your being to take its place.
Creative Dose: Trigger-free and Happy
Purpose: To stop comparison triggers in their tracks
Mindfulness is a wonderful tool, but sometimes you have to get hardcore and do as much as you can to eliminate distractions so that you can first hear your own thoughts in order to know which ones you need to focus on.
Here are four steps to becoming trigger-free and happier.
Step 1: Make a List
Pay attention when you get the most triggered and hooked.
Is it on Twitter, Facebook, Instagram, or Snapchat?
Is it YouTube, TV shows, or magazines?
Make list of your top triggers.
My primary trigger is:______________________________________
My second trigger is:______________________________________
My third trigger is:______________________________________
Now that you have your list, you need to get an idea just how often you’re getting triggered.
Step 2: Monitor
It’s easy to think that we should track our activity on the computer, but these days, it’s no longer our computer use that is the culprit: most of us access social media and news from our phones. Fortunately, there are apps that will track the usage for both.
Seeing just how much you consume media from either or both will show you how much of an accomplice the use of devices is to your comparison syndrome, and how much you need to modify your behavior accordingly.
For tracking both computer use and tablet use, this app works great:

RescueTime.com tracks app usage and sends a productivity report at the end of the week via email.

For your phone, there are many for either platform.4 Although I recommend fully researching what is available and will work for you best, here are a few recommendations:

For both platforms: Offtime, Breakfree, Checky
For Android only: Flipd, AppDetox, QualityTime, Stay On Task
For iOS only: Moment

Install your app of choice, and see what you find. How much time are you spending on sites or apps that compel you to compare?
Step 3: Just Say No
Now that you know what your triggers are and how much you’re exposing yourself to them, it’s time to say No.
Put yourself on a partial social media and/or media detox for a specified period of time; consider even going for a full media detox.5 I recommend starting with one month.
To help you to fully commit, I recommend writing this down and posting it where you can see it.
I, ___________________, commit to avoiding my comparison triggers 
of ___________________, ___________________, and ___________________ 
for the period of ___________________, 
starting on ___________________ and ending on ___________________ .
To help you out, I’ve created a social media detox commitment sheet for you.
Step 4: Block
When I decided to reduce my use of Twitter and Facebook to break my comparison habit, initially I tried to rely solely on self-discipline, which was only moderately successful. Then I realized that I could use the power of technology to help. Don’t think you have to rely upon sheer willpower to block, or at least limit, your exposure to known triggers. If your primary access to the items that cause you to compare yourself to others is via computers and other digitalia, use these devices to help maintain your mental equilibrium.
Here are some apps and browser extensions that you can use during your media detox to help keep yourself sane and stay away from sites that could throw you into a comparison tailspin.
These apps are installed onto your computer:

RescueTime.com works on both computer and mobile devices, and does a lot more than just prevent you from going to sites that will ruin your concentration, it will also track your apps usage and give you a productivity report at the end of the week.
Focus and SelfControl (Mac-only)

To go right to the source and prevent you from visiting sites through your browser, there are browser extensions.
Not only can you put in the list of the URLs that are your points of weakness, but you can also usually set the times of the day you need the self-control the most.

Google Chrome: StayFocusd, Strict Workflow, and Website Blocker
Firefox: Idderall and Leechblock
Safari: WasteNoTime and MindfulBrowsing
Edge (or Explorer): Unfortunately, there are currently no website blocking extensions for these browsers.

I currently use a browser extension to block me from using Facebook between 9:00am – 6:00pm. It’s been a boon for my sanity: I compare tons less. A bonus is that it’s been terrific for my productivity as well. 
Which tool will you use for your media detox time? Explore them all and then settle upon the one(s) that will work the best for you. Install it and put it to work.
Despite the tool, you will still need to exercise discipline. Resist the urge to browse Instagram or Facebook while waiting for your morning train. You can do it!
Step 5: Relax
Instead of panicking from FOMO (Fear of Missing Out), take comfort from this thought: what you don’t know won’t affect you. Start embracing JOMO (Joy of Missing Out), and the process of rebuilding and maintaining your sanity.
What will you do instead of consuming the media that compels you to
compare? Here are some ideas:

Read a book 
Go for a walk 
Have dinner with a friend 
Go watch a movie 
Learn how to play the harmonica 
Take an improv class

Really, you could do anything. And depending on how much of your time and attention you’ve devoted to media, you could be recapturing a lot of lost moments, minutes, hours, and days.
Step 6: Reconnect
Use your recovered time and attention to focus on your life and reconnect with your true value-driven goals, higher aspirations, and activities that you’ve always wanted to do.

This article is an excerpt from the book Banish Your Inner Critic by Denise Jacobs, and has been reprinted with permission. If you’d like to read more, you can find the book on Amazon.




Shane Parrish, “Mental Model: Bias from Envy and Jealousy,” Farnam Street, accessed February 9, 2017. ↩


Parrish, “Mental Model: Bias from Envy and Jealousy.” ↩


Henrik Edberg, “How to Overcome Envy: 5 Effective Tips,” Practical Happiness Advice That Works | The Positivity Blog, accessed February 9, 2017. ↩


Jeremy Golden, “6 Apps to Stop Your Smartphone Addiction,” Inc.com, accessed February 10, 2017. ↩


Emily Nickerson, “How to Silence the Voice of Doubt,” The Muse, accessed February 8, 2017. ↩


title: All That Glisters
year: 2017
author: Drew McLellan
author_slug: drewmclellan
published: 2017-12-24T00:00:00+00:00
url: https://24ways.org/2017/all-that-glisters/
topic: business
contents:
Tradition has it that at this time of year, families gather together, sit, eat and share stories. It’s an opportunity for the wisdom of the elders to be passed down to the younger members of the tribe. Tradition also has it that we should chase cheese downhill and dunk the nice lady to prove she’s a witch, so maybe let’s not put too much stock in that.
I’ve been building things on the web professionally for about twenty years, and although the web has changed immeasurably, it’s probably not changed as much as I have. While I can happily say I’m not the young (always right, always arrogant) developer that I once was, unfortunately I’m now an approaching-middle-age developer who thinks he’s always right and on top of it is extremely pompous. What can you do? Nature has devised this system with the distinct advantage of allowing us to always be right, and only ever wrong in the future or in the past. So let’s roll with it.
Increasingly, there seems to be a sense of fatigue within our industry. Just when you think you’ve got a handle on whatever the latest tool or technology is, something new comes out to replace it. Suddenly you find that you’ve invested precious time learning something new and it’s already old hat. The pace of change is so rapid, that new developers don’t know where to start, and experienced developers don’t know where it ends. With that in mind, here’s some fireside thoughts from a pompous old developer, that I hope might bring some Christmas comfort.
Reliable and boring beats shiny and new
There are so many new tools, frameworks, techniques, styles and libraries to learn. You know what? You don’t have to use them. You’re not a bad developer if you use Grunt even though others have switched to Gulp or Brunch or Webpack or Banana Sandwich. It’s probably misguided to spend lots of project time messing around with build tool fashions when your so last year build tool is already doing what you need.
Just a little reminder that it’s about 100 times more important what you build than how you build it.— Chris Coyier (@chriscoyier) December 10, 2017

I think it helps if we understand why so many new solutions exist. Most developers are predisposed to enjoy creating new things more than improving established systems. It’s natural, because it’s actually much easier and more exciting to create something new that works exactly how you think it should be than to improve an existing, imperfect solution. Improving and refactoring a system is hard, and it takes real chops, much more than just building something new.
The consequence of this is that new tools appear all the time. A developer will get a fresh new idea of how to tackle a problem – usually out of dissatisfaction with an existing solution, and figure the best way to implement that idea is to build something new around it. Often, that something new will do the same job as something old that already exists; it will just do it in a different way. Sometimes in a better way. Sometimes, just different.
xkcd: Standards
That’s not to say new tools are bad, and it’s not bad that they exist. We shouldn’t be crushing new ideas, and it’s not wrong to adopt a new solution over an old one, but you know what? There’s no imperative to switch right away. The next time you hit a pain point with your current solution, or have time to re-evaluate, check out what’s new and see how the latest generation of tools and technologies can help. There’s no prize for solving problems you don’t have yet, and heading further into the desert in search of water is a survival tactic, not an aspiration.
New is better, but also worse
Software, much like people, is born with a whole lot of potential and not much utility. Newborns — both digital and meaty — are exciting and cute but they also lead to sleepless nights and pools of vomit.
New technology contains lots of useful new features, but it’s also more likely to contain bugs and be subject to more rapid change. Jumping on a new framework is great, right until there are API changes and you need to refactor your entire project to be able to update. More mature solutions have a higher weight of existing projects on their shoulders, and so the need to maintain backward compatibility is stronger. Things still move forward, but in a more controlled way.
So how do we balance the need to move technology forward with the need to provide mature and stable solutions for the projects we work on? I think there’s a couple of good ways to do that.
Get personal
Use all the new shiny tools on your side-projects, personal projects, seasonal throw-aways and anywhere where the stakes are low. If you know you can patch around problems without much consequence, go for it. Build your personal blog on a CMS that stores data in the woven bark of a silver birch. Find where it breaks. Find where it excels. Find yourself if you like. When it comes to high-stakes projects, you’ll hopefully have enough experience to know what you’re getting into.
Focus on the unique problem
That’s not to say you should never risk using a new technology for ‘real’ work. Instead, distinguish the areas of your project where a new technology solves a specifically identified, measurable business objective, verses those where it won’t. 
A brand new web application framework might be fun to use, but are you in the business of solving a web application framework problem?  That new web server made of taffeta might increase static file throughput slightly, but are you in the business of serving static assets, or would it be better to just run up nginx and never have to think about that problem again. (Clue: it’s the nginx one.)
But when it comes to building that live sports interface for keeping fans up to date with the blow-by-blow of the big game, that’s where it might make sense to take a risk on an amazing-looking new JavaScript realtime interface framework. That’s the time to run up a breakthrough new message queue server that can deliver jobs to workers via extrasensory perception and keep the score updates flowing instantaneously. 
Those are the risks worth taking, as those new technologies have the potential to help you solve your core problems in a markedly improved way. Unproven technology is worth the risk if it solves a specific business objective. If it doesn’t, don’t make work for yourself - use something mature and stable.
Pick the right tools
Our job as developers is to solve problems using code, and do so in an effective and responsible way. You’ve been hired to use your expertise in picking the right tools for the job, and a big part of that is weighing up the risk verse the reward of each part of the system. The best tools for the job might be something cutting edge, but ‘best’ can also mean most stable, reliable or easy-to-hire-for.
Go out and learn (and create!) new tools and experiment with them. Understand what problems they solve and what the pitfalls are. Use them in production for low-stakes projects to get real experience, and then once you really know their character, then think about using them when the stakes are higher.
The rest of the time? The tools you’re using now are solid and proven and you know their capabilities and pitfalls well. They might not always be the fashionable candidate, but they often make for a very solid choice.


