<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-gb"><title type="text">24 ways</title>
<subtitle type="text">to impress your friends</subtitle>

<link rel="alternate" type="text/html" href="http://24ways.org/" />
<id>tag:24ways.org,2005:7e1577ceca7ea22e28af5c35ee62927a</id>
<generator uri="http://textpattern.com/" version="4.0.6">Textpattern</generator>
<updated>2009-11-17T07:12:45Z</updated>
<author>
		<name>Drew McLellan</name>
		<email>feeds@allinthehead.com</email>
		<uri>http://24ways.org/</uri>
</author>

<link rel="self" href="http://feeds.feedburner.com/24ways" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
		<author>
			<name>Jeffrey Zeldman</name>
		</author>
		<published>2008-12-24T00:00:06Z</published>
		<updated>2008-12-24T00:00:06Z</updated>
		<title type="html">Recession Tips For Web Designers</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/r41lXp5dxPw/recession-tips-for-web-designers" />
		<id>tag:24ways.org,2008-12-23:7e1577ceca7ea22e28af5c35ee62927a/477559978e59cda03c61eca861b9d70a</id>
		<category term="business" />
		
		<content type="html">
&lt;p&gt;For web designers, there are four keys to surviving bad economic times: do good work, charge a fair price, lower your overhead, and be sure you are communicating with your client. As a reader of 24 ways, you already do good work, so let&amp;#8217;s focus on the rest.&lt;/p&gt;

	&lt;p&gt;I know something about surviving bad times, having started my agency, &lt;a href="http://www.happycog.com/"&gt;Happy Cog&lt;/a&gt;, at the dawn of the dot-com bust. Of course, the recession we&amp;#8217;re in now may end up making the dot-com bust look like the years of bling and gravy. But the bust was rough enough at the time. &lt;/p&gt;

	&lt;p&gt;Bad times are hard on overweight companies and over-leveraged start-ups, but can be kind to freelancers and small agencies. Clients who once had money to burn and big agencies to help them burn it suddenly consider the quality of work more important than the marquee value of the business card. Fancy offices and ten people at every meeting are out. A close relationship with an individual or small team that listens is in.&lt;/p&gt;

	&lt;h3&gt;Thin is in&lt;/h3&gt;

	&lt;p&gt;If you were good in client meetings when you were an employee, print business cards and pick a name for your new agency. Once some cash rolls in, see an accountant. &lt;/p&gt;

	&lt;p&gt;If the one-person entrepreneur model isn&amp;#8217;t you, it&amp;#8217;s no problem. Form a virtual agency with colleagues who complement your creative, technical, and business skills. &lt;a href="http://athleticsnyc.com/"&gt;Athletics&lt;/a&gt; is a Brooklyn-based multi-disciplinary &amp;#8220;art and design collective.&amp;#8221; Talk about low overhead: they don&amp;#8217;t have a president, a payroll, or a pension plan. But that hasn&amp;#8217;t stopped clients like adidas, Nike, &lt;span class="caps"&gt;MTV&lt;/span&gt;, &lt;span class="caps"&gt;HBO&lt;/span&gt;, Disney, &lt;span class="caps"&gt;DKNY&lt;/span&gt;, and Sundance Channel from knocking on their (virtual) doors.&lt;/p&gt;

	&lt;p&gt;Running a traditional business is like securing a political position in Chicago: it costs a fortune. That&amp;#8217;s why bad times crush so many companies. But you are a creature of the internets. You don&amp;#8217;t need an office to do great work. I ran Happy Cog out of my apartment for far longer than anyone realized. My clients, when they learned my secret, didn&amp;#8217;t care. &lt;/p&gt;

	&lt;p&gt;Keep it lean: if you can budget your incoming freelance money, you don&amp;#8217;t have to pay yourself a traditional salary. Removing the overhead associated with payroll means more of the budget stays in your pocket, enabling you to price your projects competitively, while still within industry norms. (Underpricing is uncool, and clients who knowingly choose below-market-rate vendors tend not to treat those vendors with respect.)&lt;/p&gt;

	&lt;h3&gt;Getting gigs&lt;/h3&gt;

	&lt;p&gt;Web design is a people business. If things are slow, email former clients. If you just lost your job, email former agency clients with whom you worked closely to inform them of your freelance business and find out how they&amp;#8217;re doing. Best practice: focus the email on wishing them a happy holiday and asking how they&amp;#8217;re doing. Let your email signature file tell them you&amp;#8217;re now the president of Your Name Design. Leading with the fact that you just lost your job may earn sympathy (or commiseration: the client may have lost her job, too) but it&amp;#8217;s not exactly a sure-fire project getter.&lt;/p&gt;

	&lt;p&gt;The qualities that help you land a web design project are the same in good times or bad. Have a story to tell about the kind of services you offer, and the business benefits they provide. (If you design with web standards, you already have one great story line. What are the others?) &lt;/p&gt;

	&lt;p&gt;Don&amp;#8217;t be shy about sharing your story, but don&amp;#8217;t make it the focus of the meeting. The client is the focus. Before you meet her, learn as much as you can about her users, her business, and her competitors. At the very least, read her site&amp;#8217;s About pages, and spend some quality time with Google. &lt;/p&gt;

	&lt;p&gt;Most importantly, go to the meeting knowing how much you &lt;em&gt;don&amp;#8217;t&lt;/em&gt; know. Arrive curious, and armed with questions. Maintain eye contact and keep your ears open. If a point you raise causes two people to nod at each other, follow up on that point, don&amp;#8217;t just keep grinding through your Keynote presentation. &lt;/p&gt;

	&lt;p&gt;If you pay attention and think on your feet, it tells the potential client that they can expect you to listen and be flexible. (Clients are like unhappy spouses: they&amp;#8217;re dying for someone to finally listen.) If you stick to a prepared presentation, it might send the message that you are inflexible or nervous or both. &amp;#8220;Nervous&amp;#8221; is an especially bad signal to send. It indicates that you are either dishonest or inexperienced. Neither quality invites a client to sign on. Web design is a people business for the client, too: they should feel that their interactions with you will be pleasant and illuminating. And that you&amp;#8217;ll listen. Did I mention that?&lt;/p&gt;

	&lt;h3&gt;Give it time&lt;/h3&gt;

	&lt;p&gt;Securing clients takes longer and requires more effort in a recession. If two emails used to land you a gig, it will now take four, plus an in-person meeting, plus a couple of follow-up calls. This level of salesmanship is painful to geeks and designers, who would rather spend four hours kerning type or debugging a style sheet than five minutes talking business on the telephone. I know. I&amp;#8217;m the same way. But we must overcome our natural shyness and inwardness if we intend not to fish our next meal out of a neighbor&amp;#8217;s garbage can. &lt;/p&gt;

	&lt;p&gt;As a bonus, once the recession ends, your hard-won account management skills will help you take your business to the next level. By the time jobs are plentiful again, you may not want to work for anyone but yourself. You&amp;#8217;ll be a captain of our industry. And talented people will be emailing to ask you for a job.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=r41lXp5dxPw:Qb0jMiF8Utk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=r41lXp5dxPw:Qb0jMiF8Utk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=r41lXp5dxPw:Qb0jMiF8Utk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=r41lXp5dxPw:Qb0jMiF8Utk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=r41lXp5dxPw:Qb0jMiF8Utk:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/r41lXp5dxPw" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://zeldman.com/"&gt;Jeffrey Zeldman&lt;/a&gt; rounds of our 2008 season with some hard-earned advice for web designers and developers to take into 2009. As the economic climate gets tougher and budgets get cut, our skills need to extend to staying in work, not just completing work won.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/recession-tips-for-web-designers</feedburner:origLink></entry>
<entry>
		<author>
			<name>Andy Clarke</name>
		</author>
		<published>2008-12-23T00:00:07Z</published>
		<updated>2008-12-23T00:00:07Z</updated>
		<title type="html">Contract Killer</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/8XeMn7rGExI/contract-killer" />
		<id>tag:24ways.org,2008-12-22:7e1577ceca7ea22e28af5c35ee62927a/a8ae5f18ae72b214f8b638987b3342bd</id>
		<category term="business" />
		
		<content type="html">
&lt;p&gt;When times get tough, it can often feel like there are no good people left in the world, only people who haven&amp;#8217;t yet turned bad. These bad people will go back on their word, welch on a deal, put themselves first. You owe it to yourself to stay on top. You owe it to yourself to ensure that no matter how bad things get, you&amp;#8217;ll come away clean. You owe it yourself and your business not to be the guy lying bleeding in an alley with a slug in your gut.&lt;/p&gt;

	&lt;p&gt;But you&amp;#8217;re a professional, right? Nothing bad is going to happen to you.&lt;/p&gt;

	&lt;p&gt;You&amp;#8217;re a good guy. You do good work for good people.&lt;/p&gt;

	&lt;p&gt;Think again chump.&lt;/p&gt;

	&lt;p&gt;Maybe you&amp;#8217;re a gun for hire, a one man army with your back to the wall and nothing standing between you and the line at a soup kitchen but your wits. Maybe you work for the agency, or like me you run one of your own. Either way, when times get tough and people get nasty, you&amp;#8217;ll need more than a killer smile to save you. You&amp;#8217;ll need a killer contract too.&lt;/p&gt;

	&lt;p&gt;It was exactly ten years ago today that I first opened my doors for business. In that time I&amp;#8217;ve thumbed through enough contracts to fill a filing cabinet. I&amp;#8217;ve signed more contracts than I can remember, many so complicated that I &lt;em&gt;should&lt;/em&gt; have hired a lawyer (or detective) to make sense of their complicated jargon and solve their cross-reference puzzles. These documents had not been written to be understood on first reading but to spin me around enough times so as to give the other player the upper-hand.&lt;/p&gt;

	&lt;p&gt;If signing a contract I didn&amp;#8217;t fully understand made me a stupid son-of-a-bitch, not asking my customers to sign one just makes me plain dumb. I&amp;#8217;ve not always been so careful about asking my customers to sign contracts with me as I am now. Somehow in the past I felt that insisting on a contract went against the friendly, trusting relationship that I like to build with my customers. Most of the time the game went my way. On rare the occasions when a fight broke out, I ended up bruised and bloodied. I learned that asking my customers to sign a contract matters to both sides, but what also matters to me is that these contracts should be more meaningful, understandable and less complicated than any of those that I have ever autographed.&lt;/p&gt;

	&lt;h3&gt;Writing a killer contract&lt;/h3&gt;

	&lt;p&gt;If you are writing a contract between you and your customers it doesn&amp;#8217;t have to conform to the seemingly standard format of jargon and complicated legalese. You can be creative. A killer contract will clarify what is expected of both sides and it can also help you to communicate your approach to doing business. It will back-up your brand values and help you to build a great relationship between you and your customers. In other words, a creative contract can be a killer contract.&lt;/p&gt;

	&lt;h4&gt;Your killer contract should cover:&lt;/h4&gt;

	&lt;ul&gt;
		&lt;li&gt;A simple overview of who is hiring who, what they are being hired to do, when and for how much&lt;/li&gt;
		&lt;li&gt;What both parties agree to do and what their respective responsibilities are&lt;/li&gt;
		&lt;li&gt;The specifics of the deal and what is or isn&amp;#8217;t included in the scope&lt;/li&gt;
		&lt;li&gt;What happens when people change their minds (as they almost always do)&lt;/li&gt;
		&lt;li&gt;A simple overview of liabilities and other legal matters&lt;/li&gt;
		&lt;li&gt;You might even include a few jokes&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;To help you along, I will illustrate those bullet points by pointing both barrels at the &lt;a href="http://24ways.org/examples/contract-killer/contract-sample.txt"&gt;contract&lt;/a&gt; that I wrote and have been using at &lt;a href="http://www.stuffandnonsense.co.uk"&gt;Stiffs &amp;amp; Nonsense&lt;/a&gt; for the past year. My contract has been worth its weight in lead and you are welcome to take all or any part of it to use for yourself. It&amp;#8217;s packing a creative-commons attribution share-a-like license. That means you are free to re-distribute it, translate it and otherwise re-use it in ways I never considered. In return I only ask you mention my name and link back to this article. As I am only an amateur detective, you should have it examined thoroughly by your own, trusted legal people if you use it.&lt;/p&gt;

	&lt;p class="note"&gt;&lt;strong&gt;NB:&lt;/strong&gt; The specific details of this killer contract work for me and my customers. That doesn&amp;#8217;t mean that they will work for you and yours. The ways that I handle design revisions, testing, copyright ownership and other specifics are not the main focus of this article. That you handle each of them carefully when you write your own killer contract is.&lt;/p&gt;

	&lt;h3&gt;Kiss Me, Deadly&lt;/h3&gt;

	&lt;h4&gt;Setting a tone and laying foundations for agreement&lt;/h4&gt;

	&lt;p&gt;The first few paragraphs of a killer contract are the most important. Just like a well thought-out web page, these first few words should be simple, concise and include the key points in your contract. As this is the part of the contract that people absorb most easily, it is important that you make it count. Start by setting the overall tone and explaining how your killer contract is structured and why it is different.&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;We will always do our best to fulfill your needs and meet your goals, but sometimes it is best to have a few simple things written down so that we both know what is what, who should do what and what happens if stuff goes wrong. In this contract you won&amp;#8217;t find complicated legal terms or large passages of unreadable text. We have no desire to trick you into signing something that you might later regret. We do want what&amp;#8217;s best for the safety of both parties, now and in the future.&lt;/p&gt;
		&lt;p&gt;&lt;strong&gt;In short&lt;/strong&gt;&lt;/p&gt;
		&lt;p&gt;You &lt;strong&gt;([customer name])&lt;/strong&gt; are hiring us &lt;strong&gt;([company name])&lt;/strong&gt; located at &lt;strong&gt;[address]&lt;/strong&gt; to &lt;strong&gt;[design and develop a web site]&lt;/strong&gt; for the estimated total price of &lt;strong&gt;[total]&lt;/strong&gt; as outlined in our previous correspondence. Of course it&amp;#8217;s a little more complicated, but we&amp;#8217;ll get to that.&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;h3&gt;The Big Kill&lt;/h3&gt;

	&lt;h4&gt;What both parties agree to do&lt;/h4&gt;

	&lt;p&gt;Have you ever done work on a project in good faith for a junior member of a customer&amp;#8217;s team, only to find out later that their spending hadn&amp;#8217;t been authorized? To make damn sure that does not happen to you,  you should ask your customer to confirm that not only are they authorized to enter into your contract but that they will fulfill all of their obligations to help you meet yours. This will help you to avoid any gunfire if, as deadline day approaches, you have fulfilled your side of the bargain but your customer has not come up with the goods.&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;As our customer, you have the power and ability to enter into this contract on behalf of your company or organization. You agree to provide us with everything that we need to complete the project including text, images and other information as and when we need it, and in the format that we ask for. You agree to review our work, provide feedback and sign-off approval in a timely manner too. Deadlines work two ways and you will also be bound by any dates that we set together. You also agree to stick to the payment schedule set out at the end of this contract.&lt;/p&gt;
		&lt;p&gt;We have the experience and ability to perform the services you need from us and we will carry them out in a professional and timely manner. Along the way we will endeavor to meet all the deadlines set but we can&amp;#8217;t be responsible for a missed launch date or a deadline if you have been late in supplying materials or have not approved or signed off our work on-time at any stage. On top of this we will also maintain the confidentiality of any information that you give us.&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;h3&gt;My Gun Is Quick&lt;/h3&gt;

	&lt;h4&gt;Getting down to the nitty gritty&lt;/h4&gt;

	&lt;p&gt;What appear at first to be a straight-forward projects can sometimes turn long and complicated and unless you play it straight from the beginning your relationship with your customer can suffer under the strain. Customers do, and should have the opportunity to, change their minds and give you new assignments. After-all, projects should be flexible and few customers know from the get-go exactly what they want to see. If you handle this well from the beginning you will help to keep yourself and your customers from becoming frustrated. You will also help yourself to dodge bullets in the event of a fire-fight.&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;We will create designs for the look-and-feel, layout and functionality of your web site. This contract includes one main design plus the opportunity for you to make up to two rounds of revisions. If you&amp;#8217;re not happy with the designs at this stage, you will pay us in full for all of the work that we have produced until that point and you may either cancel this contract or continue to commission us to make further design revisions at the daily rate set out in our original estimate.&lt;/p&gt;
		&lt;p&gt;We know from plenty of experience that fixed-price contracts are rarely beneficial to you, as they often limit you to your first idea about how something should look, or how it might work. We don&amp;#8217;t want to limit  either your options or your opportunities to change your mind.&lt;/p&gt;
		&lt;p&gt;The estimate/quotation prices at the beginning of this document are based on the number of days that we estimate we&amp;#8217;ll need to accomplish everything that you have told us you want to achieve. If you do want to change your mind, add extra pages or templates or even add new functionality, that won&amp;#8217;t be a problem. You will be charged the daily rate set out in the estimate we gave you. Along the way we might ask you to put requests in writing so we can keep track of changes.&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;As I like to push my luck when it comes to &lt;span class="caps"&gt;CSS&lt;/span&gt;, it never hurts to head off the potential issue of progressive enrichment right from the start. You should do this too. But don&amp;#8217;t forget that when it comes to technical matters your customers may have different expectations or understanding, so be clear about what you will and won&amp;#8217;t do.&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;If the project includes &lt;span class="caps"&gt;XHTML&lt;/span&gt; or &lt;span class="caps"&gt;HTML&lt;/span&gt; markup and &lt;span class="caps"&gt;CSS&lt;/span&gt; templates, we will develop these using valid &lt;span class="caps"&gt;XHTML&lt;/span&gt; 1.0 Strict markup and CSS2.1 + 3 for styling. We will test all our markup and &lt;span class="caps"&gt;CSS&lt;/span&gt; in current versions of all major browsers including those made by Apple, Microsoft, Mozilla and Opera. We will also test to ensure that pages will display visually in a &amp;#8216;similar&amp;#8217;, albeit not necessarily an identical way, in Microsoft Internet Explorer 6 for Windows as this browser is now past it&amp;#8217;s sell-by date.&lt;/p&gt;
		&lt;p&gt;We will not test these templates in old or abandoned browsers, for example Microsoft Internet Explorer 5 or 5.5 for Windows or Mac, previous versions of Apple&amp;#8217;s Safari, Mozilla Firefox or Opera unless otherwise specified. If you need to show the same or similar visual design to visitors using these older browsers, we will charge you at the daily rate set out in our original estimate for any necessary additional code and its testing.&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;h3&gt;The Twisted Thing&lt;/h3&gt;

	&lt;p&gt;It is not unheard of for customers to pass off stolen goods as their own. If this happens, make sure that you are not the one left holding the baby. You should also make it clear who owns the work that you make as customers often believe that because they pay for your time, that they own everything that you produce.&lt;/p&gt;

	&lt;h4&gt;Copyrights&lt;/h4&gt;

	&lt;blockquote&gt;
		&lt;p&gt;You guarantee to us that any elements of text, graphics, photos, designs, trademarks, or other artwork that you provide us for inclusion in the web site are either owned by your good selfs, or that you have permission to use them. When we receive your final payment, copyright is automatically assigned as follows:&lt;/p&gt;
		&lt;p&gt;You own the graphics and other visual elements that we create for you for this project. We will give you a copy of all files and you should store them really safely as we are not required to keep them or provide any native source files that we used in making them.&lt;/p&gt;
		&lt;p&gt;You also own text content, photographs and other data you provided, unless someone else owns them. We own the &lt;span class="caps"&gt;XHTML&lt;/span&gt; markup, &lt;span class="caps"&gt;CSS&lt;/span&gt; and other code and we license it to you for use on only this project.&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;h3&gt;Vengeance Is Mine!&lt;/h3&gt;

	&lt;h4&gt;The fine print&lt;/h4&gt;

	&lt;p&gt;Unless your work is pro-bono, you should make sure that your customers keep you in shoe leather. It is important that your customers know from the outset that they must pay you on time if they want to stay on good terms.&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;We are sure you understand how important it is as a small business that you pay the invoices that we send you promptly.  As we&amp;#8217;re also sure you&amp;#8217;ll want to stay friends, you agree to stick tight to the following payment schedule.&lt;/p&gt;
		&lt;p&gt;&lt;strong&gt;[Payment schedule]&lt;/strong&gt;&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;No killer contract would be complete without you making sure that you are watching your own back. Before you ask your customers to sign, make it clear-cut what your obligations are and what will happen if any part of your killer contract finds itself laying face down in the dirt.&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;We can&amp;#8217;t guarantee that the functions contained in any web page templates or in a completed web site will always be error-free and so we can&amp;#8217;t be liable to you or any third party for damages, including lost profits, lost savings or other incidental, consequential or special damages arising out of the operation of or inability to operate this web site and any other web pages, even if you have advised us of the possibilities of such damages.&lt;/p&gt;
		&lt;p&gt;Just like a parking ticket, you cannot transfer this contract to anyone else without our permission. This contract stays in place and need not be renewed.  If any provision of this agreement shall be unlawful, void, or for any reason unenforceable, then that provision shall be deemed severable from this agreement and shall not affect the validity and enforceability of any remaining provisions.&lt;/p&gt;
		&lt;p&gt;Phew.&lt;/p&gt;
		&lt;p&gt;Although the language is simple, the intentions are serious and this contract is a legal document under exclusive jurisdiction of &lt;strong&gt;[English]&lt;/strong&gt; courts. Oh and don&amp;#8217;t forget those men with big dogs.&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;h3&gt;Survival&amp;#8230; Zero!&lt;/h3&gt;

	&lt;p&gt;Take it from me, packing a killer contract will help to keep you safe when times get tough, but you must still keep your wits about you and stay on the right side of the law.&lt;/p&gt;

	&lt;p&gt;Don&amp;#8217;t be a turkey this Christmas.&lt;/p&gt;

	&lt;p&gt;Be a contract killer.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=8XeMn7rGExI:MnwuNtQ0d9s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=8XeMn7rGExI:MnwuNtQ0d9s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=8XeMn7rGExI:MnwuNtQ0d9s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=8XeMn7rGExI:MnwuNtQ0d9s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=8XeMn7rGExI:MnwuNtQ0d9s:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/8XeMn7rGExI" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://www.stuffandnonsense.co.uk/"&gt;Andy Clarke&lt;/a&gt; rides into town to remind us of the importance of having a proper contract in place between those providing a service (usually us) and our clients commissioning the work. Projects that don&amp;#8217;t run to plan are a fact of life, so make sure you&amp;#8217;re prepared.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/contract-killer</feedburner:origLink></entry>
<entry>
		<author>
			<name>Dan Rubin</name>
		</author>
		<published>2008-12-22T00:00:10Z</published>
		<updated>2008-12-22T12:04:33Z</updated>
		<title type="html">Absolute Columns</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/WFzYJJo2dwc/absolute-columns" />
		<id>tag:24ways.org,2008-12-21:7e1577ceca7ea22e28af5c35ee62927a/044b37893bf80acc55be64317acd0f41</id>
		<category term="css" />
		
		<content type="html">
&lt;p&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt; layouts have come quite a long way since the dark ages of web publishing, with all sorts of creative applications of floats, negative margins, and even background images employed in order to give us that most basic building block, the column. As the title implies, we are indeed going to be discussing columns today—more to the point, a handy little application of absolute positioning that may be exactly what you&amp;#8217;ve been looking for&amp;#8230;&lt;/p&gt;

	&lt;h3&gt;Care for a nightcap?&lt;/h3&gt;

	&lt;p&gt;If you&amp;#8217;ve been developing for the web for long enough, you may be familiar with this little children&amp;#8217;s fable, passed down from wizened Shaolin monks sitting atop the great Mt. Geocities: &amp;#8220;Once upon a time, multiple columns of the same height could be easily created using &lt;span class="caps"&gt;TABLES&lt;/span&gt;.&amp;#8221; Now, though we&amp;#8217;re all comfortably seated on the standards train (and let&amp;#8217;s be honest: even if you like to think you&amp;#8217;ve fallen off, if you&amp;#8217;ve given up using tables for layout, rest assured your sleeper car is still reserved), this particular—and as page layout goes, quite basic—trick is still a thorn in our &lt;span class="caps"&gt;CSS&lt;/span&gt;ides compared to the ease of achieving the same effect using said Tables of Evil&amp;trade;.&lt;/p&gt;

	&lt;h3&gt;See, the orange juice masks the flavor&amp;#8230;&lt;/h3&gt;

	&lt;p&gt;Creative solutions such as &lt;a href="http://simplebits.com/"&gt;Dan Cederholm&amp;#8217;s&lt;/a&gt;  &lt;a href="http://www.alistapart.com/articles/fauxcolumns/"&gt;Faux Columns&lt;/a&gt; do a good job of making it appear as though adjacent columns maintain equal height as content expands, using a background image to fill the space that the columns cannot.&lt;/p&gt;

	&lt;p&gt;Now, the Holy Grail of &lt;span class="caps"&gt;CSS&lt;/span&gt; columns behaving exactly how they would as table cells—or more to the point, as columns—still eludes us (cough &lt;a href="http://www.w3.org/TR/css3-multicol/"&gt;CSS3 Multi-column layout module&lt;/a&gt; cough), but sometimes you just need, for example, a secondary column (say, a sidebar) to match the height of a primary column, without involving the creation of images. This is where a little absolute positioning can save you time, while possibly giving your layout a little more flexibility.&lt;/p&gt;

	&lt;h3&gt;Shaken, not stirred&lt;/h3&gt;

	&lt;p&gt;You&amp;#8217;re probably familiar by now with the concept of &lt;a href="http://stopdesign.com/articles/absolute/"&gt;Making the Absolute, Relative&lt;/a&gt; as set forth long ago by &lt;a href="http://stopdesign.com/"&gt;Doug Bowman&lt;/a&gt;, but let&amp;#8217;s quickly review just in case: an element set to &lt;code&gt;position:absolute&lt;/code&gt; will position itself relative to its nearest ancestor set to &lt;code&gt;position:relative&lt;/code&gt;, rather than the browser window (see Figure 1).&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/22/2008-absolute-columns-figure1.png" width="640" height="220" alt="2008 Absolute Columns Figure 1" /&gt; &lt;span class="caption"&gt;Figure 1.&lt;/span&gt;&lt;/p&gt;

	&lt;p&gt;However, what you may not know is that we can anchor more than two sides of an absolutely positioned element. Yes, that&amp;#8217;s right, all four sides (top, right, bottom, left) can be set, though in this example we&amp;#8217;re only going to require the services of three sides (see Figure 2 for the end result).&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/22/2008-absolute-columns-figure2.png" width="640" height="450" alt="2008 Absolute Columns Figure 2" /&gt; &lt;span class="caption"&gt;Figure 2.&lt;/span&gt;&lt;/p&gt;

	&lt;h3&gt;Trust me, this will make you feel better&lt;/h3&gt;

	&lt;p&gt;Our requirements are essentially the same as the standard &amp;#8220;absolute-relative&amp;#8221; trick—a container &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; set to &lt;code&gt;position:relative&lt;/code&gt;, and our sidebar &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; set to &lt;code&gt;position:absolute&lt;/code&gt; — plus another &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; that will serve as our main content column. We&amp;#8217;ll also add a few other common layout elements (wrapper, header, and footer) so &lt;a href="http://media.24ways.org/2008/22/2008-absolute-columns-example1.html"&gt;our example markup&lt;/a&gt; looks more like a real layout and less like a test case:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;wrapper&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;header&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;h2&amp;gt;#header&amp;lt;/h2&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;container&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;column-left&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;h2&amp;gt;#left&amp;lt;/h2&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Lorem ipsum dolor sit amet…&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;column-right&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;h2&amp;gt;#right&amp;lt;/h2&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;footer&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;h2&amp;gt;#footer&amp;lt;/h2&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/absolute-columns/1.txt" title="Download the above code as a textfile"&gt;/code/absolute-columns/1.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;In this example, our main column (&lt;code&gt;#column-left&lt;/code&gt;) is only being given a width to fit within the context of the layout, and is otherwise untouched (though we&amp;#8217;re using pixels here, this trick will of course work with fluid layouts as well), and our right keeping our styles nice and minimal:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#container {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;position: relative;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#column-left {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 480px;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#column-right {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;position: absolute;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;top: 10px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;right: 10px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;bottom: 10px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 250px;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/absolute-columns/2.txt" title="Download the above code as a textfile"&gt;/code/absolute-columns/2.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;The trick is a simple one: the &lt;code&gt;#container &amp;lt;div&amp;gt;&lt;/code&gt; will expand vertically to fit the content within &lt;code&gt;#column-left&lt;/code&gt;. By telling our sidebar &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; (&lt;code&gt;#column-right&lt;/code&gt;) to attach itself not only to the top and right edges of &lt;code&gt;#container&lt;/code&gt;, but also to the bottom, it too will expand and contract to match the height of the left column (duplicate the &amp;#8220;lorem ipsum&amp;#8221; paragraph a few times to see it in action).&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/22/2008-absolute-columns-figure3.png" width="640" height="450" alt="2008 Absolute Columns Figure 3" /&gt; &lt;span class="caption"&gt;Figure 3.&lt;/span&gt;&lt;/p&gt;

	&lt;h3&gt;On the rocks&lt;/h3&gt;

	&lt;p&gt;&amp;#8220;But wait!&amp;#8221; I hear you exclaim, &amp;#8220;when the right column has more content than the left column, it doesn&amp;#8217;t expand! My text runneth over!&amp;#8221; Sure enough, that&amp;#8217;s &lt;a href="http://media.24ways.org/2008/22/2008-absolute-columns-example2.html"&gt;exactly what happens&lt;/a&gt;, and what&amp;#8217;s more, it&amp;#8217;s supposed to: Absolutely positioned elements do exactly what you tell them to do, and unfortunately aren&amp;#8217;t very good at thinking outside the box (get it? sigh&amp;#8230;). &lt;/p&gt;

	&lt;p&gt;However, this needn&amp;#8217;t get your spirits down, because there&amp;#8217;s an easy way to address the issue: by adding &lt;code&gt;overflow:auto&lt;/code&gt; to &lt;code&gt;#column-right&lt;/code&gt;, a scrollbar will &lt;a href="http://media.24ways.org/2008/22/2008-absolute-columns-example3.html"&gt;automatically appear&lt;/a&gt; if and when needed:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#column-right {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;position: absolute;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;top: 10px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;right: 10px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;bottom: 10px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 250px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;overflow: auto;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/absolute-columns/3.txt" title="Download the above code as a textfile"&gt;/code/absolute-columns/3.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;While this may limit the trick&amp;#8217;s usefulness to situations where the primary column will almost always have more content than the secondary column—or where the secondary column&amp;#8217;s content can scroll with wild abandon—a little prior planning will make it easy to incorporate into your designs.&lt;/p&gt;

	&lt;h3&gt;Driving us to drink&lt;/h3&gt;

	&lt;p&gt;It just wouldn&amp;#8217;t be right to have a friendly, festive holiday tutorial without inviting IE6, though in this particular instance there will be no shaming that old browser into admitting it has a problem, nor an intervention and subsequent 12-step program. That&amp;#8217;s right my friends, this tutorial has abstained from IE6-abuse now for 30 days, thanks to the wizard &lt;a href="http://dean.edwards.name/"&gt;Dean Edwards&lt;/a&gt; and his amazingly talented &lt;a href="http://dean.edwards.name/weblog/2008/01/ie7-2/"&gt;IE7 Javascript library&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;Simply drop the Conditional Comment and &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; element into the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of your document, along with one tiny &lt;span class="caps"&gt;CSS&lt;/span&gt; hack that only IE6 (and below) will ever see, and that browser will be &lt;a href="http://media.24ways.org/2008/22/2008-absolute-columns-example3.html"&gt;back on the straight and narrow&lt;/a&gt;:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;!--[if lt IE 7]&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;script src=&amp;quot;http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE7.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;style type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1 cmnt"&gt;&lt;code&gt;#container {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2 cmnt"&gt;&lt;code&gt;zoom:1; /* helps fix IE6 by initiating hasLayout */&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;![endif]--&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/absolute-columns/4.txt" title="Download the above code as a textfile"&gt;/code/absolute-columns/4.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;h3&gt;Eggnog is supposed to be spiked, right?&lt;/h3&gt;

	&lt;p&gt;Of course, this is one simple example of what can be a much more powerful technique, depending on your needs and creativity. Just don&amp;#8217;t go coding up your wildest fantasies until you&amp;#8217;ve had a chance to sleep off the Christmas turkey and whatever tasty liquids you happen to imbibe along the way&amp;#8230;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=WFzYJJo2dwc:1PAOymXTj3w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=WFzYJJo2dwc:1PAOymXTj3w:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=WFzYJJo2dwc:1PAOymXTj3w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=WFzYJJo2dwc:1PAOymXTj3w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=WFzYJJo2dwc:1PAOymXTj3w:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/WFzYJJo2dwc" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://superfluousbanter.org"&gt;Dan Rubin&lt;/a&gt; pops down the chimney to deliver a neat little &lt;span class="caps"&gt;CSS&lt;/span&gt; gift that, in certain circumstances, could be just the trick needed to obtain those matched height columns so often desired. Whilst no technique is perfect for every situation, the more sharp tools we have in our &lt;span class="caps"&gt;CSS&lt;/span&gt; toolbox the better.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/absolute-columns</feedburner:origLink></entry>
<entry>
		<author>
			<name>Ben Ward</name>
		</author>
		<published>2008-12-21T00:00:07Z</published>
		<updated>2008-12-21T09:19:33Z</updated>
		<title type="html">Geotag Everywhere with Fire Eagle</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/4PubaipZUmc/geotag-everywhere-with-fire-eagle" />
		<id>tag:24ways.org,2008-12-20:7e1577ceca7ea22e28af5c35ee62927a/43084377c4d1bf83bd89a331b72bce9d</id>
		<category term="apis" />
		
		<content type="html">
&lt;p&gt;Location, they say, is everywhere. Everyone has one, all of the time. But on the web, it&amp;#8217;s taken until this year to see the emergence of location in the applications we use and build.&lt;/p&gt;

	&lt;p&gt;The possibilities are broad. Increasingly, mobile phones provide &lt;abbr title="Software Development Kits"&gt;&lt;span class="caps"&gt;SDK&lt;/span&gt;&lt;/abbr&gt;s to approximate your location wherever you are, browser extensions such as &lt;a href="http://loki.com/"&gt;Loki&lt;/a&gt; and Mozilla&amp;#8217;s &lt;a href="http://labs.mozilla.com/2008/10/introducing-geode/"&gt;Geode&lt;/a&gt; provide browser-level &lt;span class="caps"&gt;API&lt;/span&gt;s to establish your location from the proximity of wireless networks to your laptop. Yahoo&amp;#8217;s Brickhouse group launched &lt;a href="http://fireeagle.com"&gt;Fire Eagle&lt;/a&gt;, an ambitious location broker enabling people to take their location from any of these devices or sources, and provide it to a plethora of web services. It enables you to take the location information that only your iPhone knows about and use it anywhere on the web.&lt;/p&gt;

	&lt;p&gt;That said, this is still a time of location as an emerging technology. Fire Eagle stores your location on the web (protected by application-specific access controls), but to try and give an idea of how useful and powerful your location can be — regardless of the services you use now — today&amp;#8217;s 24ways is going to build a bookmarklet to call up your location on demand, in any web application.&lt;/p&gt;

	&lt;h3&gt;Location Support on the Web&lt;/h3&gt;

	&lt;p&gt;Over the past year, the number of applications implementing location features has increased dramatically. &lt;a href="http://plazes.com"&gt;Plazes&lt;/a&gt; and &lt;a href="http://brightkite.com"&gt;Brightkite&lt;/a&gt; are both full featured social networks based around where you are, whilst &lt;a href="http://pownce.com"&gt;Pownce&lt;/a&gt; rolled in Fire Eagle support to allow geotagging of all the content you post to their microblogging service. &lt;a href="http://www.dipity.com"&gt;Dipity&lt;/a&gt;&amp;#8217;s beautiful timeline shows for you moving from place to place and Six Apart&amp;#8217;s activity stream for &lt;a href="http://movabletype.com/"&gt;Movable Type&lt;/a&gt; started exposing your movements.&lt;/p&gt;

	&lt;p&gt;The number of services that hook into Fire Eagle will increase as location awareness spreads through the developer community, but you can use your location on other sites indirectly too.&lt;/p&gt;

	&lt;p&gt;Consider &lt;a href="http://flickr.com"&gt;Flickr&lt;/a&gt;. Now world renowned for their incredible &lt;a href="http://flickr.com/map"&gt;mapping&lt;/a&gt; and &lt;a href="http://flickr.com/places/Germany/Bavaria/Munich"&gt;places&lt;/a&gt; features, geotagging on Flickr started out as a grassroots extension of regular tagging. That same technique can be used to start rolling geotagging in any publishing platform you come across, for any kind of content. Machine-tags (&lt;samp&gt;geo:lat=&lt;/samp&gt; and &lt;samp&gt;geo:lon=&lt;/samp&gt;) and the &lt;a href="http://microformats.org/wiki/adr"&gt;adr&lt;/a&gt; and &lt;a href="http://microformats.org/wiki/geo"&gt;geo&lt;/a&gt; &lt;a href="http://microformats.org/"&gt;microformats&lt;/a&gt; can be used to enhance anything you write with location information.&lt;/p&gt;

	&lt;h3&gt;A crash course in avian inflammability&lt;/h3&gt;

	&lt;p&gt;Fire Eagle is a location store. A broker between services and devices which provide location and those which consume it. It&amp;#8217;s a switchboard that controls which pieces of your location different applications can see and use, and keeps hidden anything you want kept private. A &lt;a href="http://fireeagle.yahoo.net/gallery/app/gdgk7LHH3J2jp2Dtt2Ht"&gt;blog widget&lt;/a&gt; that displays your current location in public can be restricted to display just your current city, whilst a service that provides you with a &lt;a href="http://atms.iamnear.net/"&gt;list of the nearest &lt;span class="caps"&gt;ATM&lt;/span&gt;s&lt;/a&gt; will operate better with a precise street address. &lt;/p&gt;

	&lt;p&gt;Even if your iPhone tells Fire Eagle exactly where you are, consuming applications only see what you want them to see. That&amp;#8217;s important for users to realise that they&amp;#8217;re in control, but also important for application developers to remember that you cannot rely on having super-accurate information available all the time. &lt;em&gt;You need to build location aware applications which degrade gracefully&lt;/em&gt;, because users will provide fuzzier information — either through choice, or through less accurate sources.&lt;/p&gt;

	&lt;p&gt;Application specific permissions are controlled through an &lt;a href="http://oauth.org"&gt;OAuth&lt;/a&gt; &lt;span class="caps"&gt;API&lt;/span&gt;. Each application has a unique key, used to request a second, user-specific key that permits access to that user&amp;#8217;s information. You store that user key and it remains valid until such a time as the user revokes your application&amp;#8217;s access. Unlike with passwords, these keys are unique per application, so revoking the access rights of one application doesn&amp;#8217;t break all the others.&lt;/p&gt;

	&lt;h3&gt;Building your first Fire Eagle app; Geomarklet&lt;/h3&gt;

	&lt;p&gt;&lt;a href="http://fireeagle.yahoo.net/developer"&gt;Fire Eagle&amp;#8217;s developer documentation&lt;/a&gt; can take you through examples of writing simple applications using server side technologies (&lt;a href="http://fireeagle.yahoo.net/developer/documentation/php_walkthru"&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://fireeagle.yahoo.net/developer/documentation/python_walkthru"&gt;Python&lt;/a&gt;). Here, we&amp;#8217;re going to write a client-side bookmarklet to make your location available in &lt;em&gt;every&lt;/em&gt; site you use. It&amp;#8217;s designed to fast-track the experience of  having location available everywhere on web, and show you how that can be really handy. Hopefully, this will set you thinking about how location can enhance the new applications you build in 2009.&lt;/p&gt;

	&lt;h4&gt;An oddity of bookmarklets&lt;/h4&gt;

	&lt;p&gt;Bookmarklets (or ‘favlets’, for those of an &lt;abbr title="Microsoft Internet Explorer"&gt;&lt;span class="caps"&gt;MSIE&lt;/span&gt;&lt;/abbr&gt; persuasion) are a strange environment to program in. Critically, you have no persistent storage available. As such, using token-auth &lt;span class="caps"&gt;API&lt;/span&gt;s in a static environment requires you to build you application in a slightly strange way; authing yourself in advance and then hardcoding the keys into your script.&lt;/p&gt;

	&lt;h4&gt;Get started&lt;/h4&gt;

	&lt;p&gt;Before you do anything else, go to &lt;a href="http://fireeagle.com"&gt;http://fireeagle.com&lt;/a&gt; and log in, get set up if you need to and by all means take a look around. Take a look at the &lt;a href="http://fireeagle.yahoo.net/gallery/onthego"&gt;mobile updaters&lt;/a&gt; section of the application gallery and perhaps pick out an app that will update Fire Eagle from your phone or laptop.&lt;/p&gt;

	&lt;p&gt;Once that&amp;#8217;s done, you need to register for an application key in the developer section. Head straight to &lt;a href="https://fireeagle.yahoo.net/developer/create"&gt;/developer/create&lt;/a&gt; and complete the form. Since you&amp;#8217;re building a standalone application, choose ‘Auth for desktop applications’ (rather than web applications), and select that you&amp;#8217;ll be ‘accessing location’, not updating.&lt;/p&gt;

	&lt;p&gt;At the end of this process, you&amp;#8217;ll have two application keys, a ‘Consumer Key’ and a ‘Consumer Secret’, which look like these:&lt;/p&gt;

 &lt;dl&gt;
    &lt;dt&gt;Consumer Key&lt;/dt&gt;
    &lt;dd&gt;luKrM9U1pMnu&lt;/dd&gt;
    &lt;dt&gt;Consumer Secret&lt;/dt&gt;
    &lt;dd&gt;ZZl9YXXoJX5KLiKyVrMZffNEaBnxnd6M&lt;/dd&gt;
 &lt;/dl&gt;

	&lt;p&gt;These keys combined allow your application to make requests to Fire Eagle.&lt;/p&gt;

	&lt;p&gt;Next up, you need to auth yourself; granting your new application permission to use your location. Because bookmarklets don&amp;#8217;t have local storage, you can&amp;#8217;t integrate the auth process into the bookmarklet itself — it would have no way of storing the returned key. Instead, I&amp;#8217;ve put together a simple web frontend through which you can auth with your application.&lt;/p&gt;

	&lt;p&gt;Head to &lt;a href="http://amadeus.benapps.net"&gt;Auth me, Amadeus!&lt;/a&gt;, enter the application keys you just generated and hit ‘Authorize with Fire Eagle’. You&amp;#8217;ll be taken to the Fire Eagle website, just as in regular Fire Eagle applications, and after granting access to your app, be redirected back to Amadeus which will provide you your user tokens. These tokens are used in subsequent requests to read your location.&lt;/p&gt;

	&lt;h4&gt;And, skip to the end…&lt;/h4&gt;

	&lt;p&gt;The process of building the bookmarklet, making requests to Fire Eagle, rendering it to the page and so forth follows, but if you&amp;#8217;re the impatient type, you might like to try this out right now. Take your four &lt;span class="caps"&gt;API&lt;/span&gt; keys from above, and drag the following link to your Bookmarks Toolbar; it contains all the code described below. Before you can use it, you need to edit in your own &lt;span class="caps"&gt;API&lt;/span&gt; keys. Open your browser&amp;#8217;s bookmark editor and where you find text like ‘YOUR_CONSUMER_KEY_HERE’, swap in the corresponding key you just generated.&lt;/p&gt;

&lt;p&gt;&lt;a href="javascript:var%20Geomarklet%20=%20function()%20{var%20Keys%20=%20{consumer_key:'YOUR_CONSUMER_KEY_HERE',consumer_secret:'YOUR_CONSUMER_SECRET_HERE',user_token:'YOUR_USER_TOKEN_HERE',user_secret:'YOUR_USER_SECRET_HERE'};var%20LocationDetail%20=%20{EXACT:%200,POSTAL:%201,NEIGHBORHOOD:%202,CITY:%203,REGION:%204,STATE:%205,COUNTRY:%206};var%20index_offset%20=%200;var%20renderers%20=%20{geotag:%20function(user)%20{if(LocationDetail.EXACT%20!==%20index_offset)%20{return%20false;}else%20{var%20coords%20=%20user.location_hierarchy[LocationDetail.EXACT].geometry.coordinates;return%20%22geo:lat=%22%20+%20coords[0]%20+%20%22,%20geo:lon=%22%20+%20coords[1];}},city:%20function(user)%20{if(LocationDetail.CITY%20%3C%20index_offset)%20{return%20false;}else%20{return%20user.location_hierarchy[LocationDetail.CITY%20-%20index_offset].name;}},html:%20function(user)%20{var%20geostring%20=%20%27%27;var%20adrstring%20=%20%27%27;var%20adr%20=%20[];adr.push(%27%3Cp%20class=%22adr%22&gt;%27);if(LocationDetail.CITY%20&gt;=%20index_offset)%20{adr.push(%27\n%20%3Cspan%20class=%22locality%22&gt;%27+%20user.location_hierarchy[LocationDetail.CITY-index_offset].normal_name+%20%27%3C/span&gt;,%27);}if(LocationDetail.REGION%20&gt;=%20index_offset)%20{adr.push(%27\n%20%3Cspan%20class=%22region%22&gt;%27+%20user.location_hierarchy[LocationDetail.REGION-index_offset].normal_name+%20%27%3C/span&gt;,%27);}if(LocationDetail.STATE%20&gt;=%20index_offset)%20{adr.push(%27\n%20%3Cspan%20class=%22region%22&gt;%27+%20user.location_hierarchy[LocationDetail.STATE-index_offset].normal_name+%20%27%3C/span&gt;,%27);}if(LocationDetail.COUNTRY%20&gt;=%20index_offset)%20{adr.push(%27\n%20%3Cspan%20class=%22country-name%22&gt;%27+%20user.location_hierarchy[LocationDetail.COUNTRY-index_offset].normal_name+%20%27%3C/span&gt;%27);}if(LocationDetail.POSTAL%20&gt;=%20index_offset)%20{adr.push(%27\n%20%3Cspan%20class=%22postal-code%22&gt;%27+%20user.location_hierarchy[LocationDetail.POSTAL-index_offset].normal_name+%20%27%3C/span&gt;,%27);}adr.push(%27\n%3C/p&gt;\n%27);adrstring%20=%20adr.join(%27%27);if(LocationDetail.EXACT%20===%20index_offset)%20{var%20coords%20=%20user.location_hierarchy[LocationDetail.EXACT].geometry.coordinates;geostring%20=%20%27%3Cp%20class=%22geo%22&gt;%27+%27\n%20%3Cspan%20class=%22latitude%22&gt;%27+%20coords[0]+%20%27%3C/span&gt;;%27+%20%27\n%20%3Cspan%20class=%22longitude%22&gt;%27+%20coords[1]+%20%27%3C/span&gt;\n%3C/p&gt;\n%27;}return%20(adrstring%20+%20geostring);}};function%20insert_prerequisites()%20{var%20style%20=%20document.createElement(%27link%27);style.href%20=%20%27http://geomarklet.benapps.net/24ways/geomarklet.css%27;style.rel%20=%20%27stylesheet%27;style.type%20=%20%27text/css%27;var%20sha1%20=%20document.createElement(%27script%27);sha1.src%20=%20%27http://pajhome.org.uk/crypt/md5/sha1.js%27;sha1.type%20=%20%27text/javascript%27;var%20oauth%20=%20document.createElement(%27script%27);oauth.src%20=%20%27http://oauth.googlecode.com/svn/code/javascript/oauth.js%27;oauth.type%20=%20%27text/javascript%27;var%20oauthext%20=%20document.createElement(%27script%27);oauthext.src%20=%20%27http://github.com/ayman/fireeagle-javascript-lib/raw/master/lib/oauthext.js%27;oauthext.type%20=%20%27text/javascript%27;var%20fireeagle%20=%20document.createElement(%27script%27);fireeagle.src%20=%20%27http://github.com/ayman/fireeagle-javascript-lib/raw/master/lib/fe.js%27;fireeagle.type%20=%20%27text/javascript%27;var%20head%20=%20document.getElementsByTagName(%27head%27)[0];head.appendChild(style);head.appendChild(sha1);head.appendChild(oauth);head.appendChild(oauthext);head.appendChild(fireeagle);}function%20draw_selector(data)%20{var%20overlay%20=%20document.createElement(%27div%27);overlay.className%20=%20%27dialog%27;overlay.id%20=%20%27net-benapps-geomarklet%27;var%20intro%20=%20document.createElement(%27h1%27);intro.appendChild(document.createTextNode(%27Select%20&amp;amp;%20copy%20your%20location:%27));renders_list%20=%20document.createElement(%27ul%27);for(r%20in%20renderers)%20{var%20sample%20=%20renderers[r](data.user);if(false%20!==%20sample)%20{var%20li%20=%20document.createElement(%27li%27);var%20pre%20=%20document.createElement(%27pre%27);var%20code%20=%20document.createElement(%27code%27);code.appendChild(document.createTextNode(sample));pre.appendChild(code);li.appendChild(pre);renders_list.appendChild(li);}}var%20close_button%20=%20document.createElement(%27button%27);close_button.appendChild(document.createTextNode(%27Close%27));close_button.onclick%20=%20function()%20{overlay.style.display%20=%20%27none%27;};overlay.appendChild(intro);overlay.appendChild(renders_list);overlay.appendChild(close_button);document.body.appendChild(overlay);}return%20{callback:%20function(json)%20{if(json.rsp%20&amp;amp;&amp;amp;%20%27fail%27%20==%20json.rsp.stat)%20{alert(%27Error%20%27%20+%20json.rsp.code%20+%20%22:%20%22%20+%20json.rsp.message);}else%20{index_offset%20=%20json.user.location_hierarchy[0].level;draw_selector(json);}},run:%20function()%20{insert_prerequisites();setTimeout(function()%20{var%20fe%20=%20new%20FireEagle(Keys.consumer_key,Keys.consumer_secret,Keys.user_token,Keys.user_secret);var%20script%20=%20document.createElement(%27script%27);script.type%20=%20%27text/javascript%27;script.src%20=%20fe.getUserUrl(FireEagle.RESPONSE_FORMAT.json,%20%27Geomarklet.callback%27);document.body.appendChild(script);},2000);}};}();Geomarklet.run();"&gt;Get Location&lt;/a&gt;&lt;/p&gt;

	&lt;h4&gt;Bookmarklet Basics&lt;/h4&gt;

	&lt;p&gt;To start on the bookmarklet code, set out a basic JavaScript module-pattern structure:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;var Geomarklet = function() {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;return ({&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;callback: function(json) {},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;run: function() {}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;});&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Geomarklet.run();&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/geotag-everywhere-with-fire-eagle/1.txt" title="Download the above code as a textfile"&gt;/code/geotag-everywhere-with-fire-eagle/1.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Next we&amp;#8217;ll add the keys obtained in the setup step, and also some basic Fire Eagle support objects:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;var Geomarklet = function() {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var Keys = {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;consumer_key: 'IuKrJUHU1pMnu',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;consumer_secret: 'ZZl9YXXoJX5KLiKyVEERTfNEaBnxnd6M',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;user_token: 'xxxxxxxxxxxx',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;user_secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var LocationDetail = {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;EXACT: 0,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;POSTAL: 1,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;NEIGHBORHOOD: 2,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;CITY: 3,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;REGION: 4,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;STATE: 5,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;COUNTRY: 6&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var index_offset;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;return ({&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;callback: function(json) {},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;run: function() {}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;});&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Geomarklet.run();&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/geotag-everywhere-with-fire-eagle/2.txt" title="Download the above code as a textfile"&gt;/code/geotag-everywhere-with-fire-eagle/2.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;h4&gt;The Location Hierarchy&lt;/h4&gt;

	&lt;p&gt;A successful Fire Eagle query returns an object called the ‘location hierarchy’. Depending on the level of detail shared, the index of a particular piece of information in the array will vary. The &lt;code&gt;LocationDetail&lt;/code&gt; object maps the array indices of each level in the hierarchy to something comprehensible, whilst the &lt;code&gt;index_offset&lt;/code&gt; variable is an adjustment based on the detail of the result returned.&lt;/p&gt;

	&lt;p&gt;The location hierarchy object looks like this, providing a granular breakdown of a location, in human consumable and machine-friendly forms.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;quot;user&amp;quot;: {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;quot;location_hierarchy&amp;quot;: [{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;level&amp;quot;: 0,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;level_name&amp;quot;: &amp;quot;exact&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;name&amp;quot;: &amp;quot;707 19th St, San Francisco, CA&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;normal_name&amp;quot;: &amp;quot;94123&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;geometry&amp;quot;: {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;&amp;quot;type&amp;quot;: &amp;quot;Point&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;&amp;quot;coordinates&amp;quot;: [ - 0.2347530752, 67.232323]&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;label&amp;quot;: null,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;best_guess&amp;quot;: true,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;id&amp;quot;: ,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;located_at&amp;quot;: &amp;quot;2008-12-18T00:49:58-08:00&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;quot;query&amp;quot;: &amp;quot;q=707%2019th%20Street,%20Sf&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;level&amp;quot;: 1,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;level_name&amp;quot;: &amp;quot;postal&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;name&amp;quot;: &amp;quot;San Francisco, CA 94114&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;normal_name&amp;quot;: &amp;quot;12345&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;woeid&amp;quot;: ,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;place_id&amp;quot;: &amp;quot;&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;geometry&amp;quot;: {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;quot;type&amp;quot;: &amp;quot;Polygon&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;quot;coordinates&amp;quot;: [],&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;quot;bbox&amp;quot;: []&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;label&amp;quot;: null,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;best_guess&amp;quot;: false,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;id&amp;quot;: 59358791,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;located_at&amp;quot;: &amp;quot;2008-12-18T00:49:58-08:00&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;level&amp;quot;: 2,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;level_name&amp;quot;: &amp;quot;neighborhood&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;name&amp;quot;: &amp;quot;The Mission, San Francisco, CA&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;normal_name&amp;quot;: &amp;quot;The Mission&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;woeid&amp;quot;: 23512048,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;place_id&amp;quot;: &amp;quot;Y12JWsKbApmnSQpbQg&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;geometry&amp;quot;: {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;quot;type&amp;quot;: &amp;quot;Polygon&amp;quot;,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;quot;coordinates&amp;quot;: [],&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;quot;bbox&amp;quot;: []&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;label&amp;quot;: null,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;best_guess&amp;quot;: false,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;id&amp;quot;: 59358801,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;quot;located_at&amp;quot;: &amp;quot;2008-12-18T00:49:58-08:00&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/geotag-everywhere-with-fire-eagle/3.txt" title="Download the above code as a textfile"&gt;/code/geotag-everywhere-with-fire-eagle/3.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;In this case the first object has a &lt;code&gt;level&lt;/code&gt; of &lt;samp&gt;0&lt;/samp&gt;, so the &lt;code&gt;index_offset&lt;/code&gt; is also &lt;samp&gt;0&lt;/samp&gt;.&lt;/p&gt;

	&lt;h4&gt;Prerequisites&lt;/h4&gt;

	&lt;p&gt;To query Fire Eagle we call in some existing libraries to handle the OAuth layer and the Fire Eagle &lt;span class="caps"&gt;API&lt;/span&gt; call. Your bookmarklet will need to add the following scripts into the page:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;The &lt;a href="http://pajhome.org.uk/crypt/md5/sha1.js"&gt;SHA1 encryption algorithm&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;The &lt;a href="http://oauth.googlecode.com/svn/code/javascript/oauth.js"&gt;OAuth wrapper&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;An &lt;a href="http://github.com/ayman/fireeagle-javascript-lib/raw/master/lib/oauthext.js"&gt;extension for the OAuth wrapper&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;The &lt;a href="http://github.com/ayman/fireeagle-javascript-lib/raw/master/lib/fe.js"&gt;Fire Eagle wrapper itself&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;When the bookmarklet is first run, we&amp;#8217;ll insert these scripts into the document. We&amp;#8217;re also inserting a stylesheet to dress up the UI that will be generated.&lt;/p&gt;

	&lt;p&gt;If you want to follow along any of the more mundane parts of the bookmarklet, you can  &lt;a href="http://geomarklet.benapps.net/24ways/geomarklet_24ways.zip"&gt;download the full source code&lt;/a&gt;.&lt;/p&gt;

	&lt;h4&gt;Rendering&lt;/h4&gt;

	&lt;p&gt;This bookmarklet can be extended to support any formatting of your location you like, but for sake of example I&amp;#8217;m going to build three common formatters that you&amp;#8217;ll find useful for common location scenarios: Sites which already ask for your location; and in publishing systems that accept tags or &lt;span class="caps"&gt;HTML&lt;/span&gt; mark-up.&lt;/p&gt;

	&lt;p&gt;All the rendering functions are items in a &lt;code&gt;renderers&lt;/code&gt; object, so they can be iterated through easily, making it trivial to add new formatting functions as your find new use cases (just add another function to the object).&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;var renderers = {&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;geotag: function(user) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(LocationDetail.EXACT !== index_offset) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;return false;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;else {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;var coords =&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;user.location_hierarchy[LocationDetail.EXACT].geometry.coordinates;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;return &amp;quot;geo:lat=&amp;quot; + coords[0] + &amp;quot;, geo:lon=&amp;quot; + coords[1];&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;city: function(user) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(LocationDetail.CITY &amp;lt; index_offset) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;return false;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;else {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;return user.location_hierarchy[LocationDetail.CITY - index_offset].name; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab7"&gt;&lt;code&gt;} &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/geotag-everywhere-with-fire-eagle/4.txt" title="Download the above code as a textfile"&gt;/code/geotag-everywhere-with-fire-eagle/4.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;You should always fail gracefully, and in line with catering to users who choose not to share their location precisely, always check that the location has been returned at the level you require. Geotags are expected to be precise, so if an exact location is unavailable, returning &lt;code&gt;false&lt;/code&gt; will tell the rendering aspect of the bookmarklet to ignore the function altogether.&lt;/p&gt;

	&lt;p&gt;These first two are quite simple, &lt;code&gt;geotag&lt;/code&gt; returns &lt;samp&gt;geo:lat=-0.2347530752, geo:lon=67.232323&lt;/samp&gt; and &lt;code&gt;city&lt;/code&gt; returns &lt;samp&gt;San Francisco, CA&lt;/samp&gt;.&lt;/p&gt;

	&lt;p&gt;This final renderer creates a chunk of &lt;span class="caps"&gt;HTML&lt;/span&gt; using the adr and geo microformats, using all available aspects of the location hierarchy, and can be used to geotag any content you write on your blog or in comments:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;html: function(user) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var geostring = '';&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var adrstring = '';&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;var adr = []; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;adr.push('&amp;lt;p class=&amp;quot;adr&amp;quot;&amp;gt;');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1 cmnt"&gt;&lt;code&gt;// city&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(LocationDetail.CITY &amp;gt;= index_offset) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;adr.push(&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;'\n &amp;lt;span class=&amp;quot;locality&amp;quot;&amp;gt;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ user.location_hierarchy[LocationDetail.CITY-index_offset].normal_name&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ '&amp;lt;/span&amp;gt;,'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1 cmnt"&gt;&lt;code&gt;// county&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(LocationDetail.REGION &amp;gt;= index_offset) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;adr.push(&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;'\n &amp;lt;span class=&amp;quot;region&amp;quot;&amp;gt;' &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ user.location_hierarchy[LocationDetail.REGION-index_offset].normal_name&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ '&amp;lt;/span&amp;gt;,'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1 cmnt"&gt;&lt;code&gt;// locality&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(LocationDetail.STATE &amp;gt;= index_offset) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;adr.push(&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;'\n &amp;lt;span class=&amp;quot;region&amp;quot;&amp;gt;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ user.location_hierarchy[LocationDetail.STATE-index_offset].normal_name&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ '&amp;lt;/span&amp;gt;,'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1 cmnt"&gt;&lt;code&gt;// country&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(LocationDetail.COUNTRY &amp;gt;= index_offset) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;adr.push(&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;'\n &amp;lt;span class=&amp;quot;country-name&amp;quot;&amp;gt;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ user.location_hierarchy[LocationDetail.COUNTRY-index_offset].normal_name&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ '&amp;lt;/span&amp;gt;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1 cmnt"&gt;&lt;code&gt;// postal&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(LocationDetail.POSTAL &amp;gt;= index_offset) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;adr.push(&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;'\n &amp;lt;span class=&amp;quot;postal-code&amp;quot;&amp;gt;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ user.location_hierarchy[LocationDetail.POSTAL-index_offset].normal_name&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;+ '&amp;lt;/span&amp;gt;,'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;adr.push('\n&amp;lt;/p&amp;gt;\n');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;adrstring = adr.join('');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(LocationDetail.EXACT === index_offset) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;var coords = &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;user.location_hierarchy[LocationDetail.EXACT].geometry.coordinates;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;geostring = '&amp;lt;p class=&amp;quot;geo&amp;quot;&amp;gt;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;+'\n&amp;lt;span class=&amp;quot;latitude&amp;quot;&amp;gt;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;+ coords[0]&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;+ '&amp;lt;/span&amp;gt;;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;+ '\n &amp;lt;span class=&amp;quot;longitude&amp;quot;&amp;gt;'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;+ coords[1]&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;+ '&amp;lt;/span&amp;gt;\n&amp;lt;/p&amp;gt;\n';&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;return (adrstring + geostring);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/geotag-everywhere-with-fire-eagle/5.txt" title="Download the above code as a textfile"&gt;/code/geotag-everywhere-with-fire-eagle/5.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Here we check the availability of every level of location and build it into the adr and geo patterns as appropriate. Just as for the geotag function, if there&amp;#8217;s no exact location the geo markup won&amp;#8217;t be returned.&lt;/p&gt;

	&lt;p&gt;Finally, there&amp;#8217;s a rendering method which creates a container for all this data, renders all the applicable location formats and then displays them in the page for a user to copy and paste. You can throw this together with &lt;span class="caps"&gt;DOM&lt;/span&gt; methods and some simple styling, or roll in some components from &lt;span class="caps"&gt;YUI&lt;/span&gt; or JQuery to handle drawing full featured overlays.&lt;/p&gt;

	&lt;p&gt;You can see this simple implementation for rendering in &lt;a href="http://geomarklet.benapps.net/24ways/geomarklet_24ways.zip"&gt;the full source code&lt;/a&gt;.&lt;/p&gt;

	&lt;h4&gt;Make the call&lt;/h4&gt;

	&lt;p&gt;With a framework in place to render Fire Eagle&amp;#8217;s location hierarchy, the only thing that remains is to actually request your location. Having already authed through Amadeus earlier, that&amp;#8217;s as simple as instantiating the Fire Eagle JavaScript wrapper and making a single function call. It&amp;#8217;s a big deal that whilst a lot of new technologies like OAuth add some complexity and require new knowledge to work with, &lt;span class="caps"&gt;API&lt;/span&gt;s like Fire Eagle are really very simple indeed.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;return {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;run: function() {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;insert_prerequisites();&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;setTimeout(&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;function() {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;var fe = new FireEagle(&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;Keys.consumer_key,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;Keys.consumer_secret,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;Keys.user_token,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;Keys.user_secret&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;var script = document.createElement('script');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;script.type = 'text/javascript';&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;script.src = fe.getUserUrl(&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;FireEagle.RESPONSE_FORMAT.json,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;'Geomarklet.callback'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;document.body.appendChild(script);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;2000&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;callback: function(json) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;if(json.rsp &amp;amp;&amp;amp; 'fail' == json.rsp.stat) {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;alert('Error ' + json.rsp.code + &amp;quot;: &amp;quot; + json.rsp.message);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;else {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab9"&gt;&lt;code&gt;index_offset = json.user.location_hierarchy[0].level; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;draw_selector(json);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/geotag-everywhere-with-fire-eagle/6.txt" title="Download the above code as a textfile"&gt;/code/geotag-everywhere-with-fire-eagle/6.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;We first insert the prerequisite scripts required for the Fire Eagle request to function, and to prevent trying to instantiate the &lt;code&gt;FireEagle&lt;/code&gt; object before it&amp;#8217;s been loaded over the wire, the remaining instantiation and request is wrapped inside a &lt;code&gt;setTimeout&lt;/code&gt; delay.&lt;/p&gt;

	&lt;p&gt;We then create the request &lt;span class="caps"&gt;URL&lt;/span&gt;, referencing the &lt;code&gt;Geomarklet.callback&lt;/code&gt; callback function and then append the script to the document body — allowing a cross-domain request.&lt;/p&gt;

	&lt;p&gt;The callback itself is quite simple. Check for the presence and value of &lt;code&gt;rsp.status&lt;/code&gt; to test for errors, and display them as required. If the request is successful set the &lt;code&gt;index_offset&lt;/code&gt; — to adjust for the granularity of the location hierarchy — and then pass the object to the renderer.&lt;/p&gt;

	&lt;p&gt;The result? When &lt;code&gt;Geomarklet.run()&lt;/code&gt; is called, your location from Fire Eagle is read, and each &lt;code&gt;renderer&lt;/code&gt; displayed on the page in an easily copy and pasteable form, ready to be used however you need.&lt;/p&gt;

	&lt;h3&gt;Deploy&lt;/h3&gt;

	&lt;p&gt;The final step is to convert this code into a long string for use as a bookmarklet. Easiest for Mac users is the JavaScript bundle in TextMate — choose &lt;kbd&gt;Bundles: JavaScript: Copy as Bookmarklet to Clipboard&lt;/kbd&gt;. Then create a new ‘Get Location’ bookmark in your browser of choice and paste in.&lt;/p&gt;

	&lt;p&gt;Those without TextMate can shrink their code down into a single line by first running their code through the &lt;a href="http://jslint.com/"&gt;&lt;span class="caps"&gt;JSL&lt;/span&gt;int&lt;/a&gt; tool (to ensure the code is free from errors and has all the required semi-colons) and then use a find-and-replace tool to remove line breaks from your code (or even run your code through &lt;a href="http://fmarcia.info/jsmin/test.html"&gt;&lt;span class="caps"&gt;JSM&lt;/span&gt;in&lt;/a&gt; to shrink it down).&lt;/p&gt;

	&lt;p&gt;With the bookmarklet created and added to your bookmarks bar, you can now call up your location on any page at all. Get a feel for a web where your location is just another reliable part of the browsing experience.&lt;/p&gt;

	&lt;h3&gt;Where next?&lt;/h3&gt;

	&lt;p&gt;So, the Geomarklet you&amp;#8217;ve been guided through is a pretty simple premise and pretty simple output. But from this base you can start to extend: Add code that will insert each of the location renderings directly into form fields, perhaps, or how about site-specific handlers to add your location tags into the correct form field in Wordpress or Tumblr? Paste in your current location to Google Maps? Or Flickr?&lt;/p&gt;

	&lt;p&gt;Geomarklet gives you a base to start experimenting with location on your own pages and the sites you browse daily.&lt;/p&gt;

	&lt;p&gt;The introduction of consumer accessible geo to the web is an adventure of discovery; not so much discovering new locations, but discovering location itself.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=4PubaipZUmc:v-815h9UQPE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=4PubaipZUmc:v-815h9UQPE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=4PubaipZUmc:v-815h9UQPE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=4PubaipZUmc:v-815h9UQPE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=4PubaipZUmc:v-815h9UQPE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/4PubaipZUmc" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://ben-ward.co.uk/"&gt;Ben Ward&lt;/a&gt; walks us through the process of building a small client-side application using the Fire Eagle &lt;span class="caps"&gt;API&lt;/span&gt;. Yahoo&amp;#8217;s Fire Eagle is a service for disseminating details of your location physical location to other services on the web. Ben shows us how such a thing can be made useful.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/geotag-everywhere-with-fire-eagle</feedburner:origLink></entry>
<entry>
		<author>
			<name>Gavin Bell</name>
		</author>
		<published>2008-12-20T00:00:13Z</published>
		<updated>2008-12-20T00:00:13Z</updated>
		<title type="html">Ghosts On The Internet</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/8FpKirXRosg/ghosts-on-the-internet" />
		<id>tag:24ways.org,2008-12-19:7e1577ceca7ea22e28af5c35ee62927a/3c3cac8f504d9fe8eebd76af41604f84</id>
		<category term="microformats" />
		<category term="information-architecture" />
		<content type="html">
&lt;p&gt;By rights the internet should be full of poltergeists, poor rootless things looking for their real homes. Many events on the internet are not properly associated with their correct timeframe. I don&amp;#8217;t mean a server set to the wrong time, though that happens too. Much of the content published on the internet is separated from any proper reference to its publication time. What does publication even mean? Let me tell you a story&amp;#8230;&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;&amp;#8220;It is 2019 and this is Kathy Clees reporting on the story of the moment, the shock purchase of Microsoft by Apple Inc. A Internet Explorer security scare story from 2008 was responsible, yes from 11 years ago, accidently promoted by an analyst, who neglected to check the date of their sources.&amp;#8221;&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;If you think this is fanciful nonsense, then cast your mind back to September 2008, this story in &lt;a href="http://blog.wired.com/27bstroke6/2008/09/six-year-old-st.html"&gt;Wired&lt;/a&gt; or &lt;a href="http://technology.timesonline.co.uk/tol/news/tech_and_web/article4742147.ece"&gt;The Times (UK)&lt;/a&gt; about a huge United Airlines stock tumble. A Florida newspaper had a automated popular story section. A random reader looking at a story about United&amp;#8217;s 2002 Bankruptcy proceedings caused this story to get picked up by Google&amp;#8217;s later visit to the South Florida Sun Sentinel&amp;#8217;s news home page. &lt;/p&gt;

	&lt;p&gt;The story was undated, Google&amp;#8217;s news engine apparently gave it a 2008 date, an analyst picked it up and pushed it to Bloomberg and within minutes the United stock was tumbling. Their stock price dropped from $12 to $3, then recovered to $11 over the day. An eight percent fall in share price over a mis-configured date&lt;/p&gt;

	&lt;p&gt;Completing this out of order Christmas Carol, lets look at what is current practice and how dates are managed, we might even get to clank some chains. Publication date used to be inseparable from publication, the two things where stamped on the same piece of paper. How can we determine when things have been published, now?&lt;/p&gt;

	&lt;h3&gt;Determining publication dates&lt;/h3&gt;

	&lt;p&gt;Time as defined by &lt;a href="http://www.w3.org/TR/NOTE-datetime"&gt;http://www.w3.org/TR/NOTE-datetime&lt;/a&gt; extends &lt;span class="caps"&gt;ISO&lt;/span&gt; 8601, mandating the use of a year value. This is pretty well defined, we can even get very accurate timings down to milliseconds, Ruby and other languages can even handle &lt;a href="http://www.ruby-doc.org/core/classes/DateTime.html"&gt;Calendar reformation&lt;/a&gt;. So accuracy is not the issue.&lt;/p&gt;

	&lt;p&gt;One problem is that there are many dates which could be interpreted as the publication date. Publication can mean any of date written or created; date placed on server; last modified date; or the current date from the web server. Created and modified have parallels with file systems, but the large number of database driven websites means that this no longer holds much meaning, as there are no longer any files. &lt;/p&gt;

	&lt;p&gt;Checking web server &lt;code&gt;HEAD&lt;/code&gt; may also not correspond, it might give the creation time for the &lt;span class="caps"&gt;HTML&lt;/span&gt; file you are viewing or it might give the last modified time for a file from disk. It is too unreliable and lacking in context to be of real value. So if the web server will not help, then how can we get the right timeframe for our content? &lt;/p&gt;

	&lt;p&gt;We are left with &lt;span class="caps"&gt;URL&lt;/span&gt;s and the actual page content.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;a href="http://www.flickr.com/photos/douglascountyhistory/2714248706/in/datetaken/"&gt;&lt;img src="http://farm4.static.flickr.com/3050/2714248706_50d6c9f968.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;Looking at Flickr, &lt;a href="http://www.flickr.com/photos/douglascountyhistory/2714248706/in/datetaken/"&gt;this picture&lt;/a&gt; (by Douglas County History Research Center) has four date values which can be associated with it. It was taken around 1900, scanned in 1992 and placed on Flickr on July 29th, 2008 and replaced later that day. Which dates should be represented here? &lt;/p&gt;

	&lt;p&gt;This is hard question to answer, but currently the date of upload to Flickr is the best represented in terms of the date &lt;span class="caps"&gt;URL&lt;/span&gt;, &lt;code&gt;/photos/douglascountyhistory/archives/date-posted/2008/07/29/&lt;/code&gt;, plus some &lt;a href="http://dublincore.org/"&gt;Dublin Core&lt;/a&gt; &lt;span class="caps"&gt;RDF&lt;/span&gt; for the year. Flickr uses 2008 as the value for this image. Not accurate, but a reasonable compromise for the millions of other images on their site.&lt;/p&gt;

	&lt;p&gt;Flickr represents location much better than it represents time. For the most part this is fine, but once you go back in time to the 1800s then the maps of the world start to change a lot and you need to reference both time and place.&lt;/p&gt;

	&lt;p&gt;The &lt;a href="http://www.google.com/experimental/#RefinementBarTopViewTabs"&gt;Google timeline search&lt;/a&gt; offers another interesting window on the world, showing results organised by decade for any search term. Being able to jump to a specific occurrence of a term makes it easier to get primary results rather than later reporting. &lt;/p&gt;

	&lt;p&gt;The 1918 &lt;a href="http://www.google.com/views?hl=en&amp;amp;client=safari&amp;amp;rls=en-gb&amp;amp;q=influenza+view:timeline&amp;amp;btnG=Search&amp;amp;sa=N&amp;amp;ct=timeline"&gt;&amp;#8220;Spanish flu&amp;#8221;&lt;/a&gt; results jump out in this timeline. &lt;/p&gt;

	&lt;p class="image"&gt;&lt;a href="http://www.google.com/views?hl=en&amp;amp;client=safari&amp;amp;rls=en-gb&amp;amp;q=influenza+view:timeline&amp;amp;btnG=Search&amp;amp;sa=N&amp;amp;ct=timeline"&gt;&lt;img src="http://media.24ways.org/2008/20/timeline.png" width="647" height="112" alt="Timeline search result from Google" /&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;Any major news event will have multiple analysis articles after the event, finding the original reporting of hurricane Katrina is harder now. Many publishers are putting older content online, e.g. &lt;a href="http://harpers.org/archive/1963/01/0075693"&gt;Harpers&lt;/a&gt; or Nature or The Times, often these use good date based &lt;span class="caps"&gt;URL&lt;/span&gt;s, sometimes they are unhelpful database references. If this content is available for free, then how much better would it be to provide good metadata on date of publication.&lt;/p&gt;

	&lt;h3&gt;Date based &lt;span class="caps"&gt;URL&lt;/span&gt;s&lt;/h3&gt;

	&lt;p&gt;A quick word on date based &lt;span class="caps"&gt;URL&lt;/span&gt;s, they can be brilliant at capturing first published date. However they can be hard to interpret. Is &lt;code&gt;/03/04&lt;/code&gt; a date in March or April, what about &lt;code&gt;08/03/04&lt;/code&gt;? Obviously &lt;code&gt;2008/03/04&lt;/code&gt; is easier to understand, it is probably March 4th. Including a proper timestamp in the page content avoid this kind of guesswork. &lt;/p&gt;

	&lt;p&gt;Many sites represent the date as a plain text string; a few hook an &lt;span class="caps"&gt;HTML&lt;/span&gt; class of &lt;code&gt;date&lt;/code&gt; around it, a very few provide an actual timestamp. Associating the date with the individual content makes it harder to get the date wrong.&lt;/p&gt;

	&lt;p&gt;Movable Type and TypePad are a notable exceptions, they will embed Dublin Core &lt;span class="caps"&gt;RDF&lt;/span&gt; to represent each posting e.g. &lt;code&gt;dc:date=&amp;quot;2008-12-18T02:57:28-08:00&amp;quot;&lt;/code&gt;. WordPress doesn&amp;#8217;t support date markup out of the box, though there is &lt;a href="http://trac.wordpress.org/ticket/2105"&gt;a patch&lt;/a&gt; and &lt;a href="http://fberriman.com/2006/08/07/implementing-hatom-the-entries-code/"&gt;a howto&lt;/a&gt; for &lt;a href="http://microformats.org/wiki/hatom"&gt;hAtom&lt;/a&gt; available.&lt;/p&gt;

	&lt;p&gt;In terms of newspapers, the &lt;span class="caps"&gt;BBC&lt;/span&gt; use &lt;code&gt;&amp;lt;meta name=&amp;quot;OriginalPublicationDate&amp;quot; content=&amp;quot;2008/12/18 18:52:05&amp;quot; /&amp;gt;&lt;/code&gt; along with opaque &lt;span class="caps"&gt;URL&lt;/span&gt;s such as &lt;code&gt;http://news.bbc.co.uk/1/hi/technology/7787335.stm&lt;/code&gt;. &lt;/p&gt;

	&lt;p&gt;The Guardian use nice clear &lt;span class="caps"&gt;URL&lt;/span&gt;s &lt;code&gt;http://www.guardian.co.uk/business/2008/dec/18/car-industry-recession&lt;/code&gt; but have no marked up date on the page. &lt;/p&gt;

	&lt;p&gt;The New York Times are similar to the Guardian with nice &lt;span class="caps"&gt;URL&lt;/span&gt;s, &lt;code&gt;http://www.nytimes.com/2008/12/19/business/19markets.html&lt;/code&gt;, but again no timestamps. All of these papers have all the data available, but it is not marked up in a useful manner.&lt;/p&gt;

	&lt;h3&gt;Syndication formats&lt;/h3&gt;

	&lt;p&gt;Syndication formats are better at supporting dates, &lt;a href="http://cyber.law.harvard.edu/rss/rss.html"&gt;&lt;span class="caps"&gt;RSS&lt;/span&gt;&lt;/a&gt; uses &lt;a href="http://tools.ietf.org/html/rfc822"&gt;&lt;span class="caps"&gt;RFC&lt;/span&gt; 822&lt;/a&gt; for dates, just like email so dates such as &lt;code&gt;Wed, 17 Dec 2008 12:52:40 GMT&lt;/code&gt; are valid, with all the white space issues that entails. &lt;/p&gt;

	&lt;p&gt;The Atom syndication format uses the much clearer &lt;code&gt;http://tools.ietf.org/html/rfc3339&lt;/code&gt; with timestamps of the form &lt;code&gt;1996-12-19T16:39:57-08:00&lt;/code&gt;. Both syndication formats encourage the use of last modified. This is understandable, but a pity as published date is a very useful value. The Atom syndication format supports &amp;#8220;published&amp;#8221; and mandates &amp;#8220;updated&amp;#8221; as timestamps, see the &lt;a href="http://tools.ietf.org/html/rfc4287"&gt;Atom &lt;span class="caps"&gt;RFC&lt;/span&gt; 4287&lt;/a&gt; for more detail.&lt;/p&gt;

	&lt;h3&gt;Marking up dates&lt;/h3&gt;

	&lt;p&gt;However the aim of this short article is to encourage you to use &lt;a href="http://microformats.org/"&gt;microformats&lt;/a&gt; or &lt;a href="http://www.w3.org/RDF/"&gt;&lt;span class="caps"&gt;RDF&lt;/span&gt;&lt;/a&gt; to encode dates. A good example of this is Twitter, they use hAtom for each individual entry, &lt;code&gt;http://twitter.com/zzgavin/status/1065835819&lt;/code&gt; contains the following markup, which represents a human and a machine readable version of the time of that tweet.&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;published&amp;quot; title=&amp;quot;2008-12-18T22:01:27+00:00&amp;quot;&amp;gt;about 3 hours ago&amp;lt;/span&amp;gt;&lt;/code&gt; &lt;/p&gt;

	&lt;p&gt;The spec for datetime is still draft at the minute and there is still ongoing conversation around the right format and semantics for representing date and time in microformats, see the &lt;a href="http://microformats.org/wiki/datetime-design-pattern"&gt;datetime design pattern&lt;/a&gt; for details. &lt;/p&gt;

	&lt;p&gt;The &lt;a href="http://microformats.org/wiki/hatom-examples"&gt;hAtom example page&lt;/a&gt; shows the minimal changes required to implement hAtom on well formed blog post content and for other less well behaved content. You have the information already in your content publication systems, this is not some additional onerous content entry task, simply some template formatting.&lt;/p&gt;

	&lt;p&gt;I started to see this as a serious issue after reading Stewart Brand&amp;#8217;s &lt;a href="http://www.edge.org/3rd_culture/brand/"&gt;Clock of the Long Now&lt;/a&gt; about five years ago. &lt;a href="http://www.amazon.com/dp/0465007805"&gt;Brand&amp;#8217;s book&lt;/a&gt; explores the issues of short term thinking that permeate our society, thinking beyond the end of the financial year is a stretch for many people. The Long Now has a world view of a 10,000 year timeframe, see &lt;a href="http://longnow.org/"&gt;http://longnow.org/&lt;/a&gt; for much more information. Freebase from Long Now Board member Danny Hillis, supports dates quite well &amp;#8211; see the entry for &lt;a href="http://www.freebase.com/view/en/a_christmas_carol"&gt;A Christmas Carol&lt;/a&gt;.&lt;/p&gt;

	&lt;h3&gt;In conclusion&lt;/h3&gt;

	&lt;p&gt;I feel we should be making it easier for people searching for our content in the future. We&amp;#8217;ve moved through tagging content and on to geo-tagging content. Now it is time to get the timestamps right on our content. How do I know when something happened and how can I find other things that happened at the same time is a fair question. This should be something I can satisfy simply and easily. There are a range of tools available to us in either &lt;a href="http://microformats.org/wiki/hatom"&gt;hAtom&lt;/a&gt; or &lt;a href="http://www.w3.org/RDF/"&gt;&lt;span class="caps"&gt;RDF&lt;/span&gt;&lt;/a&gt; to specify time accurately alongside the content, so what is stopping you?&lt;/p&gt;

	&lt;p&gt;Thinking of the long term it is hard for us to know now what will be of relevance for future generations, so we should aim to raise the floor for publishing tools so that all content has the right timeframe associated with it. We are moving from publishing words and pictures on the internet to being able to associate publication with an individual via &lt;a href="http://microformats.org/wiki/xfn"&gt;&lt;span class="caps"&gt;XFN&lt;/span&gt;&lt;/a&gt; and &lt;a href="http://openid.net/"&gt;OpenID&lt;/a&gt;. We can associate place quite well too, the last piece of useful metadata is timeframe.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=8FpKirXRosg:0wOKSfA29fw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=8FpKirXRosg:0wOKSfA29fw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=8FpKirXRosg:0wOKSfA29fw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=8FpKirXRosg:0wOKSfA29fw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=8FpKirXRosg:0wOKSfA29fw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/8FpKirXRosg" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://gavinbell.com/"&gt;Gavin Bell&lt;/a&gt; takes some time to consider date-based content and how we publish it on the web. We&amp;#8217;re generating more digital content than ever, and the date and time of creation is an increasingly useful metric. But how do we publish that in a way that remains useful for us now and the generations to come? &lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/ghosts-on-the-internet</feedburner:origLink></entry>
<entry>
		<author>
			<name>Brian Suda</name>
		</author>
		<published>2008-12-19T00:00:24Z</published>
		<updated>2008-12-22T10:40:15Z</updated>
		<title type="html">Moo'y Christmas</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/pOi3dKmoO0U/mooy-christmas" />
		<id>tag:24ways.org,2008-12-18:7e1577ceca7ea22e28af5c35ee62927a/6071b212322a3acf2a0dadaed667123b</id>
		<category term="apis" />
		
		<content type="html">
&lt;p&gt;As the web matures, it is less and less just about the virtual world. It is becoming entangled with our world and it is harder to tell what is virtual and what is real. There are several companies who are blurring this line and make the virtual just an extension of the physical. &lt;a href="http://moo.com/"&gt;Moo&lt;/a&gt; is one such company. &lt;/p&gt;

	&lt;p&gt;Moo offers simple print on demand services. You can print business cards, moo mini cards, stickers, postcards and more. They give you the ability to upload your images, customize them, then have them sent to your door. Many companies allow this sort of digital to physical interaction, but Moo has taken it one step further and has &lt;a href="http://www.moo.com/api/"&gt;built an &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt;. &lt;/p&gt;

	&lt;h3&gt;Printable stocking stuffers &lt;/h3&gt;

	&lt;p&gt;The Moo &lt;span class="caps"&gt;API&lt;/span&gt; consists of a simple &lt;span class="caps"&gt;XML&lt;/span&gt; file that is sent to their servers. It describes all the information needed to dynamically assemble and print your object. This is very helpful, not just for when you want to print your own stickers, but when you want to offer them to your customers, friends, organization or community with no hassle. Moo handles the check-out and shipping, all you need to do is what you do best, create! &lt;/p&gt;

	&lt;p&gt;Now using an &lt;span class="caps"&gt;API&lt;/span&gt; sounds complicated, but it is actually very easy. I am going to walk you through the options so you can easily be printing in no time. &lt;/p&gt;

	&lt;p&gt;Before you can begin sending data to the Moo &lt;span class="caps"&gt;API&lt;/span&gt;, you need to register and get an &lt;span class="caps"&gt;API&lt;/span&gt; key. This is important, because it allows Moo to track usage and to credit you. To register, visit &lt;a href="http://www.moo.com/api/"&gt;http://www.moo.com/api/&lt;/a&gt; and click &amp;#8220;Request an &lt;span class="caps"&gt;API&lt;/span&gt; key&amp;#8221;. &lt;/p&gt;

	&lt;p&gt;In the following examples, I will use &lt;code&gt;{YOUR API KEY HERE}&lt;/code&gt; as a place holder, replace that with your &lt;span class="caps"&gt;API&lt;/span&gt; key and everything will work fine. &lt;/p&gt;

	&lt;p&gt;First thing you need to do is to create an &lt;span class="caps"&gt;XML&lt;/span&gt; file to describe the check-out basket. Open any text-editor and start with some &lt;span class="caps"&gt;XML&lt;/span&gt; basics. Don&amp;#8217;t worry, this is pretty simple and Moo gives you a few tools to check your &lt;span class="caps"&gt;XML&lt;/span&gt; for errors before you order. &lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;moo xsi:noNamespaceSchemaLocation=&amp;quot;http://www.moo.com/xsd/api_0.7.xsd&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt; &amp;lt;request&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt; &amp;lt;version&amp;gt;0.7&amp;lt;/version&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt; &amp;lt;api_key&amp;gt;{YOUR API KEY HERE}&amp;lt;/api_key&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt; &amp;lt;call&amp;gt;build&amp;lt;/call&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt; &amp;lt;return_to&amp;gt;http://www.example.com/return.html&amp;lt;/return_to&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt; &amp;lt;fail_to&amp;gt;http://www.example.com/fail.html&amp;lt;/fail_to&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt; &amp;lt;/request&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt; &amp;lt;payload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt; ...&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt; &amp;lt;/payload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/moo&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/1.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/1.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Much like &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;#8217;s &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;, Moo has created &lt;code&gt;&amp;lt;request&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;payload&amp;gt;&lt;/code&gt; elements all wrapped in a &lt;code&gt;&amp;lt;moo&amp;gt;&lt;/code&gt; element. &lt;/p&gt;

	&lt;p&gt;The &lt;code&gt;&amp;lt;request&amp;gt;&lt;/code&gt; element contains a few pieces of information that is the same across all the &lt;span class="caps"&gt;API&lt;/span&gt; calls. The &lt;code&gt;&amp;lt;version&amp;gt;&lt;/code&gt; element describes which version of the &lt;span class="caps"&gt;API&lt;/span&gt; is being used. This is more important for Moo than for you, so just stick with &amp;#8220;0.7&amp;#8221; for now. &lt;/p&gt;

	&lt;p&gt;The &lt;code&gt;&amp;lt;api_key&amp;gt;&lt;/code&gt; allows Moo to track sales, referrers and credit your account. &lt;/p&gt;

	&lt;p&gt;The &lt;code&gt;&amp;lt;call&amp;gt;&lt;/code&gt; element can only take &amp;#8220;build&amp;#8221; so that is pretty straight forward. The &lt;code&gt;&amp;lt;return_to&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;fail_to&amp;gt;&lt;/code&gt; elements are &lt;span class="caps"&gt;URL&lt;/span&gt;s. These are optional and are the &lt;span class="caps"&gt;URL&lt;/span&gt;s the customer is redirected to if there is an error, or when the check out process is complete. This allows for some basic branding and a custom &amp;#8220;thank you&amp;#8221; page which is under your control. That&amp;#8217;s it for the &lt;code&gt;&amp;lt;request&amp;gt;&lt;/code&gt; element, pretty easy so far! &lt;/p&gt;

	&lt;p&gt;Next up is the &lt;code&gt;&amp;lt;payload&amp;gt;&lt;/code&gt; element. What goes inside here describes what is to be printed. There are two possible elements, we can put &lt;code&gt;&amp;lt;chooser&amp;gt;&lt;/code&gt; or we can put &lt;code&gt;&amp;lt;products&amp;gt;&lt;/code&gt; directly inside &lt;code&gt;&amp;lt;payload&amp;gt;&lt;/code&gt;. They work in a similar ways, but they drop the customer into different parts of the Moo checkout process. &lt;/p&gt;

	&lt;p&gt;If you specify &lt;code&gt;&amp;lt;products&amp;gt;&lt;/code&gt; then you send the customer straight to the Moo payment process. If you specify &lt;code&gt;&amp;lt;chooser&amp;gt;&lt;/code&gt; then you send the customer one-step earlier where they are allowed to pick and choose some images, remove the ones they don&amp;#8217;t like, adjust the crop, etc. The example here will use &lt;code&gt;&amp;lt;chooser&amp;gt;&lt;/code&gt; but with a &lt;a href="http://www.moo.com/api/documentation.php#stage1_1"&gt;little bit of homework&lt;/a&gt; you can easily adjust to &lt;code&gt;&amp;lt;products&amp;gt;&lt;/code&gt; if you desire. &lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;... &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;chooser&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt; &amp;lt;product_type&amp;gt;sticker&amp;lt;/product_type&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt; &amp;lt;images&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt; &amp;lt;url&amp;gt;http://example.com/images/christmas1.jpg&amp;lt;/url&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt; &amp;lt;/images&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/chooser&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/2.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/2.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Inside the &lt;code&gt;&amp;lt;chooser&amp;gt;&lt;/code&gt; element, we can see there are two basic piece of information. The type of product we want to print, and the images that are to be printed. The &lt;code&gt;&amp;lt;product_type&amp;gt;&lt;/code&gt; element can take one of five options and is required! The possibilities are: minicard, notecard, sticker, postcard or greetingcard. We&amp;#8217;ll now look at two of these more closely. &lt;/p&gt;

	&lt;h3&gt;Moo Stickers &lt;/h3&gt;

	&lt;p&gt;In the Moo sticker books you get 90 small squarish stickers in a small little booklet. &lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/19/stickers.jpg" width="600" height="450" alt="Stickers" /&gt;&lt;/p&gt;

	&lt;p&gt;The simplest &lt;span class="caps"&gt;XML&lt;/span&gt; you could send would be something like the following payload:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;payload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;chooser&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;product_type&amp;gt;sticker&amp;lt;/product_type&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;url&amp;gt;http://example.com/image1.jpg&amp;lt;/url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;url&amp;gt;http://example.com/image2.jpg&amp;lt;/url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;url&amp;gt;http://example.com/image3.jpg&amp;lt;/url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/chooser&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/payload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/3.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/3.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;This creates a sticker book with only 3 unique images, but 30 copies of each image. The Sticker books always print 90 stickers in multiples of the images you uploaded. That example only has 3 &lt;code&gt;&amp;lt;images&amp;gt;&lt;/code&gt; elements, but you can easily duplicate the &lt;span class="caps"&gt;XML&lt;/span&gt; and send up to 90. The &lt;code&gt;&amp;lt;url&amp;gt;&lt;/code&gt; should be the full path to your image and the image needs to be a minimum of 300 pixels by 300 pixels.&lt;/p&gt;

	&lt;p&gt;You can add more &lt;span class="caps"&gt;XML&lt;/span&gt; to describe cropping, but the simplest option is to either, let your customers choose or to pre-crop all your images square so there are no issues.&lt;/p&gt;

	&lt;p&gt;The full &lt;span class="caps"&gt;XML&lt;/span&gt; you would post to the Moo &lt;span class="caps"&gt;API&lt;/span&gt; to print sticker books would look like this:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;moo xsi:noNamespaceSchemaLocation=&amp;quot;http://www.moo.com/xsd/api_0.7.xsd&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;request&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;version&amp;gt;0.7&amp;lt;/version&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;api_key&amp;gt;{YOUR API KEY HERE}&amp;lt;/api_key&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;call&amp;gt;build&amp;lt;/call&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;return_to&amp;gt;http://www.example.com/return.html&amp;lt;/return_to&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;fail_to&amp;gt;http://www.example.com/fail.html&amp;lt;/fail_to&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/request&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;payload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;chooser&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;product_type&amp;gt;sticker&amp;lt;/product_type&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;url&amp;gt;http://example.com/image1.jpg&amp;lt;/url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;/images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;url&amp;gt;http://example.com/image2.jpg&amp;lt;/url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;/images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;url&amp;gt;http://example.com/image3.jpg&amp;lt;/url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;/images&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/chooser&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/payload&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/moo&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/4.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/4.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;h3&gt;Mini-cards &lt;/h3&gt;

	&lt;p&gt;The mini-cards are the small cute business cards in 14&amp;#215;35 dimensions and come in packs of 100. &lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/19/cards.jpg" width="600" height="450" alt="Cards" /&gt;&lt;/p&gt;

	&lt;p&gt;Since the mini-cards are print on demand, this allows you to have 100 unique images on the back of the cards.&lt;/p&gt;

	&lt;p&gt;Just like the stickers example, we need the same &lt;span class="caps"&gt;XML&lt;/span&gt; setup. The &lt;code&gt;&amp;lt;moo&amp;gt;&lt;/code&gt; element and &lt;code&gt;&amp;lt;request&amp;gt;&lt;/code&gt; elements will be the same as before. The part you will focus on is the &lt;code&gt;&amp;lt;payload&amp;gt;&lt;/code&gt; section. &lt;/p&gt;

	&lt;p&gt;Since you are sending along specific information, we can&amp;#8217;t use the &lt;code&gt;&amp;lt;chooser&amp;gt;&lt;/code&gt; option any more. Switch this to &lt;code&gt;&amp;lt;products&amp;gt;&lt;/code&gt; which has a child of &lt;code&gt;&amp;lt;product&amp;gt;&lt;/code&gt;, which in turn has a &lt;code&gt;&amp;lt;product_type&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;designs&amp;gt;&lt;/code&gt;. This might seem like a lot of work, but once you have it set up you won&amp;#8217;t need to change it.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;payload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;products&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;product&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;product_type&amp;gt;minicard&amp;lt;/product_type&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;designs&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;/designs&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/product&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/products&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/payload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/5.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/5.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;So now that we have the basic framework, we can talk about the information specific to minicards. Inside the &lt;code&gt;&amp;lt;designs&amp;gt;&lt;/code&gt; element, you will have one &lt;code&gt;&amp;lt;design&amp;gt;&lt;/code&gt; for each card. Much like before, this contains a way to describe the image. Note that this time the element is called &lt;code&gt;&amp;lt;image&amp;gt;&lt;/code&gt;, not images plural. &lt;/p&gt;

	&lt;p&gt;Inside the &lt;code&gt;&amp;lt;image&amp;gt;&lt;/code&gt; element you have a &lt;code&gt;&amp;lt;url&amp;gt;&lt;/code&gt; which points to where the image lives and a &lt;code&gt;&amp;lt;type&amp;gt;&lt;/code&gt;. The &lt;code&gt;&amp;lt;type&amp;gt;&lt;/code&gt; should just be set to &amp;#8216;variable&amp;#8217;. You can pass crop information here instead, but we&amp;#8217;re going to keep it simple for this tutorial. If you are interested in how that works, you should refer to the official &lt;span class="caps"&gt;API&lt;/span&gt; documentation.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;design&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;image&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;url&amp;gt;http://example.com/image1.jpg&amp;lt;/url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;type&amp;gt;variable&amp;lt;/type&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/image&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/design&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/6.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/6.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;So far, we have managed to build a pack of 100 Moo mini-cards with the same image on the front. If you wanted 100 different images, you just need to replicate this snippit, 99 more times.&lt;/p&gt;

	&lt;p&gt;That describes the front design, but the flip-side of your mini-cards can contain 6 lines of text, which is customizable in a variety of colors, fonts and styles.&lt;/p&gt;

	&lt;p&gt;The &lt;span class="caps"&gt;API&lt;/span&gt; allows you to create different text on the back of each mini-card, something the web interface doesn&amp;#8217;t implement. To describe the text on the mini-card we need to add a &lt;code&gt;&amp;lt;text_collection&amp;gt;&lt;/code&gt; element inside the &lt;code&gt;&amp;lt;design&amp;gt;&lt;/code&gt; element. If you skip this element, the back of your mini-card will just be blank, but that&amp;#8217;s not very festive!&lt;/p&gt;

	&lt;p&gt;Inside the &lt;code&gt;&amp;lt;text_collection&amp;gt;&lt;/code&gt; element, we need to describe the type of text we want to format, so we add a &lt;code&gt;&amp;lt;minicard&amp;gt;&lt;/code&gt; element, which in turn contains all the lines of text. Each of Moo&amp;#8217;s printed products take different numbers of lines of text, so if you are not planning on making mini-cards, be sure to consult the documentation.&lt;/p&gt;

	&lt;p&gt;For mini-cards, we can have 6 distinct lines, each with their own style and layout. Each line is represented by an element &lt;code&gt;&amp;lt;text_line&amp;gt;&lt;/code&gt; which has several optional children. The &lt;code&gt;&amp;lt;id&amp;gt;&lt;/code&gt; tells which line of the 6 to print the text one. The &lt;code&gt;&amp;lt;string&amp;gt;&lt;/code&gt; is the text you want to print and it must be shorter than 38 characters. The &lt;code&gt;&amp;lt;bold&amp;gt;&lt;/code&gt; element is false by default, but if you want your text bolded, then add this and set it to true. &lt;/p&gt;

	&lt;p&gt;The &lt;code&gt;&amp;lt;align&amp;gt;&lt;/code&gt; element is also optional. By default it is set to align left. You can also set this to right or center if you desirer. The &lt;code&gt;&amp;lt;font&amp;gt;&lt;/code&gt; element takes one of 3 types, modern, traditional or typewriter. The default is modern. Finally, you can set the &lt;code&gt;&amp;lt;colour&amp;gt;&lt;/code&gt;, yes that&amp;#8217;s color with a &amp;#8216;u&amp;#8217;, Moo is a British company, so they get to make the rules. When you start a print on demand company, you can spell it however you want. The &lt;code&gt;&amp;lt;colour&amp;gt;&lt;/code&gt; element takes a 6 character hex value with a leading #.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;design&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;...&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;text_collection&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;minicard&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;text_line&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;id&amp;gt;(1-6)&amp;lt;/id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;string&amp;gt;String, I must be less than 38 chars!&amp;lt;/string&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;bold&amp;gt;true&amp;lt;/bold&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;align&amp;gt;left&amp;lt;/align&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;font&amp;gt;modern&amp;lt;/font&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;colour&amp;gt;#ff0000&amp;lt;/colour&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;/text_line&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/minicard&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/text_collection&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/design&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/7.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/7.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;If you combine all of this into a mini-card request you&amp;#8217;d get this example:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;moo xsi:noNamespaceSchemaLocation=&amp;quot;http://www.moo.com/xsd/api_0.7.xsd&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;request&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;version&amp;gt;0.7&amp;lt;/version&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;api_key&amp;gt;{YOUR API KEY HERE}&amp;lt;/api_key&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;call&amp;gt;build&amp;lt;/call&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;return_to&amp;gt;http://www.example.com/return.html&amp;lt;/return_to&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;fail_to&amp;gt;http://www.example.com/fail.html&amp;lt;/fail_to&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/request&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;payload&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;products&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;product&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;product_type&amp;gt;minicard&amp;lt;/product_type&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;designs&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;&amp;lt;design&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;lt;image&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab7"&gt;&lt;code&gt;&amp;lt;url&amp;gt;http://example.com/image1.jpg&amp;lt;/url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab7"&gt;&lt;code&gt;&amp;lt;type&amp;gt;variable&amp;lt;/type&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;lt;/image&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;lt;text_collection&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab7"&gt;&lt;code&gt;&amp;lt;minicard&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab8"&gt;&lt;code&gt;&amp;lt;text_line&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab8"&gt;&lt;code&gt;&amp;lt;id&amp;gt;1&amp;lt;/id&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab8"&gt;&lt;code&gt;&amp;lt;string&amp;gt;String, I must be less than 38 chars!&amp;lt;/string&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab8"&gt;&lt;code&gt;&amp;lt;bold&amp;gt;true&amp;lt;/bold&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab8"&gt;&lt;code&gt;&amp;lt;align&amp;gt;left&amp;lt;/align&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab8"&gt;&lt;code&gt;&amp;lt;font&amp;gt;modern&amp;lt;/font&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab8"&gt;&lt;code&gt;&amp;lt;colour&amp;gt;#ff0000&amp;lt;/colour&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab8"&gt;&lt;code&gt;&amp;lt;/text_line&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab7"&gt;&lt;code&gt;&amp;lt;/minicard&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;&amp;lt;/text_collection&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;&amp;lt;/design&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;&amp;lt;/designs&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;/product&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/products&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/payload&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/moo&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/8.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/8.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Now you know how to construct the &lt;span class="caps"&gt;XML&lt;/span&gt; that describes what to print. Next, you need to know how to send it to Moo to make it happen!&lt;/p&gt;

	&lt;h3&gt;Posting to the &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/h3&gt;

	&lt;p&gt;So your &lt;span class="caps"&gt;XML&lt;/span&gt; is file ready to go. First thing we need to do is check it to make sure it&amp;#8217;s valid. Moo has created a &lt;a href="http://www.moo.com/api/validator.php"&gt;simple validator&lt;/a&gt; where you paste in your &lt;span class="caps"&gt;XML&lt;/span&gt;, and it alerts you to problems.&lt;/p&gt;

	&lt;p&gt;When you have a fully valid &lt;span class="caps"&gt;XML&lt;/span&gt; file, you&amp;#8217;ll want to send that to the Moo &lt;span class="caps"&gt;API&lt;/span&gt;. There are a few ways to do this, but the simplest is with an &lt;span class="caps"&gt;HTML&lt;/span&gt; form. &lt;/p&gt;

	&lt;p&gt;This is the sample code for an &lt;span class="caps"&gt;HTML&lt;/span&gt; form with a big &amp;#8220;Buy My Stickers&amp;#8221; button. Once you know that it is working, you can use all your existing &lt;span class="caps"&gt;HTML&lt;/span&gt; knowledge to style it up any way you like.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;form method=&amp;quot;POST&amp;quot; action=&amp;quot;http://www.moo.com/api/api.php&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;xml&amp;quot; value=&amp;quot;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt; &amp;lt;moo xsi:noNamespaceSchemaLocation=&amp;quot;http://www.moo.com/xsd/api_0.7.xsd&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&amp;gt; &amp;lt;request&amp;gt;....&amp;lt;/request&amp;gt; &amp;lt;payload&amp;gt;...&amp;lt;/payload&amp;gt; &amp;lt;/moo&amp;gt; &amp;quot;&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;submit&amp;quot; name=&amp;quot;submit&amp;quot; value=&amp;quot;Buy My Stickers&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/mooy-christmas/9.txt" title="Download the above code as a textfile"&gt;/code/mooy-christmas/9.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;This is just a basic &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element that submits to the Moo &lt;span class="caps"&gt;API&lt;/span&gt;, &lt;code&gt;http://www.moo.com/api/api.php&lt;/code&gt;, when someone clicks the button. There is a hidden input called &amp;#8220;xml&amp;#8221; which contains the value the &lt;span class="caps"&gt;XML&lt;/span&gt; file we created previously.&lt;/p&gt;

	&lt;p&gt;For those of you who need to &amp;#8220;view source&amp;#8221; to fully understand what&amp;#8217;s happening can see &lt;a href="http://suda.co.uk/projects/microformats/moo/"&gt;a working version&lt;/a&gt; and peek under the hood.&lt;/p&gt;

	&lt;p&gt;Using the &lt;span class="caps"&gt;API&lt;/span&gt; has advantages over uploading the images directly yourself. The images and text that you send via the &lt;span class="caps"&gt;API&lt;/span&gt; can be dynamic. Some companies, like &lt;a href="http://dopplr.com/"&gt;Dopplr&lt;/a&gt;, have taken user profiles and dynamic data that changes every minute to generate customer stickers of places that you&amp;#8217;ve travelled to or mini-cards with a world map of all the cities you have visited. Every single customer has different travel plans and therefore different sets of stickers and mini-card maps. The &lt;span class="caps"&gt;API&lt;/span&gt; allows for the utmost current information to be printed, on demand, in real-time.&lt;/p&gt;

	&lt;h3&gt;Go forth and Moo&amp;#8217;ltiply&lt;/h3&gt;

	&lt;p&gt;See, making an &lt;span class="caps"&gt;API&lt;/span&gt; call wasn&amp;#8217;t that hard was it? You are now 90% of the way to creating anything with the Moo &lt;span class="caps"&gt;API&lt;/span&gt;. With a bit of reading, you can learn that extra 10% and print any Moo product. Be on the lookout in 2009 for the official release of the 1.0 &lt;span class="caps"&gt;API&lt;/span&gt; with improvements and some extras that were not available when this article was written.&lt;/p&gt;

	&lt;p&gt;This article is released under the creative-commons attribution share-a-like license. That means you are free to re-distribute it, mash it up, translate it and otherwise re-using it ways the author never considered, in return he only asks you mention his name.&lt;/p&gt;

	&lt;p&gt;&lt;a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"&gt;&lt;img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /&gt;&lt;/a&gt;&lt;br /&gt;
This &lt;span xmlns:dc="http://purl.org/dc/elements/1.1/" href="http://purl.org/dc/dcmitype/Text" rel="dc:type"&gt;work&lt;/span&gt; by &lt;span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName"&gt;Brian Suda&lt;/span&gt; is licensed under a &lt;a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"&gt;Creative Commons Attribution-Share Alike 3.0 Unported License&lt;/a&gt;.	&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=pOi3dKmoO0U:DlcaetR1h3s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=pOi3dKmoO0U:DlcaetR1h3s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=pOi3dKmoO0U:DlcaetR1h3s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=pOi3dKmoO0U:DlcaetR1h3s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=pOi3dKmoO0U:DlcaetR1h3s:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/pOi3dKmoO0U" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://suda.co.uk"&gt;Brian Suda&lt;/a&gt; mooves us up a gear with a look at using the Moo &lt;span class="caps"&gt;API&lt;/span&gt; for print-on-demand services. No web application is an island, so well written &lt;span class="caps"&gt;API&lt;/span&gt;s can be a great way to hook into specialist services with the very minimum of effort. With a few simple steps, print can be one of those services.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/mooy-christmas</feedburner:origLink></entry>
<entry>
		<author>
			<name>John Allsopp</name>
		</author>
		<published>2008-12-18T00:00:08Z</published>
		<updated>2008-12-18T08:46:04Z</updated>
		<title type="html">Shiny Happy Buttons</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/aWhYr88VNgQ/shiny-happy-buttons" />
		<id>tag:24ways.org,2008-12-17:7e1577ceca7ea22e28af5c35ee62927a/24e0d56244e9bd63e3d22dc019c80b4a</id>
		<category term="css" />
		
		<content type="html">
&lt;p&gt;Since Mac OS X burst onto our screens, glossy, glassy, shiny buttons have been almost de rigeur, and have essentially, along with reflections and rounded corners, become a cliché of Web 2.0 &amp;#8220;design&amp;#8221;. But if you can&amp;#8217;t beat &amp;#8216;em you&amp;#8217;d better join &amp;#8216;em. So, in this little contribution to our advent calendar, we&amp;#8217;re going to take a plain old boring &lt;span class="caps"&gt;HTML&lt;/span&gt; button, and 2.0 it up the wazoo. &lt;/p&gt;

	&lt;p&gt;But, here&amp;#8217;s the catch. We&amp;#8217;ll use no images, either in our &lt;span class="caps"&gt;HTML&lt;/span&gt; or our &lt;span class="caps"&gt;CSS&lt;/span&gt;. No sliding doors, no image replacement techniques. Just straight up, &lt;span class="caps"&gt;CSS&lt;/span&gt;, CSS3 and a bit of experimental &lt;span class="caps"&gt;CSS&lt;/span&gt;. And, it will be compatible with pretty much any browser (though with some progressive enhancement for those who keep up with the latest browsers).&lt;/p&gt;

	&lt;h3&gt;The &lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/h3&gt;

	&lt;p&gt;We&amp;#8217;ll start with our &lt;span class="caps"&gt;HTML&lt;/span&gt;.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;button type=&amp;quot;submit&amp;quot;&amp;gt;This is a shiny button&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;OK, so it&amp;#8217;s not shiny yet &amp;#8211; but boy will it ever be.&lt;/p&gt;

	&lt;p&gt;Before styling, that&amp;#8217;s going to &lt;a href="http://media.24ways.org/2008/18/button.html"&gt;look like this&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;Ironically, depending on the operating system and browser you are using, it may well be a shiny button already, but that&amp;#8217;s not the point. We want to make it shiny 2.0. Our mission is to make it look something like this&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/18/buttondone.png" alt="Shiny button as it will look when finished, in Safari" /&gt;&lt;/p&gt;

	&lt;p&gt;If you want to follow along at home keep in mind that depending on which browser you are using you may see fewer of the &lt;span class="caps"&gt;CSS&lt;/span&gt; effects we&amp;#8217;ve added to create the button. As of writing, only in Safari are all the effects we&amp;#8217;ll apply supported.&lt;/p&gt;

	&lt;p&gt;Taking a look at our finished product, here&amp;#8217;s what we&amp;#8217;ve done to it:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;We&amp;#8217;ve given the button some padding and a width.&lt;/li&gt;
		&lt;li&gt;We&amp;#8217;ve changed the text color, and given the text a drop shadow.&lt;/li&gt;
		&lt;li&gt;We&amp;#8217;ve given the button a border.&lt;/li&gt;
		&lt;li&gt;We&amp;#8217;ve given the button some rounded corners.&lt;/li&gt;
		&lt;li&gt;We&amp;#8217;ve given the button a drop shadow.&lt;/li&gt;
		&lt;li&gt;We&amp;#8217;ve given the button a gradient background.&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p&gt;and remember, all without using any images.&lt;/p&gt;

	&lt;h3&gt;Styling the button&lt;/h3&gt;

	&lt;p&gt;So, let&amp;#8217;s get to work.&lt;/p&gt;

	&lt;p&gt;First, we&amp;#8217;ll add given the element some padding and a width:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;button {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;padding: .5em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 15em;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Next, we&amp;#8217;ll add the text color, and the drop shadow:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;color: #ffffff;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;text-shadow: 1px 1px 1px #000;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;h4&gt;A note on text-shadow&lt;/h4&gt;

	&lt;p&gt;If you&amp;#8217;ve not seen text-shadows before well, here&amp;#8217;s the quick back-story. Text shadow was introduced in CSS2, but only supported in Safari (version 1!) some years later. It was removed from CSS2.1, but returned in CSS3 (in the &lt;a href="http://www.w3.org/TR/2003/CR-css3-text-20030514/#text-shadows"&gt;text&lt;/a&gt; module). It&amp;#8217;s now supported in Safari, Opera and Firefox (3.1). Internet Explorer has a shadow filter, but the syntax is completely different.&lt;/p&gt;

	&lt;p&gt;So, how do text-shadows work? The three length values specify respectively a horizontal offset, a vertical offset and a blur (the greater the number the more blurred the shadow will be), and finally a color value for the shadow.&lt;/p&gt;

	&lt;h4&gt;Rounding the corners&lt;/h4&gt;

	&lt;p&gt;Now we&amp;#8217;ll add a border, and round the corners of the element:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;border: solid thin #882d13;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-webkit-border-radius: .7em;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-moz-border-radius: .7em;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;border-radius: .7em;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Here, we&amp;#8217;ve used the same property in three slightly different forms. We add the browser specific prefix for Webkit and Mozilla browsers, because right now, both of these browsers only support border radius as an experimental property. We also add the standard property name, for browsers that do support the property fully in the future. &lt;/p&gt;

	&lt;p&gt;The benefit of the browser specific prefix is that if a browser only partly supports a given property, we can easily avoid using the property with that browser simply by not adding the browser specific prefix. At present, as you might guess, &lt;code&gt;border-radius&lt;/code&gt; is supported in Safari and Firefox, but in each the relevant prefix is required.&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;border-radius&lt;/code&gt; takes a length value, such as pixels. (It can also take two length values, but that&amp;#8217;s for another Christmas.) In this case, as with padding, I&amp;#8217;ve used ems, which means that as the user scales the size of text up and down, the radius will scale as well. You can test the difference by making the radius have a value of say 5px, and then zooming up and down the text size. &lt;/p&gt;

	&lt;p&gt;We&amp;#8217;re well and truly on the way now. All we need to do is add a shadow to the button, and then a gradient background.&lt;/p&gt;

	&lt;p&gt;In CSS3 there&amp;#8217;s the &lt;code&gt;box-shadow&lt;/code&gt; property, currently only supported in Safari 3. It&amp;#8217;s very similar to &lt;code&gt;text-shadow&lt;/code&gt; &amp;#8211; you specify a horizontal and vertical offset, a blur value and a color.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;-webkit-box-shadow: 2px 2px 3px #999; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;box-shadow: 2px 2px 2px #bbb;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Once more, we require the &amp;#8220;experimental&amp;#8221; &lt;code&gt;-webkit-&lt;/code&gt; prefix, as Safari&amp;#8217;s support for this property is still considered by its developers to be less than perfect.&lt;/p&gt;

	&lt;h4&gt;Gradient Background&lt;/h4&gt;

	&lt;p&gt;So, all we have left now is to add our shiny gradient effect. Now of course, people have been doing this kind of thing with images for a long time. But if we can avoid them all the better. Smaller pages, faster downloads, and more scalable designs that adapt better to the user&amp;#8217;s font size preference. But how can we add a gradient background without an image?&lt;/p&gt;

	&lt;p&gt;Here we&amp;#8217;ll look at the only property that is not as yet part of the &lt;span class="caps"&gt;CSS&lt;/span&gt; standard &amp;#8211; Apple&amp;#8217;s gradient function for use anywhere you can use images with &lt;span class="caps"&gt;CSS&lt;/span&gt; (in this case backgrounds). In essence, this takes &lt;span class="caps"&gt;SVG&lt;/span&gt; gradients, and makes them available via &lt;span class="caps"&gt;CSS&lt;/span&gt; syntax.&lt;/p&gt;

	&lt;p&gt;Here&amp;#8217;s what the property and its value looks like:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;background-image: -webkit-gradient(linear, left top, left bottom, from(#e9ede8), to(#ce401c),color-stop(0.4, #8c1b0b));&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Zooming in on the gradient function, it has this basic form:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;-webkit-gradient(type, point, point, from(color), to(color),color-stop(where, color));&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Which might look complicated, but is less so than at first glance.&lt;/p&gt;

	&lt;p&gt;The name of the function is &lt;code&gt;gradient&lt;/code&gt; (and in this case, because it is an experimental property, we use the &lt;code&gt;-webkit-&lt;/code&gt; prefix).&lt;/p&gt;

	&lt;p&gt;You might not have seen &lt;span class="caps"&gt;CSS&lt;/span&gt; functions before, but there are others, including the &lt;code&gt;attr()&lt;/code&gt; function, used with generated content. A function returns a value that can be used as a property value &amp;#8211; here we are using it as a background image.&lt;/p&gt;

	&lt;p&gt;Next we specify the type of the gradient. Here we have a linear gradient, and there are also radial gradients. &lt;/p&gt;

	&lt;p&gt;After that, we specify the start and end points of the gradient &amp;#8211; in our case the top and bottom of the element, in a vertical line. &lt;/p&gt;

	&lt;p&gt;We then specify the start and end colors &amp;#8211; and finally one stop color, located at 40% of the way down the element. Together, this creates a gradient that smoothly transitions from the start color in the top, vertically to the stop color, then smoothly transitions to the end color.&lt;/p&gt;

	&lt;p&gt;There&amp;#8217;s one last thing. What color will the background of our button be if the browser doesn&amp;#8217;t support gradients? It will be white (or possibly some default color for buttons). Which may make the text difficult or impossible to read. So, we&amp;#8217;ll add a background color as well (see why the validator is always warning you when a color but not a background color is specified for an element?).&lt;/p&gt;

	&lt;p&gt;If we put it all together, here&amp;#8217;s what we have:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;button {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 15em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;padding: .5em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;color: #ffffff;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;text-shadow: 1px 1px 1px #000;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;border: solid thin #882d13;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;-webkit-border-radius: .7em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;-moz-border-radius: .7em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;border-radius: .7em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;-webkit-box-shadow: 2px 2px 3px #999; &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;box-shadow: 2px 2px 2px #bbb;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;background-color: #ce401c;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;background-image: -webkit-gradient(linear, left top, left bottom, from(#e9ede8), to(#ce401c),color-stop(0.4, #8c1b0b));&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/shiny-happy-buttons/8.txt" title="Download the above code as a textfile"&gt;/code/shiny-happy-buttons/8.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Which looks like this in various browsers:&lt;/p&gt;

	&lt;p&gt;In Safari (3)&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/18/buttondone.png" alt="shiny button as it will look when finished, in Safari" /&gt;&lt;/p&gt;

	&lt;p&gt;In Firefox 3.1 (3.0 supports border-radius but not text-shadow)&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/18/buttondoneffox.png" alt="Finished button in Firefox 3.1" /&gt;&lt;/p&gt;

	&lt;p&gt;In Opera 10&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/18/buttondoneffoxopera.png" alt="Finished button in Opera" /&gt;&lt;/p&gt;

	&lt;p&gt;and of course in Internet Explorer (version 8 shown here)&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/18/buttondoneIE.png" alt="finished button in IE" /&gt;&lt;/p&gt;

	&lt;h4&gt;But it looks different in different browsers&lt;/h4&gt;

	&lt;p&gt;Yes, it &lt;strong&gt;does&lt;/strong&gt; look different in different browsers, but we all know the answer to the question &amp;#8220;&lt;a href="http://dowebsitesneedtolookexactlythesameineverybrowser.com/"&gt;do web sites need to look the same in every browser?&lt;/a&gt;&amp;#8220;.&lt;/p&gt;

	&lt;p&gt;Even if you really think sites should look the same in every browser, hopefully this little tutorial has whet your appetite for what CSS3 and experimental &lt;span class="caps"&gt;CSS&lt;/span&gt; that&amp;#8217;s already supported in widely used browsers (and we haven&amp;#8217;t even touched on animations and similar effects!).&lt;/p&gt;

	&lt;p&gt;I hope you&amp;#8217;ve enjoyed out little &lt;span class="caps"&gt;CSSM&lt;/span&gt;as present, and look forward to seeing your shiny buttons everywhere on the web.&lt;/p&gt;

	&lt;p&gt;Oh, and there&amp;#8217;s just a bit of homework &amp;#8211; your job is to use the &lt;code&gt;:hover&lt;/code&gt; selector, and make a gradient in the hover state. &lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=aWhYr88VNgQ:4KcpRhIbKRU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=aWhYr88VNgQ:4KcpRhIbKRU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=aWhYr88VNgQ:4KcpRhIbKRU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=aWhYr88VNgQ:4KcpRhIbKRU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=aWhYr88VNgQ:4KcpRhIbKRU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/aWhYr88VNgQ" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://www.westciv.com/"&gt;John Allsopp&lt;/a&gt; has a shining example of what can be done to customise the look of &lt;span class="caps"&gt;HTML&lt;/span&gt; buttons without resorting to images. Custom button styles are a frequent request, but the use of images can heavily restrict the implementation. Avoid those pitfalls by sticking to pure &lt;span class="caps"&gt;CSS&lt;/span&gt;.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/shiny-happy-buttons</feedburner:origLink></entry>
<entry>
		<author>
			<name>Jon Tan</name>
		</author>
		<published>2008-12-17T00:00:08Z</published>
		<updated>2008-12-17T00:00:08Z</updated>
		<title type="html">A Festive Type Folly</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/VG_G-FaNF9o/a-festive-type-folly" />
		<id>tag:24ways.org,2008-12-16:7e1577ceca7ea22e28af5c35ee62927a/e8fb5b4b689f55ecc8ac2873ae06f7cb</id>
		<category term="typography" />
		
		<content type="html">
&lt;p&gt;&amp;#8216;Tis the season to be jolly, so the carol singers tell us. At 24 ways, we&amp;#8217;re keeping alive another British tradition that includes the odd faux-Greco-Roman building dotted around the British countryside, Tower Bridge built in 1894, and your Dad&amp;#8217;s Christmas jumper with the dancing reindeer motif. &amp;#8216;Tis the season of the &lt;a href="http://en.wikipedia.org/wiki/Folly"&gt;folly&lt;/a&gt;!&lt;/p&gt;

 &lt;div id="type"&gt;
 &lt;h1&gt;&lt;a href="http://24ways.org/2008/a-festive-type-folly"&gt;&lt;em&gt;2&lt;span&gt;4 &lt;span&gt;W&lt;span&gt;a&lt;span&gt;y&lt;span&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/em&gt; &lt;strong&gt;to &lt;span&gt;i&lt;span&gt;m&lt;span&gt;pre&lt;span&gt;s&lt;span&gt;s &lt;span&gt;your   &lt;span&gt;friends&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/h1&gt;
 &lt;/div&gt;

	&lt;p&gt;The example is not an image, just text. You may wish to see a &lt;a href="http://media.24ways.org/2008/17/safari-sample.gif"&gt;screenshot in Safari&lt;/a&gt; to compare with your own operating system and browser rendering.&lt;/p&gt;

	&lt;p&gt;Like all follies this is an embellishment — a bit of web typography fun. It&amp;#8217;s similar to the &lt;a href="http://jontangerine.com"&gt;masthead text at my place&lt;/a&gt;, but it&amp;#8217;s also a hyperlink. Unlike the architectural follies of the past, no child labour was used to fund or build it, just some &lt;abbr title="Hyper Text Markup Language"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/abbr&gt; flavoured with &lt;abbr title="Cascading Style Sheets"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/abbr&gt;, and a heavy dose of &lt;a href="http://en.wikipedia.org/wiki/Times_Roman"&gt;Times New Roman&lt;/a&gt;. Why Times New Roman, you ask? Well, after a few wasted hours experimenting with heaps of typefaces, seeking an elusive consistency of positioning and rendering across platforms, it proved to be the most consistent. Who&amp;#8217;d&amp;#8216;a thought? To make things more interesting, I wanted to use a &lt;a href="http://www.webtypography.net/Harmony_and_Counterpoint/Size/3.1.1/"&gt;traditional scale&lt;/a&gt; and make the whole thing elastic by using relative lengths that would react to a person&amp;#8217;s font size. So, to the meat of this festive frippery:&lt;/p&gt;

	&lt;p&gt;There are three things we rely on to create this indulgence:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;&lt;a href="http://24ways.org/#type-folly-descendant-selectors"&gt;Descendant selectors&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://24ways.org/#type-folly-absolute-positioning"&gt;Absolute positioning&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://24ways.org/#type-folly-inheritance"&gt;Inheritance&lt;/a&gt;&lt;/li&gt;
	&lt;/ol&gt;

	&lt;h3 id="type-folly-descendant-selectors"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt; &amp;amp; Descendant Selectors&lt;/h3&gt;

	&lt;p&gt;The markup for the folly might seem complex at first glance. To semantics pedants and purists it may seem outrageous. If that&amp;#8217;s you, read on at your peril! Here it is with lots of whitespace:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;type&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;  &amp;lt;a href=&amp;quot;/&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;    &amp;lt;em&amp;gt;2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;      &amp;lt;span&amp;gt;4 &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;        &amp;lt;span&amp;gt;w&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;          &amp;lt;span&amp;gt;a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;            &amp;lt;span&amp;gt;y&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;              &amp;lt;span&amp;gt;s&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;            &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;          &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;        &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;      &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;    &amp;lt;/em&amp;gt; &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;    &amp;lt;strong&amp;gt;to &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;      &amp;lt;span&amp;gt;i&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;        &amp;lt;span&amp;gt;m&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;          &amp;lt;span&amp;gt;pre&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;            &amp;lt;span&amp;gt;s&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;              &amp;lt;span&amp;gt;s &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;                &amp;lt;span&amp;gt;your &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;                  &amp;lt;span&amp;gt;friends&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;                &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;              &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;            &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;          &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;        &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;      &amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;    &amp;lt;/strong&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;  &amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/1.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/1.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Why so much markup? Well, we want to individually style many of the glyphs. By nesting the elements, we can pick out the bits we need as &lt;a href="http://www.w3.org/TR/CSS21/selector.html#descendant-selectors"&gt;descendant selectors&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;To retain a smidgen of semantics, the text is wrapped in &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; elements. The two phrases, &amp;#8220;24 ways&amp;#8221; and &amp;#8220;to impress your friends&amp;#8221; are wrapped in &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; tags, respectively. Within those loving arms, their descendant &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;s cascade invisibly, making a right mess of our source, but ready to be picked out in our &lt;span class="caps"&gt;CSS&lt;/span&gt; rules.&lt;/p&gt;

	&lt;p&gt;So, to select the &amp;#8220;2&amp;#8221; from the &lt;a href="http://24ways.org/#type"&gt;example&lt;/a&gt; we can simply write, &lt;code&gt;#type h1 em{ }&lt;/code&gt;. Of course, that selects everything within the &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt; tags, but as we drill down the document tree, selecting other glyphs, any property / value styles can be reset or changed as required.&lt;/p&gt;

	&lt;h3&gt;Pixels Versus Ems&lt;/h3&gt;

	&lt;p&gt;Before we get stuck into the &lt;span class="caps"&gt;CSS&lt;/span&gt;, I should say that the goal here is to have everything expressed in &lt;a href="http://www.w3.org/TR/CSS21/syndata.html#length-units"&gt;relative &amp;#8220;em&amp;#8221; lengths&lt;/a&gt;. However, when I&amp;#8217;m starting out, I use pixels for all values, and only convert them to ems after I&amp;#8217;ve finished. It saves re-calculating the em length for every change I make as the folly evolves, but still makes the final result elastic, &lt;em&gt;without&lt;/em&gt; relying on browser zoom.&lt;/p&gt;

	&lt;p&gt;To skip ahead, &lt;a href="http://media.24ways.org/2008/17/festive-type-folly.css"&gt;see the complete &lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;

	&lt;h3 id="type-folly-absolute-positioning"&gt;Absolutely Positioned Glyphs&lt;/h3&gt;

	&lt;p&gt;If a parent element has &lt;code&gt;position: relative&lt;/code&gt;, or &lt;code&gt;position: absolute&lt;/code&gt; applied to it, all children of that parent can be positioned absolutely relative to it. (See &lt;a href="http://www.mezzoblue.com/archives/2004/03/04/positioning_/"&gt;Dave Shea&amp;#8217;s excellent introduction to this&lt;/a&gt;.) That&amp;#8217;s exactly how the folly is achieved. As the parent, &lt;code&gt;#type&lt;/code&gt; also has a &lt;code&gt;font-size&lt;/code&gt; of 16px set, a width and height, and some basic style with a background and border:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#type{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;font-size: 16px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;text-align: left;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;background: #e8e9de;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;border: 0.375em solid #fff;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 22.5em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;height: 13.125em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;position: relative;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/2.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/2.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;The &lt;code&gt;h1&lt;/code&gt; is also given a default style with a &lt;code&gt;font-size&lt;/code&gt; of 132px in ems relative to the parent &lt;code&gt;font-size&lt;/code&gt; of 16px:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#type h1{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;font-family: &amp;quot;Times New Roman&amp;quot;, serif;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1 cmnt"&gt;&lt;code&gt;font-size: 8.25em; /* 132px */&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;line-height: 1em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;font-weight: 400;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;margin: 0;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;padding: 0;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/3.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/3.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;To get the em value, we divide the &lt;em&gt;required size&lt;/em&gt; in pixels by the actual parent &lt;code&gt;font-size&lt;/code&gt; in pixels&lt;/p&gt;

	&lt;p&gt;132 &amp;#247; 16 = 8.25&lt;/p&gt;

	&lt;p&gt;We also give the descendants of the &lt;code&gt;h1&lt;/code&gt; some default properties. The line height, style and weight are normalised, they are positioned absolutely relative to &lt;code&gt;#type&lt;/code&gt;, and a border and padding is applied:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#type h1 em,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 strong,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 span{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;line-height: 1em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;font-style: normal;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;font-weight: 400;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;position: absolute;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;padding: 0.1em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;border: 1px solid transparent;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/4.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/4.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;The padding ensures that some browsers don&amp;#8217;t forget about parts of a glyph that are drawn outside of their invisible container. When this happens, IE will trim the glyph, cutting off parts of descenders, for example. The border is there to make sure the glyphs have layout. Without this, positioning can be problematic. IE6 will not respect the &lt;code&gt;transparent&lt;/code&gt; border colour — it uses the actual text colour — but in all other respects renders the example. You can hack around it, but it seemed unnecessary for this example.&lt;/p&gt;

	&lt;p&gt;Once these defaults are established, the rest is trial and error. As a quick example, the numeral &amp;#8220;2&amp;#8221; is first to be positioned:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#type h1 a em{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1 cmnt"&gt;&lt;code&gt;font-size: 0.727em; /* (2) 96px */&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;left: 0.667em;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;top: 0;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/5.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/5.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Every element of the folly is positioned in exactly the same way as you can see in the &lt;a href="http://media.24ways.org/2008/17/festive-type-folly.css"&gt;complete &lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/a&gt;. When converting pixels to ems, the &lt;code&gt;font-size&lt;/code&gt; is set first. Then, because we know what that is, we calculate the equivalent x- and y-position accordingly.&lt;/p&gt;

	&lt;h3 id="type-folly-inheritance"&gt;Inheritance&lt;/h3&gt;

	&lt;p&gt;&lt;a href="http://www.w3.org/TR/CSS21/cascade.html#inheritance"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt; inheritance&lt;/a&gt; gave me a headache a long time ago when I first encountered it. After the penny dropped I came to experience something disturbingly close to affection for this characteristic. What it basically means is that children inherit the characteristics of their parents. For example:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;We gave &lt;code&gt;#type&lt;/code&gt; a &lt;code&gt;font-size&lt;/code&gt; of 16px.&lt;/li&gt;
		&lt;li&gt;For &lt;code&gt;#type h1&lt;/code&gt; we changed it by setting &lt;code&gt;font-size: 8.25em;&lt;/code&gt;. Than means that &lt;code&gt;#type h1&lt;/code&gt; now has a computed &lt;code&gt;font-size&lt;/code&gt; of 8.25 &amp;#215; 16px = 132px.&lt;/li&gt;
		&lt;li&gt;Now, all children of &lt;code&gt;#type h1&lt;/code&gt; in the document tree will inherit a &lt;code&gt;font-size&lt;/code&gt; of 132px unless we explicitly change it as we did for &lt;code&gt;#type h1 a em&lt;/code&gt;.&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p&gt;The &amp;#8220;2&amp;#8221; in the &lt;a href="http://24ways.org/#type"&gt;example&lt;/a&gt; — selected with &lt;code&gt;#type h1 a em&lt;/code&gt; — is set at 96px with &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;top&lt;/code&gt; positioning calculated relatively to that. So, the &lt;code&gt;left&lt;/code&gt; position of &lt;code&gt;0.667em&lt;/code&gt; is 0.667 × 96 = 64px, approximately (three decimal points in em lengths don&amp;#8217;t always give exact pixel equivalents).&lt;/p&gt;

	&lt;p&gt;One way to look at inheritance is as a cascade of dependancy: In our example, the computed font size of any given element &lt;em&gt;depends&lt;/em&gt; on that of the parent, and the absolute x- and y-position &lt;em&gt;depends&lt;/em&gt; on the computed font size of the element itself.&lt;/p&gt;

	&lt;h3&gt;Link Colours&lt;/h3&gt;

	&lt;p&gt;The same descendant selectors we use to set and position the type are also used to apply the colour by combining them with pseudo-selectors like &lt;code&gt;:focus&lt;/code&gt; and &lt;code&gt;:hover&lt;/code&gt;. Because the descendant selectors are available to us, we can pretty much pick out any glyph we like. First, we need to disable the underline:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:link,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:visited{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;text-decoration: none;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/6.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/6.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;In our &lt;a href="http://24ways.org/#type"&gt;example&lt;/a&gt;, the &amp;#8220;24&amp;#8221; has a unique default state (colour):&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:link em,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:visited em{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;color: #624;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/7.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/7.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;The rest of the &amp;#8220;Ways&amp;#8221; text has a different colour, which it shares with the large &amp;#8220;s&amp;#8221; in &amp;#8220;impress&amp;#8221;:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:link em span span,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:visited em span span,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:link strong span span span span,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:visited strong span span span span{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;color: #b32720;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/8.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/8.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;&amp;#8220;24&amp;#8221; changes on &lt;code&gt;:focus&lt;/code&gt;, &lt;code&gt;:hover&lt;/code&gt; and &lt;code&gt;:active&lt;/code&gt;. Critically though, the whole of the &amp;#8220;24 Ways&amp;#8221; text, and the large &amp;#8220;s&amp;#8221; in &amp;#8220;impress&amp;#8221; all have the same style in this instance:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:focus em,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:hover em,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:active em,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:focus em span span,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:hover em span span,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:active em span span,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:focus strong span span span span,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:hover strong span span span span,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#type h1 a:active strong span span span span{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;color: #804;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-festive-type-folly/9.txt" title="Download the above code as a textfile"&gt;/code/a-festive-type-folly/9.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;If a descendant selector has a &lt;code&gt;:link&lt;/code&gt; and &lt;code&gt;:visited&lt;/code&gt; state set as a pseudo element, it needs to also have the corresponding &lt;code&gt;:focus&lt;/code&gt;, &lt;code&gt;:hover&lt;/code&gt; and &lt;code&gt;:active&lt;/code&gt; states set.&lt;/p&gt;

	&lt;h3&gt;A Final Note About Web Typography&lt;/h3&gt;

	&lt;p&gt;From &lt;a href="http://www.subtraction.com/2004/12/31/grid-computi"&gt;grids&lt;/a&gt; to &lt;a href="http://www.webtypography.net/Rhythm_and_Proportion/Vertical_Motion/2.2.1/"&gt;basic leading&lt;/a&gt; to &lt;a href="http://jontangerine.com/log/2008/10/font-face-in-ie-making-web-fonts-work"&gt;web fonts&lt;/a&gt;, and even absolute positioning, there&amp;#8217;s a wealth of things we can do to treat type on the Web with love and respect. However, experiments like this can highlight the &lt;a href="http://jontangerine.com/log/2008/11/display-type-and-the-raster-wars"&gt;vagaries of rasterisation and rendering&lt;/a&gt; that limit our ability to achieve truly subtle and refined results. At the operating system level, the differences in type rendering are extreme, and even between sequential iterations in Windows — from Standard to ClearType — they can be daunting. Add to that huge variations in screen quality, and even the paper we print our type onto has many potential variations. Compare our &lt;a href="http://24ways.org/#type"&gt;example&lt;/a&gt; in Safari 3.2.1 / OS X 10.5.5 (left) and IE7 / Win XP (right). Both rendered on a 23&amp;#8221; Apple Cinema HD (&lt;span class="caps"&gt;LCD&lt;/span&gt;):&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/17/comparison.gif" alt="Type folly comparison showing much poorer anti-alias in IE7." /&gt;&lt;/p&gt;

	&lt;p&gt;Browser developers continue to make &lt;a href="http://my.opera.com/ODIN/blog/opera-10-alpha-web-fonts-acid3" title="Opera 10 to support web fonts"&gt;great strides&lt;/a&gt;. However, those of us who set type on the Web need more consistency and quality if we want to avoid technologies like Flash and evolve web typography. Although web typography is inevitably — and mistakenly — compared unfavourably to print, it has the potential to achieve the same refinement in a different way. Perhaps one day, the glyphs of our favourite faces, so carefully crafted, kerned and hinted for the screen, will be rendered with the same precision with which they were drawn by type designers and styled by web designers. That would be my wish for the new year. Happy holidays!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=VG_G-FaNF9o:vSjUT2DnVb4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=VG_G-FaNF9o:vSjUT2DnVb4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=VG_G-FaNF9o:vSjUT2DnVb4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=VG_G-FaNF9o:vSjUT2DnVb4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=VG_G-FaNF9o:vSjUT2DnVb4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/VG_G-FaNF9o" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://jontangerine.com/"&gt;Jon Tan&lt;/a&gt; upholds the good British tradition of building follies and talks us through the process of creating one such on the web using only &lt;span class="caps"&gt;HTML&lt;/span&gt; and &lt;span class="caps"&gt;CSS&lt;/span&gt;. Follies themselves are just for enjoyment. However, there&amp;#8217;s always interesting things to be learned when we venture out and have some fun. &lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/a-festive-type-folly</feedburner:origLink></entry>
<entry>
		<author>
			<name>Meri Williams</name>
		</author>
		<published>2008-12-16T00:00:14Z</published>
		<updated>2008-12-16T00:00:44Z</updated>
		<title type="html">What Your Turkey Can Teach You About Project Management</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/21V3tE3NE7U/what-your-turkey-can-teach-you-about-project-management" />
		<id>tag:24ways.org,2008-12-15:7e1577ceca7ea22e28af5c35ee62927a/e6dc1ad3d91a78566315f9f212253217</id>
		<category term="business" />
		
		<content type="html">
&lt;p&gt;The problem with project management is that everyone thinks it&amp;#8217;s boring. Well, that&amp;#8217;s not really the problem. The problem is that everyone thinks it&amp;#8217;s boring &lt;strong&gt;but it&amp;#8217;s still really important&lt;/strong&gt;. Project management is what lets you deliver your art – whether that be design or development. &lt;/p&gt;

	&lt;p&gt;In the same way, a Christmas dinner cooked by a brilliant chef with no organizational skills is disastrous – courses arrive in the wrong order, some things are cold whilst others are raw and generally it&amp;#8217;s a trip to the ER waiting to happen. Continuing the Christmas dinner theme, here are my top tips for successful projects, wrapped up in a nice little festive analogy. Enjoy!&lt;/p&gt;

	&lt;h3&gt;Tip 1: Know What You&amp;#8217;re Aiming For&lt;/h3&gt;

	&lt;h4&gt;(Turkey? Ham? Both??)&lt;/h4&gt;

	&lt;p&gt;The underlying cause for the failure of so many projects is mismatched expectations. Christmas dinner cannot be a success if you serve glazed ham and your guests view turkey as the essential Christmas dinner ingredient. It doesn&amp;#8217;t matter how delicious and well executed your glazed ham is, it&amp;#8217;s still fundamentally just not turkey. You might win one or two adventurous souls over, but the rest will go home disappointed.&lt;/p&gt;

	&lt;p&gt;Add to the mix the fact that most web design projects are nowhere near as emotive as Christmas dinner (trust me, a ham vs turkey debate will rage much longer than a fixed vs fluid debate in normal human circles) and the problem is compounded. In particular, as technologists, we forget that our ability to precisely imagine the outcome of a project, be it a website, a piece of software, or similar, is much more keenly developed than the average customer of such projects. &lt;/p&gt;

	&lt;p&gt;So what&amp;#8217;s the solution? &lt;strong&gt;Get very clear, from the very beginning, on exactly what the project is about.&lt;/strong&gt; What are you trying to achieve? How will you measure success? Is the presence of turkey a critical success factor?&lt;/p&gt;

	&lt;p&gt;Summarize all this information in some form of document (in PM-speak, it&amp;#8217;s called a Project Initiation Document typically). Ideally, get the people who are the real decision makers to sign their agreement to that summary in their own blood. Well, you get the picture, I suppose actual blood is not strictly necessary, but a bit of gothic music to set the tone can be useful!&lt;/p&gt;

	&lt;h3&gt;Tip 2: Plan at the Right Level of Detail&lt;/h3&gt;

	&lt;p&gt;Hugely detailed and useless Gantt charts are a personal bugbear of mine. For any project, you should plan at the appropriate level of detail (and in an appropriate format) for the project itself. In our Christmas dinner example, it may be perfectly fine to have a list of tasks for the preparation work, but for the intricate interplay of oven availability and cooking times, something more complex is usually due. Having cooked roast dinners for fourteen in a student house where only the top oven and two of the rings on the hob actually worked, I can attest to the need for sequence diagrams in some of these situations!&lt;/p&gt;

	&lt;p&gt;The mistake many small teams make is to end up with a project plan that is really the amalgamation of their individual todo lists. What is needed is a project plan that will:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;reflect reality&lt;/li&gt;
		&lt;li&gt;be easy to update&lt;/li&gt;
		&lt;li&gt;help to track progress (i.e. are we on track or not?)&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p&gt;A good approach is to break your project into stages (each representing something tangible) and then into deliverables (again, something tangible for each milestone, else you&amp;#8217;ll never know if you&amp;#8217;ve hit it or not!). &lt;/p&gt;

	&lt;p&gt;My personal rule of thumb is that the level of granularity needed on most projects is 2-3 days – i.e. we should never be more than two to three days from a definitive milestone which will either be complete or not. The added advantage of this approach is that if find yourself off track, you can only be two to three days off track&amp;#8230; much easier to make up than if you went weeks or even months working hard but not actually delivering what was needed!&lt;/p&gt;

	&lt;p&gt;In our Christmas dinner example, there are a number of critical milestones – a tick list of questions. Do we have all the ingredients? Check. Has the turkey been basted? Check. On the actual day, the sequencing and timing will mean more specific questions: It&amp;#8217;s 12pm. Are the Brussels sprouts cooked to death yet? Check. (Allowing for the extra hour of boiling to go from soft and green to mushy and brown&amp;#8230; Yeuch!) &lt;/p&gt;

	&lt;h3&gt;Tip 3: Actively Manage Risks and Issues&lt;/h3&gt;

	&lt;p&gt;A risk is something that could go wrong. An issue is something that has already gone wrong. Risks and issues are where project management superstars are born. Anyone can manage things when everything is going according to plan; it&amp;#8217;s what you do when Cousin Jim refuses to eat anything but strawberry jam sandwiches that sorts the men from the boys. &lt;/p&gt;

	&lt;p&gt;The key with a Christmas dinner, as with any project, is to have contingency plans for the most likely and most damaging risks. These depend on your own particular situation, but some examples might be:&lt;/p&gt;

 &lt;table class="procon"&gt;
		&lt;tr&gt;
			&lt;th&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;RISK&lt;/span&gt;&lt;/span&gt;&lt;/th&gt;
			&lt;th&gt;&lt;span class="caps"&gt;&lt;span class="caps"&gt;CONTINGENCY&lt;/span&gt; &lt;span class="caps"&gt;PLAN&lt;/span&gt;&lt;/span&gt;&lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Cousin Jim is a picky eater.&lt;/td&gt;
			&lt;td&gt;Have strawberry jam and sliced white bread on hand to placate.&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Prime organic turkey might not be available at Waitrose on Christmas eve.&lt;/td&gt;
			&lt;td&gt;Shop in advance!&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;You live somewhere remote that seems to lose power around Christmas on a disturbingly regular basis.&lt;/td&gt;
			&lt;td&gt;(number of options here depending on how far you want to go&amp;#8230;)&lt;br /&gt;

					Buy a backup generator.&lt;br /&gt;

					Invent a new cooking method using only candles.&lt;br /&gt;

					Stock up on &amp;#8220;Christmas dinner in a tin&amp;#8221;.&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Your mother in law is likely to be annoying.&lt;/td&gt;
			&lt;td&gt;Bottle of sherry at the ready (whether it&amp;#8217;s for you or her, you can decide!).&lt;/td&gt;
		&lt;/tr&gt;
 &lt;/table&gt;

	&lt;p&gt;The point of planning in advance is so that most of your issues don&amp;#8217;t blindside you – you can spring into action with the contingency plan immediately. This leaves you with plenty of ingenuity and ability to cope in reserve for those truly unexpected events. &lt;/p&gt;

	&lt;p&gt;Back in your regular projects, you should have a risk management plan (developed at the beginning of the project and regularly reviewed) as well as an issue list, tracking open, in progress and closed issues. Importantly, your issue list should be separate from any kind of bug list – issues are at a project level, bugs are at a technical level.&lt;/p&gt;

	&lt;h3&gt;Tip 4: Have a Project Board&lt;/h3&gt;

	&lt;p&gt;A project board consists of the overall sponsor of your project (often, but not always, the guy with the cheque book) and typically a business expert and a technical expert to help advise the sponsor. The project board is the entity that is meant to make the big, critical decisions. As a project manager, your role is to prepare a recommendation, but leave the actual decision up to the board. &lt;/p&gt;

	&lt;p&gt;Admittedly this is where our Christmas dinner analogy has to stretch the most, but if you imagine that instead of just cooking for your family you are the caterer preparing a Christmas feast for a company. In this case, you obviously want to please the diners who will be eating the food, but key decisions are likely to be taken by whoever is organizing the event. They, in turn, will involve the boss if there are really big decisions that would affect the project drastically – for instance, having to move it to January, or it exceeding the set budget by a significant amount.&lt;/p&gt;

	&lt;p&gt;Most projects suffer from not having a project board to consult for these major decisions, or from having the wrong people selected. The first ailment is eased by ensuring that you have a functioning project board, with whom you either meet regularly to update on status, or where there is a special process for convening the board if they are needed. The second problem is a little more subtle. Key questions to ask yourself are:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Who is funding this project?&lt;/li&gt;
		&lt;li&gt;Who has the authority to stop the project if it was the right thing to do?&lt;/li&gt;
		&lt;li&gt;Who are the right business and technical advisors?&lt;/li&gt;
		&lt;li&gt;Who are the folks who don&amp;#8217;t look like they are powerful on the org chart, but in fact might scupper this project? (e.g. administrators, tech support, personal assistants&amp;#8230;)&lt;/li&gt;
	&lt;/ul&gt;

	&lt;h3&gt;Tip 5: Finish Unequivocably and Well&lt;/h3&gt;

	&lt;p&gt;No one is ever uncertain as to when Christmas dinner ends. Once the flaming pudding has been consumed and the cheese tray picked at, the end of the dinner is heralded by groaning and everyone collapsing in their chairs. Different households have different rituals, so you might only open your presents after Christmas dinner (unlikely if you have small children!), or you might round off the afternoon watching the Queen&amp;#8217;s speech (in Britland, certainly) or if you live in warmer climes you might round off Christmas dinner with a swim (which was our tradition in Cape Town – after 30 mins of food settling so you didn&amp;#8217;t get cramp, of course!). &lt;/p&gt;

	&lt;p&gt;The problem with projects is that they are one time efforts and so nowhere near as ritualized. Unless you have been incredibly lucky, you&amp;#8217;ve probably worked on a project where you thought you were finished but seemed unable to lose your “zombie customers” – those folks who just didn&amp;#8217;t realise it was over and kept coming back with more and more requests. You might even have fallen prey to this yourself, believing that the website going live was the end of the project and not realising that a number of things still needed to be wrapped up.&lt;/p&gt;

	&lt;p&gt;The essence of this final tip is to inject some of that end-of-Christmas finality ritual into your projects. Find your own ritual for closing down projects – more than just sending the customer the invoice and archiving the files. Consider things like documentation, support structure handover and training to make sure that those zombies are going to the right people (hopefully not you!). &lt;/p&gt;

	&lt;h4&gt;So, to summarise:&lt;/h4&gt;

	&lt;ol&gt;
		&lt;li&gt;Make sure you start your projects well – with an agreed (written) vision of what you&amp;#8217;re trying to achieve.&lt;/li&gt;
		&lt;li&gt;Plan your projects at the right level of detail and in an appropriate format – never be more than a few days away from knowing for sure whether you&amp;#8217;re on track or not.&lt;/li&gt;
		&lt;li&gt;Plan for likely and important risks and make sure you track and resolve those you actually encounter.&lt;/li&gt;
		&lt;li&gt;Institute a project board, made up of the people with the real power over your project.&lt;/li&gt;
		&lt;li&gt;Create rituals for closing projects well – don&amp;#8217;t leave anyone in doubt that the project has been delivered, or of who they should go to for further help.&lt;/li&gt;
	&lt;/ol&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=21V3tE3NE7U:a93focE3BJg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=21V3tE3NE7U:a93focE3BJg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=21V3tE3NE7U:a93focE3BJg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=21V3tE3NE7U:a93focE3BJg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=21V3tE3NE7U:a93focE3BJg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/21V3tE3NE7U" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://blog.geekmanager.co.uk"&gt;Meri Williams&lt;/a&gt; sets our stomachs rumbling with a festive look at making sure our projects stay on track with some simple and effective project management techniques. Most web work is undertaken as some kind of project, so use these tips to make sure you&amp;#8217;re not working late on Christmas Eve.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/what-your-turkey-can-teach-you-about-project-management</feedburner:origLink></entry>
<entry>
		<author>
			<name>Jason Santa Maria</name>
		</author>
		<published>2008-12-15T00:00:11Z</published>
		<updated>2008-12-15T19:13:42Z</updated>
		<title type="html">Making Modular Layout Systems</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/ojgioWHg-yk/making-modular-layout-systems" />
		<id>tag:24ways.org,2008-12-14:7e1577ceca7ea22e28af5c35ee62927a/e679858a80c0f287ea8855869935f46a</id>
		<category term="css" />
		<category term="design" />
		<content type="html">
&lt;p&gt;For all of the advantages the web has with distribution of content, I&amp;#8217;ve always lamented the handiness of the &lt;span class="caps"&gt;WYSIWYG&lt;/span&gt; design tools from the print publishing world. When I set out to redesign &lt;a title="Jason Santa Maria" href="http://jasonsantamaria.com/"&gt;my personal website&lt;/a&gt;, I wanted to have some of the same abilities that those tools have, laying out pages how I saw fit, and that meant a flexible system for dealing with imagery. &lt;/p&gt;

	&lt;p&gt;Building on some of the &lt;span class="caps"&gt;CSS&lt;/span&gt; that &lt;a title="Eric Meyer" href="http://meyerweb.com/"&gt;Eric Meyer&lt;/a&gt; employed a few years back on the &lt;a title="A List Apart" href="http://alistapart.com/"&gt;A List Apart&lt;/a&gt; design, I created a set of classes to use together to achieve the variety I was after. Employing multiple classes isn&amp;#8217;t a new technique, but most examples aren&amp;#8217;t coming at this from strictly editorial and visual perspectives; I wanted to have options to vary my layouts depending on content.&lt;/p&gt;

	&lt;p&gt;If you want to skip ahead, you can &lt;a title="Example" href="http://media.24ways.org/2008/15/layout-eg.html"&gt;view the example&lt;/a&gt; first.&lt;/p&gt;

	&lt;h3&gt;Laying the Foundation&lt;/h3&gt;

	&lt;p&gt;We need to be able to map out our page so that we have predictable canvas, and then create a system of image sizes that work with it. For the sake of this article, let&amp;#8217;s use a simple &lt;a title="Example with grid" href="http://media.24ways.org/2008/15/layout-eg.html?grid"&gt;uniform 7-column grid&lt;/a&gt;, consisting of seven 100px-wide columns and 10px of space between each column, though you can use any measurements you want as long as they remain constant.&lt;/p&gt;

	&lt;p&gt;All of our images will have a width that references the grid column widths (in our example, 100px, 210px, 320px, 430px, 540px, 650px, or 760px), but the height can be as large as needed.&lt;/p&gt;

	&lt;p&gt;Once we know our images will all have one of those widths, we can setup our &lt;span class="caps"&gt;CSS&lt;/span&gt; to deal with the variations in layout. In the most basic form, we&amp;#8217;re going to be dealing with three classes: one each that represent an identifier, a size, and a placement for our elements.&lt;/p&gt;

	&lt;p&gt;This is really a process of abstracting the important qualities of what you would do with a given image in a layout into separate classes, allowing you to quickly customize their appearance by combining the appropriate classes. Rather than trying to serve up a one-size-fits-all approach to styling, we give each class only one or two attributes and rely on the combination of classes to get us there.&lt;/p&gt;

	&lt;h4&gt;Identifier&lt;/h4&gt;

	&lt;p&gt;This specifies what kind of element we have: usually either an image (&lt;code&gt;pic&lt;/code&gt;) or some piece of text (&lt;code&gt;caption&lt;/code&gt;).&lt;/p&gt;

	&lt;h4&gt;Size&lt;/h4&gt;

	&lt;p&gt;Since we know how our grid is constructed and the potential widths of our images, we can knock out a space equal to the width of any number of columns. In our example, that value can be &lt;code&gt;one&lt;/code&gt;, &lt;code&gt;two&lt;/code&gt;, &lt;code&gt;three&lt;/code&gt;, &lt;code&gt;four&lt;/code&gt;, &lt;code&gt;five&lt;/code&gt;, &lt;code&gt;six&lt;/code&gt;, or &lt;code&gt;seven&lt;/code&gt;.&lt;/p&gt;

	&lt;h4&gt;Placement&lt;/h4&gt;

	&lt;p&gt;This tells the element where to go. In our example we can use a class of &lt;code&gt;left&lt;/code&gt; or &lt;code&gt;right&lt;/code&gt;, which sets the appropriate floating rule.&lt;/p&gt;

	&lt;h4&gt;Additions&lt;/h4&gt;

	&lt;p&gt;I created a few additions that be tacked on after the &amp;#8220;placement&amp;#8221; in the class stack: &lt;code&gt;solo&lt;/code&gt;, for a bit more space beneath images without captions, &lt;code&gt;frame&lt;/code&gt; for images that need a border, and &lt;code&gt;inset&lt;/code&gt; for an element that appears inside of a block of text. Outset images are my default, but you could easily switch the default concept to use inset images and create a class of &lt;code&gt;outset&lt;/code&gt; to pull them out of the content columns.&lt;/p&gt;

	&lt;h3&gt;The &lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/h3&gt;

 &lt;ol class="code"&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;/* I D E N T I F I E R */&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.pic p, .caption {&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;    font-size: 11px;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;    line-height: 16px;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;    font-family: Verdana, Arial, sans-serif;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;    color: #666;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;    margin: 4px 0 10px;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;/* P L A C E M E N T */&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.left {float: left; margin-right: 20px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.right {float: right; margin-left: 20px;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;.right.inset {margin: 0 120px 0 20px;} /* img floated right within text */&lt;/code&gt;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;.left.inset {margin-left: 230px;} /* img floated left within text */&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;/* S I Z E */&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.one {width: 100px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.two {width: 210px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.three {width: 320px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.four {width: 430px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.five {width: 540px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.six {width: 650px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.seven {width: 760px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.eight {width: 870px;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;/* A D D I T I O N S */&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.frame {border: 1px solid #999;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.solo img {margin-bottom: 20px;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/modular-layout-systems/1.txt" title="Download the above code as a textfile"&gt;/code/modular-layout-systems/1.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;h4&gt;In Use&lt;/h4&gt;

	&lt;p&gt;You can already see how powerful this approach can be. If you want an image and a caption on the left to stretch over half of the page, you would use:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;pic four left&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;image.jpg&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Caption goes here.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Or, for that same image with a border and no caption:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;image.jpg&amp;quot; class=&amp;quot;pic four left frame solo&amp;quot;/&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;You just tack on the classes that contain the qualities you need. And because we&amp;#8217;ve kept each class so simple, we can apply these same stylings to other elements too:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;p class=&amp;quot;caption two left&amp;quot;&amp;gt;Caption goes here.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;h4&gt;Caveats&lt;/h4&gt;

	&lt;p&gt;Obviously there are some potential semantic hang-ups with these methods. While classes like &lt;code&gt;pic&lt;/code&gt; and &lt;code&gt;caption&lt;/code&gt; stem the tide a bit, others like &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; are tougher to justify. This is something that you have to decide for yourself; I&amp;#8217;m fine with the occasional &lt;code&gt;four&lt;/code&gt; or &lt;code&gt;left&lt;/code&gt; class because I think there&amp;#8217;s a good tradeoff. Just as a fully semantic solution to this problem would likely be imperfect, this solution is imperfect from the other side of the semantic fence. Additionally, &lt;span class="caps"&gt;IE6&lt;/span&gt; doesn&amp;#8217;t understand the chain of classes within a &lt;span class="caps"&gt;CSS&lt;/span&gt; selector (like &lt;code&gt;.right.inset&lt;/code&gt;). If you need to support &lt;span class="caps"&gt;IE6&lt;/span&gt;, you may have to write a few more &lt;span class="caps"&gt;CSS&lt;/span&gt; rules to accommodate any discrepancies.&lt;/p&gt;

	&lt;h4&gt;Opportunities&lt;/h4&gt;

	&lt;p&gt;This is clearly a simple example, but starting with a modular foundation like this leaves the door open for opportunity. We&amp;#8217;ve created a highly flexible and human-readable system for layout manipulation. Obviously, this is something that would need to be tailored to the spacing and sizes of your site, but the systematic approach is very powerful, especially for editorial websites whose articles might have lots of images of varying sizes. It may not get us fully to the flexibility of &lt;span class="caps"&gt;WYSIWYG&lt;/span&gt; print layouts, but methods like this point us in a direction of designs that can adapt to the needs of the content.&lt;/p&gt;

	&lt;p&gt;View the example: &lt;a title="Example without grid" href="http://media.24ways.org/2008/15/layout-eg.html"&gt;without grid&lt;/a&gt; and &lt;a title="Example with grid" href="http://media.24ways.org/2008/15/layout-eg.html?grid"&gt;with grid&lt;/a&gt;.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=ojgioWHg-yk:bustyhkmFLY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=ojgioWHg-yk:bustyhkmFLY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=ojgioWHg-yk:bustyhkmFLY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=ojgioWHg-yk:bustyhkmFLY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=ojgioWHg-yk:bustyhkmFLY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/ojgioWHg-yk" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://jasonsantamaria.com/"&gt;Jason Santa Maria&lt;/a&gt; details his approach to building a modular system for laying out pages with &lt;span class="caps"&gt;CSS&lt;/span&gt;. Devising a method for dealing with the presentational when presentation is all you&amp;#8217;ve got, this can be a handy way to predictably tame content without becoming predictable.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/making-modular-layout-systems</feedburner:origLink></entry>
<entry>
		<author>
			<name>Tim Van Damme</name>
		</author>
		<published>2008-12-14T00:00:22Z</published>
		<updated>2008-12-14T09:18:46Z</updated>
		<title type="html">Rocking Restrictions</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/mHyM_lDWI2k/rocking-restrictions" />
		<id>tag:24ways.org,2008-12-13:7e1577ceca7ea22e28af5c35ee62927a/b737857cb2cf722b41542f4acafd88af</id>
		<category term="productivity" />
		
		<content type="html">
&lt;p&gt;I love &lt;a href="http://madebyelephant.com"&gt;my job&lt;/a&gt;. I &lt;strong&gt;live&lt;/strong&gt; my job. For every project I do, I try to make it look special. I&amp;#8217;ll be honest: I have a fetish for comments like &amp;#8220;I never saw anything like that!&amp;#8221; or, &amp;#8220;I wish I thought of that!&amp;#8221;. I know, I have an ego-problem. (Eleven I&amp;#8217;s already)&lt;/p&gt;

	&lt;p&gt;But sometimes, you run out of inspiration. Happens to everybody, and everybody hates it. &amp;#8220;I&amp;#8217;m the worst designer in the world.&amp;#8221; &amp;#8220;Everything I designed before this was just pure luck!&amp;#8221; No it wasn&amp;#8217;t.&lt;/p&gt;

	&lt;p&gt;Countless articles about finding inspiration have already been written. Great, but they&amp;#8217;re not the magic potion you&amp;#8217;d expect them to be when you need it. Here&amp;#8217;s a list of small tips that can have immediate effect when applying them/using them. Main theme: &lt;strong&gt;Liberate yourself from the designers&amp;#8217; block by restricting yourself.&lt;/strong&gt;&lt;/p&gt;

	&lt;h3&gt;Do&amp;#8217;s&lt;/h3&gt;

	&lt;h4&gt;Grids&lt;/h4&gt;

	&lt;p&gt;If you aren&amp;#8217;t already using grids, you&amp;#8217;re doing something wrong. Not only are they a great help for aligning your design, they also restrict you to certain widths and heights. (For more information about grids, I suggest you read &lt;a href="http://www.markboulton.co.uk/journal/comments/five_simple_steps_to_designing_grid_systems_part_1/"&gt;Mark Boulton&amp;#8217;s series on designing grid systems&lt;/a&gt;. Oh, he&amp;#8217;s also publishing &lt;a href="http://www.fivesimplesteps.co.uk/"&gt;a book&lt;/a&gt; I think.)&lt;/p&gt;

	&lt;p&gt;So what&amp;#8217;s the link between grids and restrictions? Instead of having the option to style a piece of layout with a width of 1 to 960 pixels, you have to choose from values like 60 pixels, 140, 220, 300, &amp;#8230;&lt;/p&gt;

	&lt;h4&gt;Start small&lt;/h4&gt;

	&lt;p&gt;Having a hard time finding a style for the layout, why don&amp;#8217;t you start with one small object? No, not &lt;strong&gt;that&lt;/strong&gt; small object, I meant a piece of a form, or a link, or try styling your headers (&lt;code&gt;h1&lt;/code&gt; &amp;#8211; &lt;code&gt;h6&lt;/code&gt;).&lt;/p&gt;

	&lt;p&gt;Let&amp;#8217;s take a submit button of a form: it&amp;#8217;s small, but needs much attention. People will click it. People will hover it. Maybe sometimes it&amp;#8217;s disabled? Also: a button needs to look like a button, so typically it requires more styling then a regular link. Once you&amp;#8217;ve got the button, move on, following the button&amp;#8217;s style.&lt;/p&gt;

	&lt;h4&gt;Color palettes&lt;/h4&gt;

	&lt;p&gt;There are lots of resources on the web for finding inspiration for color palettes. Some of the most famous are &lt;a href="http://www.colourlovers.com/"&gt;&lt;span class="caps"&gt;COLOUR&lt;/span&gt;lovers&lt;/a&gt;, &lt;a href="http://blog.wearpalettes.com/"&gt;wear palettes&lt;/a&gt; and &lt;a href="http://kuler.adobe.com/"&gt;Adobe&amp;#8217;s Kuler&lt;/a&gt;. Browse through them (or &lt;a href="http://24ways.org/2006/photographic-palettes"&gt;create your own from a picture&lt;/a&gt;), pick a color palette you like and which works with the subject you&amp;#8217;re handling, and stick with it. 4-5 colors, maybe with some &lt;a href="http://24ways.org/2006/photographic-palettes"&gt;tonal variations&lt;/a&gt;, but that&amp;#8217;s it.&lt;/p&gt;

	&lt;h4&gt;Fonts&lt;/h4&gt;

	&lt;p&gt;There aren&amp;#8217;t many fonts available for the web (Richard Rutter has &lt;a href="http://24ways.org/2007/increase-your-font-stacks-with-font-matrix"&gt;a great article&lt;/a&gt; on this subject), but you&amp;#8217;d be surprised how long they go. A simple &lt;code&gt;text-transform: uppercase;&lt;/code&gt; or &lt;code&gt;font-style: italic;&lt;/code&gt; can change a dull looking font into something entirely fresh.&lt;/p&gt;

	&lt;p&gt;Play around with the fonts you want to use and the variations you&amp;#8217;ll be using, and make a list. Pick five combinations of fonts and their variations, and stick with them throughout the layout.&lt;/p&gt;

	&lt;h4&gt;Single-task&lt;/h4&gt;

	&lt;p&gt;Most of us use multiple monitors. They&amp;#8217;re great to increase productivity, but make it harder to focus on a single task. Here&amp;#8217;s what you do: try using only your smallest monitor. Maybe it&amp;#8217;s the one from your laptop, maybe it&amp;#8217;s an old 1024×768 you found in the attic. Having Photoshop (or Fireworks or&amp;#8230;) taking over your entire workspace blocks out all the other distractions on your screen, and works quite liberating.&lt;/p&gt;

	&lt;h4&gt;Mute everything&amp;#8230;&lt;/h4&gt;

	&lt;p&gt;&amp;#8230;but not entirely. I noticed I was way more focused when I set NetNewsWire to refresh it&amp;#8217;s feeds only once every two hours. After two hours, I need a break anyway. Turning off Twitterrific was a mistake, as it&amp;#8217;s my window to the world, and it&amp;#8217;s the place where the people I like to call colleagues live. You can&amp;#8217;t exactly ask them to bring you a cup of coffee when they go to the vending machine, but they do keep you fresh, and it stops you from going human-shy. Instead I changed the settings to not play a notification sound when new Tweets arrive so it doesn&amp;#8217;t disturb me when I&amp;#8217;m &lt;a href="http://danbenjamin.com/articles/2008/03/offices-and-the-zone"&gt;zoning&lt;/a&gt;.&lt;/p&gt;

	&lt;h3&gt;Don&amp;#8217;ts&lt;/h3&gt;

	&lt;h4&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt; galleries&lt;/h4&gt;

	&lt;p&gt;&lt;strong&gt;Don&amp;#8217;t&lt;/strong&gt; start browsing all kinds of &lt;span class="caps"&gt;CSS&lt;/span&gt; galleries. Either you&amp;#8217;ll feel bad, or you just start using elements in a way you can&amp;#8217;t call &amp;#8220;inspired&amp;#8221; anymore. Instead gather your own collection of inspiration. Example: I use &lt;a href="http://www.realmacsoftware.com/littlesnapper/"&gt;LittleSnapper&lt;/a&gt; in which I dump everything I find inspiring. This goes from a smart layout idea, to a failed picture someone posted on Flickr. &lt;strong&gt;Everything is inspiring.&lt;/strong&gt;&lt;/p&gt;

	&lt;h4&gt;Panicking&lt;/h4&gt;

	&lt;p&gt;&lt;strong&gt;Don&amp;#8217;t&lt;/strong&gt; panic. It&amp;#8217;s the worst thing you could do. Instead, get away from the computer, and go to bed early. A good night of sleep combined with a hot/cold shower can give you a totally new perspective on a design. Got a deadline by tomorrow? Well, you should&amp;#8217;ve started earlier. Got a good excuse to start on this design this late? Tell your client it was either that or a bad design.&lt;/p&gt;

	&lt;h4&gt;120-hour work-week&lt;/h4&gt;

	&lt;p&gt;&lt;strong&gt;Don&amp;#8217;t&lt;/strong&gt; work all day long, including evenings and early mornings. &lt;a href="http://elliotjaystocks.com/blog/archive/2008/write-off-that-first-hour/"&gt;Write off that first hour&lt;/a&gt;, you don&amp;#8217;t really think you&amp;#8217;ll get anything productive done before 9AM?! I don&amp;#8217;t even think you should work on one and the same design all day long. If you&amp;#8217;re stuck, try working in blocks of 1 or 2 hours on a certain design. Mixing projects isn&amp;#8217;t for everyone, but it might just do the trick for you.&lt;/p&gt;

	&lt;h3&gt;Summary&lt;/h3&gt;

	&lt;ul&gt;
		&lt;li&gt;Use grids, not only for layout purposes.&lt;/li&gt;
		&lt;li&gt;Pick a specific element to start with.&lt;/li&gt;
		&lt;li&gt;Use a colour palette.&lt;/li&gt;
		&lt;li&gt;Limit the amount of fonts and variations you&amp;#8217;ll use.&lt;/li&gt;
		&lt;li&gt;Search for the smallest monitor around, and restrict yourself to that one.&lt;/li&gt;
		&lt;li&gt;Reduce the amount of noise.&lt;/li&gt;
		&lt;li&gt;Don&amp;#8217;t start looking on the internet for inspiration. Build your own little &lt;em&gt;inspirarchive&lt;/em&gt;.&lt;/li&gt;
		&lt;li&gt;Work in blocks.&lt;/li&gt;
	&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=mHyM_lDWI2k:GmyhrcB5Y2U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=mHyM_lDWI2k:GmyhrcB5Y2U:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=mHyM_lDWI2k:GmyhrcB5Y2U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=mHyM_lDWI2k:GmyhrcB5Y2U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=mHyM_lDWI2k:GmyhrcB5Y2U:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/mHyM_lDWI2k" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://timvandamme.com/"&gt;Tim Van Damme&lt;/a&gt; tackles the thorny issue of overcoming designer&amp;#8217;s block with a handy list of do&amp;#8217;s and don&amp;#8217;ts to help you get back on track. Creative block hits nearly all of us at some point, and so having some simple methods of breaking it can be invaluable.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/rocking-restrictions</feedburner:origLink></entry>
<entry>
		<author>
			<name>Kevin Yank</name>
		</author>
		<published>2008-12-13T00:00:13Z</published>
		<updated>2008-12-13T00:00:13Z</updated>
		<title type="html">The First Tool You Reach For</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/DsV5evpw1HE/the-first-tool-you-reach-for" />
		<id>tag:24ways.org,2008-12-12:7e1577ceca7ea22e28af5c35ee62927a/565b087d035d06f2a0b48d57ff70650e</id>
		<category term="css" />
		
		<content type="html">
&lt;p&gt;Microsoft recently &lt;a href="http://blogs.msdn.com/ie/archive/2008/11/19/ie8-what-s-after-beta-2.aspx"&gt;announced&lt;/a&gt; that Internet Explorer 8 will be released in the first half of 2009. Compared to the standards support of other major browsers, IE8 will not be especially great, but it &lt;em&gt;will&lt;/em&gt; finally catch up with the state of the art in one specific area: support for &lt;span class="caps"&gt;CSS&lt;/span&gt; tables. This milestone has the potential to trigger an important change in the way you approach web design.&lt;/p&gt;

	&lt;p&gt;To show you just how big a difference &lt;span class="caps"&gt;CSS&lt;/span&gt; tables can make, think about how you might code a fluid, three-column layout from scratch. Just to make your life more difficult, give it one fixed-width column, with a background colour that differs from the rest of the page. Ready? Go!&lt;/p&gt;

	&lt;p&gt;Okay, since you&amp;#8217;re the sort of discerning web designer who reads 24ways, I&amp;#8217;m going to assume you at least &lt;em&gt;considered&lt;/em&gt; doing this without using &lt;span class="caps"&gt;HTML&lt;/span&gt; tables for the layout. If you&amp;#8217;re especially hardcore, I imagine you began thinking of &lt;span class="caps"&gt;CSS&lt;/span&gt; floats, negative margins, and &lt;a href="http://www.alistapart.com/articles/fauxcolumns/"&gt;faux columns&lt;/a&gt;. If you did, colour me impressed!&lt;/p&gt;

	&lt;p&gt;Now admit it: you probably also gave an inward sigh about the time it would take to figure out the math on the negative margin overlaps, check for dropped floats in Internet Explorer and generally wrestle each of the major browsers into giving you what you want. If after all that you simply &lt;a href="http://giveupandusetables.com/"&gt;gave up and used &lt;span class="caps"&gt;HTML&lt;/span&gt; tables&lt;/a&gt;, I can&amp;#8217;t say I blame you.&lt;/p&gt;

	&lt;p&gt;There are plenty of professional web designers out there who still choose to use &lt;span class="caps"&gt;HTML&lt;/span&gt; tables as their main layout tool. Sure, they may know that users with screen readers get confused by inappropriate use of tables, but they have a job to do, and they want tools that will make that job easy, not difficult.&lt;/p&gt;

	&lt;p&gt;Now let me show you how to do it with &lt;span class="caps"&gt;CSS&lt;/span&gt; tables. First, we have a &lt;code&gt;div&lt;/code&gt; element for each of our columns, and we wrap them all in another two &lt;code&gt;div&lt;/code&gt;s:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;menu&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;⋮&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;content&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;⋮&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;sidebar&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;⋮&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/the-first-tool-you-reach-for/1.txt" title="Download the above code as a textfile"&gt;/code/the-first-tool-you-reach-for/1.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Don&amp;#8217;t sweat the “&lt;code&gt;div&lt;/code&gt; clutter” in this code. Unlike tables, &lt;code&gt;div&lt;/code&gt;s have no semantic meaning, and can therefore be used liberally (within reason) to provide hooks for the styles you want to apply to your page.&lt;/p&gt;

	&lt;p&gt;Using &lt;span class="caps"&gt;CSS&lt;/span&gt;, we can set the outer &lt;code&gt;div&lt;/code&gt; to display as a table with collapsed borders (i.e. adjacent cells share a border) and a fixed layout (i.e. cell widths unaffected by their contents):&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;.container {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;display: table;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;border-collapse: collapse;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;table-layout: fixed;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/the-first-tool-you-reach-for/2.txt" title="Download the above code as a textfile"&gt;/code/the-first-tool-you-reach-for/2.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;With another two rules, we set the middle &lt;code&gt;div&lt;/code&gt; to display as a table row, and each of the inner &lt;code&gt;div&lt;/code&gt;s to display as table cells:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;.container &amp;gt; div {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;display: table-row;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.container &amp;gt; div &amp;gt; div {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;display: table-cell;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/the-first-tool-you-reach-for/3.txt" title="Download the above code as a textfile"&gt;/code/the-first-tool-you-reach-for/3.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Finally, we can set the widths of the cells (and of the table itself) directly:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;.container {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 100%;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#menu {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 200px;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#content {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: auto;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#sidebar {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 25%;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/the-first-tool-you-reach-for/4.txt" title="Download the above code as a textfile"&gt;/code/the-first-tool-you-reach-for/4.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;And, just like that, we have a rock solid three-column layout, ready to be styled to your own taste, like in &lt;a href="http://media.24ways.org/2008/13/24ways-example.html"&gt;this example&lt;/a&gt;:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="Screenshot showing a three column layout with header and footer." src="http://media.24ways.org/2008/13/24ways-3col.png" /&gt;&lt;/p&gt;

	&lt;p&gt;This example will render perfectly in reasonably up-to-date versions of Firefox, Safari and Opera, as well as the current beta release of Internet Explorer 8.&lt;/p&gt;

	&lt;p&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt; tables aren&amp;#8217;t only useful for multi-column page layout; they can come in handy in most any situation that calls for elements to be displayed side-by-side on the page. Consider this simple login form layout:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="Screenshot showing a common login form with username and password fields" src="http://media.24ways.org/2008/13/24ways-form.png" /&gt;&lt;/p&gt;

	&lt;p&gt;The incantation required to achieve this layout using &lt;span class="caps"&gt;CSS&lt;/span&gt; floats may be old hat to you by now, but try to teach it to a beginner, and watch his eyes widen in horror at the hoops you have to jump through (not to mention the assumptions you have to build into your design about the length of the form labels).&lt;/p&gt;

	&lt;p&gt;Here&amp;#8217;s how to do it with &lt;span class="caps"&gt;CSS&lt;/span&gt; tables:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;form action=&amp;quot;/login&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;label for=&amp;quot;username&amp;quot;&amp;gt;Username:&amp;lt;/label&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;input&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;username&amp;quot; id=&amp;quot;username&amp;quot;/&amp;gt;&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;label for=&amp;quot;userpass&amp;quot;&amp;gt;Password:&amp;lt;/label&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;input&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;userpass&amp;quot; id=&amp;quot;userpass&amp;quot;/&amp;gt;&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;submit&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;label for=&amp;quot;login&amp;quot;&amp;gt;&amp;lt;/label&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;input&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; name=&amp;quot;login&amp;quot; id=&amp;quot;login&amp;quot; value=&amp;quot;Login&amp;quot;/&amp;gt;&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/the-first-tool-you-reach-for/5.txt" title="Download the above code as a textfile"&gt;/code/the-first-tool-you-reach-for/5.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;This time, we&amp;#8217;re using a mixture of &lt;code&gt;div&lt;/code&gt;s and &lt;code&gt;span&lt;/code&gt;s as semantically transparent styling hooks. Let&amp;#8217;s look at the &lt;span class="caps"&gt;CSS&lt;/span&gt; code.&lt;/p&gt;

	&lt;p&gt;First, we set up the outer &lt;code&gt;div&lt;/code&gt; to display as a table, the inner &lt;code&gt;div&lt;/code&gt;s to display as table rows, and the &lt;code&gt;label&lt;/code&gt;s and &lt;code&gt;span&lt;/code&gt;s as table cells (with right-aligned text):&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;form &amp;gt; div {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;display: table;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;form &amp;gt; div &amp;gt; div {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;display: table-row;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;form label,&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;form span {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;display: table-cell;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;text-align: right;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/the-first-tool-you-reach-for/6.txt" title="Download the above code as a textfile"&gt;/code/the-first-tool-you-reach-for/6.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;We want the first column of the table to be wide enough to accommodate our labels, but no wider. With &lt;span class="caps"&gt;CSS&lt;/span&gt; float techniques, we had to guess at what that width was likely to be, and adjust it whenever we changed our form labels. With &lt;span class="caps"&gt;CSS&lt;/span&gt; tables, we can simply set the &lt;code&gt;width&lt;/code&gt; of the first column to something very small (&lt;code&gt;1em&lt;/code&gt;), and then use the &lt;code&gt;white-space&lt;/code&gt; property to force the column to the required width:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;form label {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;white-space: nowrap;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 1em;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/the-first-tool-you-reach-for/7.txt" title="Download the above code as a textfile"&gt;/code/the-first-tool-you-reach-for/7.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;To polish off the layout, we&amp;#8217;ll make our text and password fields occupy the full width of the table cells that contain them:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;input[type=text],&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;input[type=password] {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 100%;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/the-first-tool-you-reach-for/8.txt" title="Download the above code as a textfile"&gt;/code/the-first-tool-you-reach-for/8.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;The rest is margins, padding and borders to get the desired look. Check out the &lt;a href="http://media.24ways.org/2008/13/24ways-example2.html"&gt;finished example&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;As the first tool you reach for when approaching any layout task, &lt;span class="caps"&gt;CSS&lt;/span&gt; tables make a lot more sense to your average designer than the cryptic incantations called for by &lt;span class="caps"&gt;CSS&lt;/span&gt; floats. When IE8 is released and all major browsers support &lt;span class="caps"&gt;CSS&lt;/span&gt; tables, we can begin to gradually deploy &lt;span class="caps"&gt;CSS&lt;/span&gt; table-based layouts on sites that are more and more mainstream.&lt;/p&gt;

	&lt;p&gt;In our new book, &lt;a href="http://www.sitepoint.com/books/csswrong1/"&gt;&lt;cite&gt;Everything You Know About &lt;span class="caps"&gt;CSS&lt;/span&gt; Is Wrong!&lt;/cite&gt;&lt;/a&gt;, Rachel Andrew and I explore in much greater detail how &lt;span class="caps"&gt;CSS&lt;/span&gt; tables work as a page layout tool in the real world. &lt;span class="caps"&gt;CSS&lt;/span&gt; tables have their quirks just like floats do, but they don&amp;#8217;t tend to affect common layout tasks, and the workarounds tend to be less fiddly too. Check it out, and get ready for the next big step forward in web design with &lt;span class="caps"&gt;CSS&lt;/span&gt;.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=DsV5evpw1HE:mrMK9A8x8aM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=DsV5evpw1HE:mrMK9A8x8aM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=DsV5evpw1HE:mrMK9A8x8aM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=DsV5evpw1HE:mrMK9A8x8aM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=DsV5evpw1HE:mrMK9A8x8aM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/DsV5evpw1HE" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://www.sitepoint.com/"&gt;Kevin Yank&lt;/a&gt; gets down and dirty with &lt;span class="caps"&gt;CSS&lt;/span&gt; tables, a technique that offers all the layout properties we loved from long forsaken &lt;span class="caps"&gt;HTML&lt;/span&gt; tables with the clear advantages of modern &lt;span class="caps"&gt;CSS&lt;/span&gt; based design. Remember, just because it looks like a table and flows like a table, doesn&amp;#8217;t mean it has to be bad.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/the-first-tool-you-reach-for</feedburner:origLink></entry>
<entry>
		<author>
			<name>Kimberly Blessing</name>
		</author>
		<published>2008-12-12T00:00:07Z</published>
		<updated>2008-12-12T00:00:07Z</updated>
		<title type="html">Checking Out: Progress Meters</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/dlxc5SggFkQ/checking-out-progress-meters" />
		<id>tag:24ways.org,2008-12-11:7e1577ceca7ea22e28af5c35ee62927a/6d3776697c43c0354978eaefe7fdd4cd</id>
		<category term="accessibility" />
		<category term="markup" />
		<content type="html">
&lt;p&gt;It&amp;#8217;s the holiday season, so you know what that means: online shopping! When I started developing Web sites back in the 90s, many of my first clients were small local shops wanting to sell their goods online, so I developed many a checkout system. And because of slow dial-up speeds back then, informing the user about where they were in the checkout process was pretty important.&lt;/p&gt;

	&lt;p&gt;Even though we&amp;#8217;re (mostly) beyond the dial-up days, informing users about where they are in a flow is still important. In usability tests at the companies I&amp;#8217;ve worked at, I&amp;#8217;ve seen time and time again how not adequately informing the user about their state can cause real frustration. This is especially true for two sets of users: mobile users and users of assistive devices, in particular, screen readers.&lt;/p&gt;

	&lt;p&gt;The progress meter is a very common design solution used to indicate to the user&amp;#8217;s state within a flow. On the design side, much effort may go in to crafting a solution that is as visually informative as possible. On the development side, however, solutions range widely. I&amp;#8217;ve checked out the checkouts at a number of sites and here&amp;#8217;s what I&amp;#8217;ve found when it comes to progress meters: they&amp;#8217;re sometimes inaccessible and often confusing or unhelpful &amp;#8212; all because of the way in which they&amp;#8217;re coded. For those who use assistive devices or text-only browsers, there must be a better way to code the progress meter &amp;#8212; and there is.&lt;/p&gt;

	&lt;p&gt;(Note: All code samples are from live sites but have been tweaked to hide the culprits&amp;#8217; identities.)&lt;/p&gt;

	&lt;h3&gt;How not to make progress&lt;/h3&gt;

	&lt;p&gt;A number of sites assemble their progress meters using non- or semi-semantic markup and images with no alternate text. On text-only browsers (like my mobile phone) and to screen readers, this looks and reads like chunks of content with no context given.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;progress&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;icon_progress_1a.gif&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;em&amp;gt;Shipping information&amp;lt;/em&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;icon_progress_arrow.gif&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;icon_progress_2a.gif&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;em&amp;gt;Payment information&amp;lt;/em&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;icon_progress_arrow.gif&amp;quot; alt=&amp;quot;&amp;quot; class=&amp;quot;progarrow&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;icon_progress_3b.gif&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;strong&amp;gt;Place your order&amp;lt;/strong&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;In the above example, the third state, &amp;#8220;Place your order&amp;#8221;, is the current state. But a screen reader may not know that, and my cell phone only displays &lt;code&gt;&amp;quot;Shipping informationPayment informationPlace your order&amp;quot;&lt;/code&gt;. Not good.&lt;/p&gt;

	&lt;h3&gt;Is this progress?&lt;/h3&gt;

	&lt;p&gt;Other sites present the entire progress meter as a graphic, like the following:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/12/sample_on.gif" alt="A sample progress meter for a three-step checkout flow, with the second step in active state" width="382" height="58" /&gt;&lt;/p&gt;

	&lt;p&gt;Now, I have no problem with using a graphic to render a very stylish progress meter (my sample above is probably not the most stylish example, of course, but you understand my point). What becomes important in this case is the use of appropriate alternate text to describe the image. Disappointingly, sites today have a wide range of solutions, including using no alternate text. Check out these code samples which call progress meter images.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;checkout_step2.gif&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;I think we can all agree that the above is bad, unless you really don&amp;#8217;t care whether or not users know where they are in a flow.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;checkout_step2.gif&amp;quot; alt=&amp;quot;Shipping information - Payment information - Place your order&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;The alt text in the example above just copies all of the text found in the graphic, but it doesn&amp;#8217;t represent the status at all. So for every page in the checkout, the user sees or hears the same text. Sure, by the second or third page in the flow, the user has figured out what&amp;#8217;s going on, but she or he had to think about it. I don&amp;#8217;t think that&amp;#8217;s good.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;img src=&amp;quot;checkout_step2.gif&amp;quot; alt=&amp;quot;Checkout: Payment information&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;The above probably has the best alternate text out of these examples, because the user at least understands that they&amp;#8217;re in the Checkout process, on the Place your order page. But going through the flow with alt text like this, the user doesn&amp;#8217;t know how many steps are in the flow.&lt;/p&gt;

	&lt;h3&gt;Semantic progress&lt;/h3&gt;

	&lt;p&gt;Of course, there are some sites that use an ordered list when marking up the progress meter. Hooray! Unfortunately, no text-only browser or screen reader would be able to describe the user&amp;#8217;s current state given this markup.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;ol class=&amp;quot;progressmeter&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;one current&amp;quot;&amp;gt;shipping information&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;two&amp;quot;&amp;gt;payment information&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;three&amp;quot;&amp;gt;place your order&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/ol&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Without &lt;span class="caps"&gt;CSS&lt;/span&gt; enabled, the above is rendered as follows:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/12/no-css-ol.gif" alt="A sample progress meter for a three-step checkout flow, with no clear active state indicated" width="326" height="91" /&gt;&lt;/p&gt;

	&lt;h3&gt;Progress at last&lt;/h3&gt;

	&lt;p&gt;We all know that semantic markup makes for the best foundation, so we&amp;#8217;ll start with the markup found above. In order to make the state information accessible, let&amp;#8217;s add some additional text in paragraph and span elements.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;progressmeter&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;p&amp;gt;There are three steps in this checkout process.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;one&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Enter your&amp;lt;/span&amp;gt; shipping information&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;two&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Enter your&amp;lt;/span&amp;gt; payment information&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;three&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Review details and&amp;lt;/span&amp;gt; place your order&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/ol&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Add on some simple &lt;span class="caps"&gt;CSS&lt;/span&gt; to hide the paragraph and spans, and arrange the list items on a single line with a background image to represent the large number, and this is what you&amp;#8217;ll get:&lt;/p&gt;

 &lt;div class="progressmeter"&gt;
	&lt;p&gt;There are three steps in this checkout process.&lt;/p&gt;
	&lt;ol&gt;
		&lt;li class="one"&gt;&lt;span&gt;Enter your&lt;/span&gt; shipping information&lt;/li&gt;
		&lt;li class="two"&gt;&lt;span&gt;Enter your&lt;/span&gt; payment information&lt;/li&gt;
		&lt;li class="three"&gt;&lt;span&gt;Review details and&lt;/span&gt; place your order&lt;/li&gt;
	&lt;/ol&gt;
 &lt;/div&gt;

	&lt;p&gt;To display and describe a state as active, add the class &amp;#8220;current&amp;#8221; to one of the list items. Then change the hidden content such that it better describes the state to the user.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;progressmeter&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;p&amp;gt;There are three steps in this checkout process.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;one current&amp;quot;&amp;gt;&amp;lt;span&amp;gt;You are currently entering your&amp;lt;/span&amp;gt; shipping information&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;two&amp;quot;&amp;gt;&amp;lt;span&amp;gt;In the next step, you will enter your&amp;lt;/span&amp;gt; payment information&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;three&amp;quot;&amp;gt;&amp;lt;span&amp;gt;In the last step, you will review the details and&amp;lt;/span&amp;gt; place your order&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/ol&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/checking-out-progress-meters/7.txt" title="Download the above code as a textfile"&gt;/code/checking-out-progress-meters/7.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;The end result is an attractive progress meter that gives much greater semantic and contextual information.&lt;/p&gt;

 &lt;div class="progressmeter"&gt;
	&lt;p&gt;There are three steps in this checkout process.&lt;/p&gt;
	&lt;ol&gt;
		&lt;li class="one current"&gt;&lt;span&gt;You are currently entering your&lt;/span&gt; shipping information&lt;/li&gt;
		&lt;li class="two"&gt;&lt;span&gt;In the next step, you will enter your&lt;/span&gt; payment information&lt;/li&gt;
		&lt;li class="three"&gt;&lt;span&gt;In the last step, you will review the details and&lt;/span&gt; place your order&lt;/li&gt;
	&lt;/ol&gt;
 &lt;/div&gt;

	&lt;p&gt;For example, the above example renders in a text-only browser as follows:&lt;/p&gt;

 &lt;blockquote&gt;
	&lt;p&gt;There are three steps in this checkout process.&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;You are currently entering your shipping information&lt;/li&gt;
		&lt;li&gt;In the next step, you will enter your payment information&lt;/li&gt;
		&lt;li&gt;In the last step, you will review the details and place your order&lt;/li&gt;
	&lt;/ol&gt;
 &lt;/blockquote&gt;

	&lt;p&gt;And the screen reader I use for testing announces the following:&lt;/p&gt;

 &lt;blockquote&gt;
	&lt;p&gt;There are three steps in this checkout process. List of three items. You are currently entering your shipping information. In the next step, you will enter your payment information. In the last step, you will review the details and place your order. List end.&lt;/p&gt;
 &lt;/blockquote&gt;

	&lt;p&gt;Here&amp;#8217;s a &lt;a href="http://media.24ways.org/2008/12/progress_meter.html"&gt;sample code page&lt;/a&gt; that summarises this approach.&lt;/p&gt;

	&lt;p&gt;Happy frustration-free online shopping with this improved progress meter!&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=dlxc5SggFkQ:hIX9QqS1e4Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=dlxc5SggFkQ:hIX9QqS1e4Y:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=dlxc5SggFkQ:hIX9QqS1e4Y:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=dlxc5SggFkQ:hIX9QqS1e4Y:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=dlxc5SggFkQ:hIX9QqS1e4Y:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/dlxc5SggFkQ" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://www.kimberlyblessing.com/"&gt;Kimberly Blessing&lt;/a&gt; takes a look at some different methods for marking up the progress meters commonly found on site checkouts. Particularly looking with respect to semantics and accessibility, Kimberly presents a neat solution of her own. Check it out. (sorry!)&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/checking-out-progress-meters</feedburner:origLink></entry>
<entry>
		<author>
			<name>Richard Rutter</name>
		</author>
		<published>2008-12-11T00:00:21Z</published>
		<updated>2008-12-11T00:02:55Z</updated>
		<title type="html">Easier Page States for Wireframes</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/tGrU-lrGUhQ/easier-page-states-for-wireframes" />
		<id>tag:24ways.org,2008-12-10:7e1577ceca7ea22e28af5c35ee62927a/f7ef00bd34b69e90f59ba38869998a59</id>
		<category term="information-architecture" />
		<category term="javascript" />
		<content type="html">
&lt;p&gt;When designing wireframes for web sites and web apps, it is often overlooked that the same &amp;#8216;page&amp;#8217; can look wildly different depending on its context. A logged-in page will look different from a logged-out page; an administrator&amp;#8217;s view may have different buttons than a regular user&amp;#8217;s view; a power user&amp;#8217;s profile will be more extensive than a new user&amp;#8217;s.&lt;/p&gt;

	&lt;p&gt;These different page states need designing at some point, especially if the wireframes are to form a useful communication medium between designer and developer. Documenting the different permutations can be a time consuming exercise involving either multiple pages in one&amp;#8217;s preferred box-and-arrow software, or a fully fledged drawing containing all the possible combinations annotated accordingly.&lt;/p&gt;

	&lt;h3&gt;Enter interactive wireframes and Polypage&lt;/h3&gt;

	&lt;p&gt;Interactive wireframes built in &lt;span class="caps"&gt;HTML&lt;/span&gt; are a great design and communication tool. They provide a clickable prototype, running in the browser as would the final site. As such they give a great feel for how the site will be to use. Once you add in the possibilities of JavaScript and a library such as &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;, they become even more flexible and powerful.&lt;/p&gt;

	&lt;p&gt;Polypage is a jQuery plugin which makes it really easy to design multiple page states in &lt;span class="caps"&gt;HTML&lt;/span&gt; wireframes. There&amp;#8217;s no JavaScript knowledge required (other than cutting and pasting in a few lines). The page views are created by simply writing all the alternatives into your &lt;span class="caps"&gt;HTML&lt;/span&gt; page and adding special class names to apply state and conditional view logic to the various options. &lt;/p&gt;

	&lt;p&gt;When the page is loaded Polypage automatically detects the page states defined by the class names and creates a control bar enabling the user to toggle page states with the click of a mouse or the clack of a keyboard.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/11/images/polypage_options_bar.jpg" title="Screenshot of the Polypage control bar showing toggles for logged-in  state, group member, etc" alt="Screenshot of the Polypage control bar showing toggles for logged-in  state, group member, etc" /&gt;&lt;/p&gt;

	&lt;p&gt;Using cookies by way of the jQuery &lt;a href="http://plugins.jquery.com/project/Cookie"&gt;cookie plugin&lt;/a&gt;, Polypage retains the view state throughout your prototype. This means you could navigate through your wireframes as if you were logged out; as if you were logged in as an administrator; with notes on or off; or with any other view or state you might require. The possibilities are entirely up to you.&lt;/p&gt;

	&lt;h3&gt;How does it work?&lt;/h3&gt;

	&lt;p&gt;Firstly you need to link to jQuery, the jQuery cookie plugin and to Polypage. Something like this:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;script src=&amp;quot;javascripts/jquery-1.2.6.min.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;script src=&amp;quot;javascripts/cookie.jquery.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;script src=&amp;quot;javascripts/polypage.jquery.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/easier-page-states-for-wireframes/1.txt" title="Download the above code as a textfile"&gt;/code/easier-page-states-for-wireframes/1.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Then you need to initialise Polypage on page load using something along these lines:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;$(document).ready(function() {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;$.polypage.init();&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;});&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/easier-page-states-for-wireframes/2.txt" title="Download the above code as a textfile"&gt;/code/easier-page-states-for-wireframes/2.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Next you need to define the areas of your wireframe which are particular to a given state or view. Do this by applying classes beginning with &lt;code&gt;pp_&lt;/code&gt;. Polypage will ignore all other classes in the document.&lt;/p&gt;

	&lt;p&gt;The &lt;code&gt;pp_&lt;/code&gt; prefix should be followed by a state name. This can be any text string you like, bearing in mind it will appear in the control bar. Typical page states might include &amp;#8216;logged_in&amp;#8217;, &amp;#8216;administrator&amp;#8217; or &amp;#8216;group_owner&amp;#8217;. A complete class name would therefore look something like &lt;code&gt;pp_logged_in&lt;/code&gt;.&lt;/p&gt;

	&lt;h3&gt;Examples&lt;/h3&gt;

	&lt;p&gt;If a user is logged in, you might want to specify an option for him or her to sign out. Using Polypage, this could be put in the wireframe as follows:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;a href=&amp;quot;logout&amp;quot; class=&amp;quot;pp_logged_in&amp;quot;&amp;gt; Sign out &amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Polypage will identify the &lt;code&gt;pp_logged_in&lt;/code&gt; class on the link and hide it (as the &amp;#8216;Sign out&amp;#8217; link should only be shown when the page is in the &amp;#8216;logged in&amp;#8217; view). Polypage will then automatically write a &amp;#8216;logged in&amp;#8217; toggle to the control bar, enabling you to show or hide the &amp;#8216;Sign out&amp;#8217; link by toggling the &amp;#8216;logged in&amp;#8217; view. The same will apply to all content marked with a &lt;code&gt;pp_logged_in&lt;/code&gt; class.&lt;/p&gt;

	&lt;p&gt;States can also be negated by adding a &lt;code&gt;not&lt;/code&gt; keyword to the class name. For example you might want to provide a log in link for users who are &lt;strong&gt;not&lt;/strong&gt; signed in. Using Polypage, you would insert the &lt;code&gt;not&lt;/code&gt; keyword after the &lt;code&gt;pp&lt;/code&gt; prefix as follows:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;a href=&amp;quot;login&amp;quot; class=&amp;quot;pp_not_logged_in&amp;quot;&amp;gt; Login &amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Again Polypage identifies the &lt;code&gt;pp&lt;/code&gt; prefix but this time sees that the &amp;#8216;Login&amp;#8217; link should not be shown when the &amp;#8216;logged in&amp;#8217; state is selected.&lt;/p&gt;

	&lt;p&gt;States can also be joined together to add some basic logic to pages. The syntax follows natural language and uses the &lt;code&gt;or&lt;/code&gt; and &lt;code&gt;and&lt;/code&gt; keywords in addition to the afore-mentioned &lt;code&gt;not&lt;/code&gt;. Some examples would be pp_logged_in_and_admin, pp_admin_or_group_owner and pp_logged_in_and_not_admin.&lt;/p&gt;

	&lt;p&gt;Finally, you can set default states for a page by passing an array to the polypage.init() function like this:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;$.polypage.init(['logged_in', 'admin']);&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;You can see a &lt;a href="http://media.24ways.org/2008/11/polypage-example.html"&gt;fully fledged example&lt;/a&gt; in this fictional social network &lt;a href="http://media.24ways.org/2008/11/polypage-example.html"&gt;group page&lt;/a&gt;. The example page defaults to a logged in state. You can see the logged out state by toggling &amp;#8216;logged in&amp;#8217; off in the Polypage control bar. There are also views specified for a &lt;em&gt;group member&lt;/em&gt;, a &lt;em&gt;group admin&lt;/em&gt;, a &lt;em&gt;new group&lt;/em&gt; and &lt;em&gt;notes&lt;/em&gt;. &lt;/p&gt;

	&lt;h3&gt;Where can I get hold of it?&lt;/h3&gt;

	&lt;p&gt;You can download the current version from &lt;a href="http://github.com/andykent/polypage/"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;Polypage was originally developed by &lt;a href="http://clearleft.com/"&gt;Clearleft&lt;/a&gt; and &lt;a href="http://new-bamboo.co.uk/"&gt;New Bamboo&lt;/a&gt;, with particular contributions from &lt;a href="http://adkent.com/"&gt;Andy Kent&lt;/a&gt; and &lt;a href="http://natbat.net/"&gt;Natalie Downe&lt;/a&gt;. It has been used in numerous real projects, but it is still an early release so there is bound to be room for improvement. We&amp;#8217;re pleased to say that Polypage is now an open source project so any feedback, particularly by way of actual improvements, is extremely welcome.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=tGrU-lrGUhQ:leelHLMN4yI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=tGrU-lrGUhQ:leelHLMN4yI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=tGrU-lrGUhQ:leelHLMN4yI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=tGrU-lrGUhQ:leelHLMN4yI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=tGrU-lrGUhQ:leelHLMN4yI:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/tGrU-lrGUhQ" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://clagnut.com/"&gt;Richard Rutter&lt;/a&gt; brings an interesting new tool to the wireframing table with the introduction of a smart and exceptionally useful jQuery plugin. If you ever get involved in designing or prototyping modern multi-state web sites or applications, you&amp;#8217;ll want to check this out.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/easier-page-states-for-wireframes</feedburner:origLink></entry>
<entry>
		<author>
			<name>Elliot Jay Stocks</name>
		</author>
		<published>2008-12-10T00:00:08Z</published>
		<updated>2008-12-10T00:08:15Z</updated>
		<title type="html">A Christmas hCard From Me To You</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/MU5i8U5s3LY/a-christmas-hcard-from-me-to-you" />
		<id>tag:24ways.org,2008-12-09:7e1577ceca7ea22e28af5c35ee62927a/99c60f9015e1fe6acd2f2c2748586184</id>
		<category term="microformats" />
		
		<content type="html">
&lt;p&gt;So apparently Christmas is coming. And what is Christmas all about? Well, cleaning out your address book, of course! What better time to go through your contacts, making sure everyone&amp;#8217;s details are up date and that you&amp;#8217;ve deleted all those nasty clients who never paid on time?&lt;/p&gt;

	&lt;p&gt;It&amp;#8217;s also a good time to make sure your current clients and colleagues have your most up-to-date details, so instead of filling up their inboxes with e-cards, why not send them something useful? Something like a&amp;#8230; vCard! (See what I did there?)&lt;/p&gt;

	&lt;p&gt;Just in case you&amp;#8217;ve been working in a magical toy factory in the upper reaches of Scandinavia for the last few years, I&amp;#8217;m going to tell you that now would also be the perfect time to get into &lt;a href="http://microformats.org/"&gt;microformats&lt;/a&gt;. Using the hCard format, we&amp;#8217;ll build a very simple web page and markup our contact details in such a way that they&amp;#8217;ll be understood by microformats plugins, like &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/4106"&gt;Operator&lt;/a&gt; or &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2240"&gt;Tails&lt;/a&gt; for Firefox, or the cross-browser &lt;a href="http://leftlogic.com/lounge/articles/microformats_bookmarklet/"&gt;Microformats Bookmarklet&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;Oh, and because Christmas is all about dressing up and being silly, we&amp;#8217;ll make the whole thing look nice and have a bit of fun with some CSS3 progressive enhancement. &lt;/p&gt;

	&lt;p&gt;If you can&amp;#8217;t wait to see what we end up with, you can &lt;a href="http://media.24ways.org/2008/10/index.html"&gt;preview it here&lt;/a&gt;.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/10/1.jpg" width="800" height="610" alt="Figure 1" /&gt;&lt;/p&gt;

	&lt;h3&gt;Step 1: Contact Details&lt;/h3&gt;

	&lt;p&gt;First, let&amp;#8217;s decide what details we want to put on the page. I&amp;#8217;d put my full name, my email address, my phone number, and my postal address, but I&amp;#8217;d rather not get surprise visits from strangers when I&amp;#8217;m fannying about with my baubles, so I&amp;#8217;m going to use Father Christmas instead (that&amp;#8217;s Santa to you Yanks).&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;Father Christmas&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fatherchristmas@elliotjaystocks.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;25 Laughingallthe Way&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Snow Falls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Lapland&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Finland&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;010 60 58 000&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;h3&gt;Step 2: hCard Creator&lt;/h3&gt;

	&lt;p&gt;Now I&amp;#8217;m not sure about you, but I rather like getting the magical robot pixies to do the work for me, so head on over to the &lt;a href="http://microformats.org/code/hcard/creator"&gt;hCard Creator&lt;/a&gt; and put those pixies to work! Pop in your details and they&amp;#8217;ll give you some nice microformatted &lt;span class="caps"&gt;HTML&lt;/span&gt; in turn.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/10/2.jpg" width="800" height="610" alt="Figure 2" /&gt;&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;hcard-Father-Christmas&amp;quot; class=&amp;quot;vcard&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;a class=&amp;quot;url fn&amp;quot; href=&amp;quot;http://elliotjaystocks.com/fatherchristmas&amp;quot;&amp;gt;Father Christmas&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;a class=&amp;quot;email&amp;quot; href=&amp;quot;mailto:fatherchristmas@elliotjaystocks.com&amp;quot;&amp;gt; fatherchristmas@elliotjaystocks.com&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;adr&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;street-address&amp;quot;&amp;gt;25 Laughingallthe Way&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;locality&amp;quot;&amp;gt;Snow Falls&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;, &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;region&amp;quot;&amp;gt;Lapland&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;, &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;postal-code&amp;quot;&amp;gt;FI-00101&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;country-name&amp;quot;&amp;gt;Finland&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;tel&amp;quot;&amp;gt;010 60 58 000&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;p style=&amp;quot;font-size:smaller;&amp;quot;&amp;gt;This &amp;lt;a href=&amp;quot;http://microformats.org/wiki/hcard&amp;quot;&amp;gt;hCard&amp;lt;/a&amp;gt; created with the &amp;lt;a href=&amp;quot;http://microformats.org/code/hcard/creator&amp;quot;&amp;gt;hCard creator&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-christmas-hcard-from-me-to-you/2.txt" title="Download the above code as a textfile"&gt;/code/a-christmas-hcard-from-me-to-you/2.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;h3&gt;Step 3: Editing The Code&lt;/h3&gt;

	&lt;p&gt;One of the great things about microformats is that you can use pretty much whichever &lt;span class="caps"&gt;HTML&lt;/span&gt; tags you want, so just because the hCard Creator Fairies say something should be wrapped in a &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; doesn&amp;#8217;t mean you can&amp;#8217;t change it to a &lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt;. Actually, no, don&amp;#8217;t do that. That&amp;#8217;s not even excusable at Christmas.&lt;/p&gt;

	&lt;p&gt;I personally have a penchant for marking up each line of an address inside a &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tag, where the parent url retains the class of &lt;code&gt;adr&lt;/code&gt;. As long as you keep the class names the same, you&amp;#8217;ll be fine.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;hcard-Father-Christmas&amp;quot; class=&amp;quot;vcard&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;&amp;lt;a class=&amp;quot;url fn&amp;quot; href=&amp;quot;http://elliotjaystocks.com/fatherchristmas&amp;quot;&amp;gt;Father Christmas &amp;lt;/a&amp;gt;&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;a class=&amp;quot;email&amp;quot; href=&amp;quot;mailto:fatherchristmas@elliotjaystocks.com?subject=Here, have some Christmas cheer!&amp;quot;&amp;gt;fatherchristmas@elliotjaystocks.com&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;ul class=&amp;quot;adr&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;street-address&amp;quot;&amp;gt;25 Laughingallthe Way&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;locality&amp;quot;&amp;gt;Snow Falls&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;region&amp;quot;&amp;gt;Lapland&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;postal-code&amp;quot;&amp;gt;FI-00101&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;country-name&amp;quot;&amp;gt;Finland&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;tel&amp;quot;&amp;gt;010 60 58 000&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-christmas-hcard-from-me-to-you/3.txt" title="Download the above code as a textfile"&gt;/code/a-christmas-hcard-from-me-to-you/3.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;h3&gt;Step 4: Testing The Microformats&lt;/h3&gt;

	&lt;p&gt;With our microformats in place, now would be a good time to test that they&amp;#8217;re working before we start making things look pretty. If you&amp;#8217;re on Firefox, you can install the &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/4106"&gt;Operator&lt;/a&gt; or &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2240"&gt;Tails&lt;/a&gt; extensions, but if you&amp;#8217;re on another browser, just add the &lt;a href="http://leftlogic.com/lounge/articles/microformats_bookmarklet/"&gt;Microformats Bookmarklet&lt;/a&gt;. Regardless of your choice, the results is the same: if you&amp;#8217;ve code microformatted content on a web page, one of these bad boys should pick it up for you and allow you to export the contact info. Give it a try and you should see father Christmas appearing in your address book of choice. Now you&amp;#8217;ll never forget where to send those Christmas lists!&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/10/4.jpg" width="800" height="400" alt="Figure 4" /&gt;&lt;/p&gt;

	&lt;h3&gt;Step 5: Some Extra Markup&lt;/h3&gt;

	&lt;p&gt;One of the first things we&amp;#8217;re going to do is put a photo of Father Christmas on the hCard. We&amp;#8217;ll be using &lt;span class="caps"&gt;CSS&lt;/span&gt; to apply a background image to a div, so we&amp;#8217;ll be needing an extra div with a class name of &amp;#8220;photo&amp;#8221;. In turn, we&amp;#8217;ll wrap the text-based elements of our hCard inside a div cunningly called &amp;#8220;text&amp;#8221;. Unfortunately, because of the float technique we&amp;#8217;ll be using, we&amp;#8217;ll have to use one of those nasty float-clearing techniques. I shall call this &amp;#8220;christmas-cheer&amp;#8221;, since that is what its presence will inevitably bring, of course.&lt;/p&gt;

	&lt;p&gt;Oh, and let&amp;#8217;s add a bit of text to give the page context, too:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;p&amp;gt;Send your Christmas lists my way...&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div id=&amp;quot;hcard-Father-Christmas&amp;quot; class=&amp;quot;vcard&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;text&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;&amp;lt;a class=&amp;quot;url fn&amp;quot; href=&amp;quot;http://elliotjaystocks.com/fatherchristmas&amp;quot;&amp;gt;Father Christmas &amp;lt;/a&amp;gt;&amp;lt;/h1&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;a class=&amp;quot;email&amp;quot; href=&amp;quot;mailto:fatherchristmas@elliotjaystocks.com?subject=Here, have some Christmas cheer!&amp;quot;&amp;gt;fatherchristmas@elliotjaystocks.com&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;ul class=&amp;quot;adr&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;street-address&amp;quot;&amp;gt;25 Laughingallthe Way&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;locality&amp;quot;&amp;gt;Snow Falls&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;region&amp;quot;&amp;gt;Lapland&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;postal-code&amp;quot;&amp;gt;FI-00101&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;&amp;lt;li class=&amp;quot;country-name&amp;quot;&amp;gt;Finland&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;tel&amp;quot;&amp;gt;010 60 58 000&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;photo&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;br class=&amp;quot;christmas-cheer&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;credits&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;p&amp;gt;A tutorial by &amp;lt;a href=&amp;quot;http://elliotjaystocks.com&amp;quot;&amp;gt;Elliot Jay Stocks&amp;lt;/a&amp;gt; for &amp;lt;a href=&amp;quot;http://24ways.org/&amp;quot;&amp;gt;24 Ways&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;p&amp;gt;Background: &amp;lt;a href=&amp;quot;http://sxc.hu/photo/1108741&amp;quot;&amp;gt;stock.xchng&amp;lt;/a&amp;gt; | Father Christmas: &amp;lt;a href=&amp;quot;http://istockphoto.com/file_closeup/people/4575943-active-santa.php?id=4575943&amp;quot;&amp;gt;iStockPhoto&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/a-christmas-hcard-from-me-to-you/4.txt" title="Download the above code as a textfile"&gt;/code/a-christmas-hcard-from-me-to-you/4.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;h3&gt;Step 6: Some Christmas Sparkle&lt;/h3&gt;

	&lt;p&gt;So far, our hCard-housing web page is slightly less than inspiring, isn&amp;#8217;t it? It&amp;#8217;s time to add a bit of &lt;span class="caps"&gt;CSS&lt;/span&gt;. There&amp;#8217;s nothing particularly radical going on here; just a simple layout, some basic typographic treatment, and the placement of the Father Christmas photo. I&amp;#8217;d usually use a more thorough &lt;span class="caps"&gt;CSS&lt;/span&gt; reset like the one found in the &lt;span class="caps"&gt;YUI&lt;/span&gt; or Eric Meyer&amp;#8217;s, but for this basic page, the simple &lt;code&gt;*&lt;/code&gt; solution will do.&lt;/p&gt;

	&lt;p&gt;Check out the step 6 demo to &lt;a href="http://media.24ways.org/2008/10/step06.html"&gt;see our basic styles in place&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;From this&amp;#8230;&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/10/6a.jpg" width="800" height="373" alt="Figure 6a" /&gt;&lt;/p&gt;

	&lt;p&gt;&amp;#8230; to this:&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/10/6b.jpg" width="800" height="610" alt="Figure 6b" /&gt;&lt;/p&gt;

	&lt;h3&gt;Step 7: Fun With imagery&lt;/h3&gt;

	&lt;p&gt;Now it&amp;#8217;s time to introduce a repeating background image to the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; element. This will seamlessly repeat for as wide as the browser window becomes.&lt;/p&gt;

	&lt;p&gt;But that&amp;#8217;s fairly straightforward. How about having some fun with the Father Christmas image? If you look at the image file itself, you&amp;#8217;ll see that it&amp;#8217;s twice as wide as the area we can see and contains a &amp;#8216;hidden&amp;#8217; photo of our rather camp St. Nick.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/10/assets/portrait.jpg" width="300" height="275" alt="Portrait" /&gt;&lt;/p&gt;

	&lt;p&gt;As a light-hearted visual&amp;#8230; er&amp;#8230; &amp;#8216;treat&amp;#8217; for users who move their mouse over the image, we move the position of the background image on the &amp;#8220;photo&amp;#8221; div. Check out the step 7 demo to &lt;a href="http://media.24ways.org/2008/10/step07.html"&gt;see it working&lt;/a&gt;.&lt;/p&gt;

	&lt;h3&gt;Step 8: Progressive Enhancement&lt;/h3&gt;

	&lt;p&gt;Finally, this fun little project is a great opportunity for us to mess around with some advanced &lt;span class="caps"&gt;CSS&lt;/span&gt; features (some from the CSS3 spec) that we rarely get to use on client projects. (Don&amp;#8217;t forget: no Christmas pressies for clients who want you to support IE6!)&lt;/p&gt;

	&lt;p&gt;Here are the rules we&amp;#8217;re using to give some browsers a superior viewing experience:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;&lt;code&gt;@font-face&lt;/code&gt; allows us to use Jos Buivenga&amp;#8217;s free font &amp;#8216;Fertigo Pro&amp;#8217; on all text;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;text-shadow&lt;/code&gt; adds a little emphasis on the opening paragraph;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;body &amp;gt; p:first-child&lt;/code&gt; causes only the first paragraph to receive this treatment;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;border-radius&lt;/code&gt; created rounded corners on our main &lt;code&gt;div&lt;/code&gt; and the links within it;&lt;/li&gt;
		&lt;li&gt;and &lt;code&gt;webkit-transition&lt;/code&gt; allows us to gently fade in between the default and hover states of those links.&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;And with that, we&amp;#8217;re done! You can &lt;a href="http://media.24ways.org/2008/10/index.html"&gt;see the results here&lt;/a&gt;. It&amp;#8217;s time to customise the page to your liking, upload it to your site, and send out the &lt;span class="caps"&gt;URL&lt;/span&gt;. And do it quickly, because I&amp;#8217;m sure you&amp;#8217;ve got some last-minute Christmas shopping to finish off!&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/10/1.jpg" width="800" height="610" alt="Figure 1" /&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=MU5i8U5s3LY:30FdLOy0MHM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=MU5i8U5s3LY:30FdLOy0MHM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=MU5i8U5s3LY:30FdLOy0MHM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=MU5i8U5s3LY:30FdLOy0MHM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=MU5i8U5s3LY:30FdLOy0MHM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/MU5i8U5s3LY" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://elliotjaystocks.com/"&gt;Elliot Jay Stocks&lt;/a&gt; steps us through publishing a set of contact details using the hCard microformat. Once the basics are in place follow along as we add some sparkle with the aid of CSS3 web fonts, text-shadow, border-radius and first-child selectors.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/a-christmas-hcard-from-me-to-you</feedburner:origLink></entry>
<entry>
		<author>
			<name>Marcus Lillington</name>
		</author>
		<published>2008-12-09T00:00:04Z</published>
		<updated>2008-12-09T00:00:04Z</updated>
		<title type="html">Charm Clients, Win Pitches</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/0RTyngP1Vfc/charm-clients-win-pitches" />
		<id>tag:24ways.org,2008-12-07:7e1577ceca7ea22e28af5c35ee62927a/27e0df2f45bcebfe377fb1c67fed7db1</id>
		<category term="business" />
		
		<content type="html">
&lt;p&gt;Over the years I have picked up a number of sales techniques that have lead to us doing pretty well in the pitches we go for. Of course, up until now, these top secret practices have remained firmly locked in the company vault but now I am going to share them with you. They are cunningly hidden within the following paragraphs so I&amp;#8217;m afraid you&amp;#8217;re going to have to read the whole thing.&lt;/p&gt;

	&lt;p&gt;Ok, so where to start? I guess a good place would be getting invited to pitch for work in the first place.&lt;/p&gt;

	&lt;h3&gt;Shameless self promotion&lt;/h3&gt;

	&lt;h4&gt;What not to do&lt;/h4&gt;

	&lt;p&gt;You&amp;#8217;re as keen as mustard to &amp;#8216;sell&amp;#8217; what you do, but you have no idea as to the right approach. From personal experience (sometimes bitter!), the following methods are as useful as the proverbial chocolate teapot:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Cold calling&lt;/li&gt;
		&lt;li&gt;Advertising&lt;/li&gt;
		&lt;li&gt;Bidding websites&lt;/li&gt;
		&lt;li&gt;Sales people&lt;/li&gt;
		&lt;li&gt;Networking events&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;Ok, I&amp;#8217;m exaggerating; sometimes these things work. For example, cold calling can work if you have a story &amp;#8211; a reason to call and introduce yourself other than &amp;#8220;we do web design and you have a website&amp;#8221;. &amp;#8220;We do web design and we&amp;#8217;ve just moved in next door to you&amp;#8221; would be fine. &lt;/p&gt;

	&lt;p&gt;Advertising can work if your offering is highly specialist. However, paying oodles of dollars a day to Google Ads to appear under the search term &amp;#8216;web design&amp;#8217; is probably not the best use of your budget. &lt;/p&gt;

	&lt;p&gt;Specialising is, in fact, probably a good way to go. Though it can feel counter intuitive in that you are not spreading yourself as widely as you might, you will eventually become an expert and therefore gain a reputation in your field. Specialism doesn&amp;#8217;t necessarily have to be in a particular skillset or technology, it could just as easily be in a particular supply chain or across a market.&lt;/p&gt;

	&lt;h4&gt;Target audience&lt;/h4&gt;

	&lt;p&gt;&amp;#8216;Who to target?&amp;#8217; is the next question. If you&amp;#8217;re starting out then do tap-up your family and friends. Anything that comes your way from them will almost certainly come with a strong recommendation. Also, there&amp;#8217;s nothing wrong with calling clients you had dealings with in previous employment (though beware of any contractual terms that may prevent this). You are informing your previous clients that your situation has changed; leave it up to them to make any move towards working with you. After all, you&amp;#8217;re simply asking to be included on the list of agencies invited to tender for any new work.&lt;/p&gt;

	&lt;p&gt;Look to target clients similar to those you have worked with previously. Again, you have a story – hopefully a good one!&lt;/p&gt;

	&lt;p&gt;So how do you reach these people?&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Mailing lists&lt;/li&gt;
		&lt;li&gt;Forums&lt;/li&gt;
		&lt;li&gt;Writing articles&lt;/li&gt;
		&lt;li&gt;Conferences / Meetups&lt;/li&gt;
		&lt;li&gt;Speaking opportunities&lt;/li&gt;
		&lt;li&gt;Sharing Expertise&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;In essence: blog, chat, talk, enthuse, show off (a little)&amp;#8230; share.&lt;/p&gt;

	&lt;p&gt;There are many ways you can do this. There&amp;#8217;s the traditional portfolio, almost obligatory blog (regularly updated of course), podcast, &amp;#8216;giveaways&amp;#8217; like Wordpress templates, &lt;span class="caps"&gt;CSS&lt;/span&gt; galleries and testimonials. Testimonials are your greatest friend. Always ask clients for quotes (write them and ask for their permission to use) and even better, film them talking about how great you are.&lt;/p&gt;

	&lt;p&gt;Finally, social networking sites can offer a way to reach your target audiences. You do have to be careful here though. You are looking to build a reputation by contributing value. Do not self promote or spam!&lt;/p&gt;

	&lt;h3&gt;Writing proposals&lt;/h3&gt;

	&lt;h4&gt;Is it worth it?&lt;/h4&gt;

	&lt;p&gt;Ok, so you have been invited to respond to a tender or brief in the form of a proposal. Good proposals take time to put together so you need to be sure that you are not wasting your time. There are two fundamental questions that you need to ask prior to getting started on your proposal:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;Can I deliver within the client&amp;#8217;s timescales?&lt;/li&gt;
		&lt;li&gt;Does the client&amp;#8217;s budget match my price?&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p&gt;The timescales that clients set are often plucked from the air and a little explanation about how long projects usually take can be enough to change expectations with regard to delivery. However, if a deadline is set in stone ask yourself if you can realistically meet it. Agreeing to a deadline that you know you cannot meet just to win a project is a recipe for an unhappy client, no chance of repeat business and no chance of any recommendations to other potential clients.&lt;/p&gt;

	&lt;p&gt;Price is another thing altogether. So why do we need to know?&lt;/p&gt;

	&lt;p&gt;The first reason, and most honest reason, is that we don&amp;#8217;t want to do a lot of unpaid pitch work when there is no chance that our price will be accepted. Who would? But this goes both ways – the client&amp;#8217;s time is also being wasted. It may only be the time to read the proposal and reject it, but what if all the bids are too expensive? Then the client needs to go through the whole process again.&lt;/p&gt;

	&lt;p&gt;The second reason why we need to know budgets relates to what we would like to include in a proposal over what we need to include. For example, take usability testing. We always highly recommend that a client pays for at least one round of usability testing because it will definitely improve their new site – no question. But, not doing it doesn&amp;#8217;t mean they&amp;#8217;ll end up with an unusable turkey. It&amp;#8217;s just more likely that any usability issues will crop up after launch.&lt;/p&gt;

	&lt;p&gt;I have found that the best way to discover a budget is to simply provide a ballpark total, usually accompanied by a list of &amp;#8216;likely tasks for this type of project&amp;#8217;, in an initial email or telephone response. Expect a lot of people to dismiss you out of hand. This is good. Don&amp;#8217;t be tempted to &amp;#8216;just go for it&amp;#8217; anyway because you like the client or work is short – you will regret it.&lt;/p&gt;

	&lt;p&gt;Others will say that the ballpark is ok. This is not as good as getting into a proper discussion about what priorities they might have but it does mean that you are not wasting your time and you do have a chance of winning the work. The only real risk with this approach is that you misinterpret the requirements and produce an inaccurate ballpark.&lt;/p&gt;

	&lt;p&gt;Finally, there is a less confrontational approach that I sometimes use that involves modular pricing. We break down our pricing into quite detailed tasks for all proposals but when I really do not have a clue about a client&amp;#8217;s budget, I will often separate pricing into &amp;#8216;core&amp;#8217; items and &amp;#8216;optional&amp;#8217; items. This has proved to be a very effective method of presenting price.&lt;/p&gt;

	&lt;h4&gt;What to include&lt;/h4&gt;

	&lt;p&gt;So, what should go into a proposal? It does depend on the size of the piece of work. If it&amp;#8217;s a quick update for an existing client then they don&amp;#8217;t want to read through all your blurb about why they should choose to work with you – a simple email will suffice.&lt;/p&gt;

	&lt;p&gt;But, for a potential new client I would look to include the following:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Your suitability&lt;/li&gt;
		&lt;li&gt;Summary of tasks&lt;/li&gt;
		&lt;li&gt;Timescales&lt;/li&gt;
		&lt;li&gt;Project management methodology&lt;/li&gt;
		&lt;li&gt;Pricing&lt;/li&gt;
		&lt;li&gt;Testing methodology&lt;/li&gt;
		&lt;li&gt;Hosting options&lt;/li&gt;
		&lt;li&gt;Technologies&lt;/li&gt;
		&lt;li&gt;Imagery&lt;/li&gt;
		&lt;li&gt;References&lt;/li&gt;
		&lt;li&gt;Financial information&lt;/li&gt;
		&lt;li&gt;Biographies&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;However, probably the most important aspect of any proposal is that you respond fully to the brief. In other words, don&amp;#8217;t ignore the bits that either don&amp;#8217;t make sense to you or you think irrelevant. If something is questionable, cover it and explain why you don&amp;#8217;t think it is something that warrants inclusion in the project.&lt;/p&gt;

	&lt;p&gt;Should you provide speculative designs? If the brief doesn&amp;#8217;t ask for any, then certainly not. If it does, then speak to the client about why you don&amp;#8217;t like to do speculative designs. Explain that any designs included as part of a proposal are created to impress the client and not the website&amp;#8217;s target audience. Producing good web design is a partnership between client and agency. This can often impress and promote you as a professional. However, if they insist then you need to make a decision because not delivering any mock-ups will mean that all your other work will be a waste of time.&lt;/p&gt;

	&lt;h4&gt;Walking away&lt;/h4&gt;

	&lt;p&gt;As I have already mentioned, all of this takes a lot of work. So, when should you be prepared to walk away from a potential job? I have already covered unrealistic deadlines and insufficient budget but there are a couple of other reasons. Firstly, would this new client damage your reputation, particularly within current sectors you are working in? Secondly, can you work with this client? A difficult client will almost certainly lead to a loss-making project.&lt;/p&gt;

	&lt;h3&gt;Perfect pitch&lt;/h3&gt;

	&lt;h4&gt;Requirements&lt;/h4&gt;

	&lt;p&gt;If the original brief didn&amp;#8217;t spell out what is expected of you at a presentation then make sure you ask beforehand. The critical element is how much time you have. It seems that panels are providing less and less time these days.&lt;/p&gt;

	&lt;p&gt;The usual formula is that you get an hour; half of which should be a presentation of your ideas followed by 30 minutes of questions. This isn&amp;#8217;t that much time, particularly for a big project that covers all aspect of web design and production. Don&amp;#8217;t be afraid to ask for more time, though it is very rare that you will be granted any.&lt;/p&gt;

	&lt;p&gt;Ask if there any areas that a) they particularly want you to cover and b) if there are any areas of your proposal that were weak.&lt;/p&gt;

	&lt;p&gt;Ask who will be attending. The main reason for this is to see if the decision maker(s) will be present but it&amp;#8217;s also good to know if you&amp;#8217;re presenting to 3 or 30 people.&lt;/p&gt;

	&lt;h4&gt;Who should be there&lt;/h4&gt;

	&lt;p&gt;Generally speaking, I think two is the ideal number. Though I have done many presentations on my own, I always feel having two people to bounce ideas around with and have a bit of banter with, works well. You are not only trying to sell your ideas and expertise but also yourselves. One of the main things in the panels minds will be – &amp;#8220;can I work with these people?&amp;#8221;&lt;/p&gt;

	&lt;p&gt;Having more than two people at a presentation often looks like you&amp;#8217;re wheeling people out just to demonstrate that they exist.&lt;/p&gt;

	&lt;h4&gt;What makes a client want to hire you?&lt;/h4&gt;

	&lt;p&gt;In a nutshell: Confidence, Personality, Enthusiasm.&lt;/p&gt;

	&lt;p&gt;You can impart confidence by being well prepared and professional, providing examples and demonstrations and talking about your processes. You may find project management boring but pretty much every potential client will want to feel reassured that you manage your projects effectively.&lt;/p&gt;

	&lt;p&gt;As well as demonstrating that you know what you&amp;#8217;re talking about, it is important to encourage, and be part of, discussion about the project. Be prepared to suggest and challenge and be willing to say &amp;#8220;I don&amp;#8217;t know&amp;#8221;.&lt;/p&gt;

	&lt;p&gt;Also, no-one likes a show-off so don&amp;#8217;t over promote yourself; encourage them to contact your existing clients.&lt;/p&gt;

	&lt;h4&gt;What makes a client like you?&lt;/h4&gt;

	&lt;p&gt;Engaging with a potential client is tricky and it&amp;#8217;s probably the area where you need to be most on your toes and try to gauge the reaction of the client. We recommend the following:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Encourage questions throughout&lt;/li&gt;
		&lt;li&gt;Ask if you make sense – which encourages questions if you&amp;#8217;re not getting any&lt;/li&gt;
		&lt;li&gt;Humour – though don&amp;#8217;t keep trying to be funny if you&amp;#8217;re not getting any laughs!&lt;/li&gt;
		&lt;li&gt;Be willing to go off track&lt;/li&gt;
		&lt;li&gt;Read your audience&lt;/li&gt;
		&lt;li&gt;Empathise with the process – chances are, most of the people in front of you would rather be doing something else&lt;/li&gt;
		&lt;li&gt;Think about what you wear – this sounds daft but do you want to be seen as either the &amp;#8216;stiff in the suit&amp;#8217; or the &amp;#8216;scruffy art student&amp;#8217;? Chances are neither character would get hired.&lt;/li&gt;
	&lt;/ul&gt;

	&lt;h4&gt;Differentiation&lt;/h4&gt;

	&lt;p&gt;Sometimes, especially if you think you are an outsider, it&amp;#8217;s worth taking a few risks. I remember my colleague Paul starting off a presentation once with the line (backed up on screen) – &amp;#8220;Headscape is not a usability consultancy&amp;#8221;. This was in response to the clients request to engage a usability consultancy. The thrust of Paul&amp;#8217;s argument was that we are a lot more than that.&lt;/p&gt;

	&lt;p&gt;This really worked. We were the outside choice but they ended up hiring us. Basically, this differentiated us from the crowd. It showed that we are prepared to take risks and think, dare I say it, outside of the box.&lt;/p&gt;

	&lt;h4&gt;Dealing with difficult characters &lt;/h4&gt;

	&lt;p&gt;How you react to tricky questioning is likely to be what determines whether you have a good or bad presentation. Here are a few of those characters that so often turn up in panels:&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;The techie&lt;/strong&gt; – this is likely to be the situation where you need to say &amp;#8220;I don&amp;#8217;t know&amp;#8221;. Don&amp;#8217;t bluff as you are likely to dig yourself a great big embarrassment-filled hole. Promise to follow up with more information and make sure that you do so as quickly as possible after the pitch. &lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;The &amp;#8216;hard man&amp;#8217; MD&lt;/strong&gt; – this the guy who thinks it is his duty to throw &amp;#8216;curve ball&amp;#8217; questions to see how you react. Focus on your track record (big name clients will impress this guy) and emphasise your processes.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;The &amp;#8216;no clue&amp;#8217; client&lt;/strong&gt; – you need to take control and be the expert though you do need to explain the reasoning behind any suggestions you make. This person will be judging you on how much you are prepared to help them deliver the project.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;The price negotiator&lt;/strong&gt; – be prepared to discuss price but do not reduce your rate or the effort associated with your proposal. Fall back on modular pricing and try to reduce scope to come within budget. You may wish to offer a one-off discount to win a new piece of work but don&amp;#8217;t get into detail at the pitch.&lt;/p&gt;

	&lt;h4&gt;Don&amp;#8217;t panic&amp;#8230;&lt;/h4&gt;

	&lt;p&gt;If you go into a presentation thinking &amp;#8216;we must win this&amp;#8217; then, chances are, you won&amp;#8217;t. Relax and be yourself. If you&amp;#8217;re not hitting it off with the panel then so be it. You have to remember that quite often you will be making up the numbers in a tendering process. This is massively frustrating but, unfortunately, part of it. If it&amp;#8217;s not going well, concentrate on what you are offering and try to demonstrate your professionalism rather than your personality. Finally, be on your toes, watch people&amp;#8217;s reactions and pay attention to what they say and try to react accordingly.&lt;/p&gt;

	&lt;p&gt;So where are the secret techniques I hear you ask? Well, using the words &amp;#8216;secret&amp;#8217; and &amp;#8216;technique&amp;#8217; was probably a bit naughty. Most of this stuff is about being keen, using your brain and believing in yourself and what you are selling rather than following a strict set of rules.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=0RTyngP1Vfc:FqJdAfJJ4kY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=0RTyngP1Vfc:FqJdAfJJ4kY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=0RTyngP1Vfc:FqJdAfJJ4kY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=0RTyngP1Vfc:FqJdAfJJ4kY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=0RTyngP1Vfc:FqJdAfJJ4kY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/0RTyngP1Vfc" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://www.headscape.co.uk/"&gt;Marcus Lillington&lt;/a&gt; has some ideas to pitch &amp;#8211; to help you to win more of the jobs worth winning. From deciding how to market your services, through to writing a proposal and eventually attending a pitch, let Marcus take you by the hand and walk you through the process.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/charm-clients-win-pitches</feedburner:origLink></entry>
<entry>
		<author>
			<name>Jeremy Keith</name>
		</author>
		<published>2008-12-08T00:00:13Z</published>
		<updated>2008-12-08T00:00:13Z</updated>
		<title type="html">The IE6 Equation</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/aMWCaJnINhY/the-ie6-equation" />
		<id>tag:24ways.org,2008-12-07:7e1577ceca7ea22e28af5c35ee62927a/5dbf9d438440ca79e57c568797a871a2</id>
		<category term="browsers" />
		<category term="productivity" />
		<content type="html">
&lt;p&gt;It is the destiny of one browser to serve as the nemesis of web developers everywhere. At the birth of the Web Standards movement, that role was played by Netscape Navigator 4; an outdated browser that refused to die. Its tenacious existence hampered the adoption of modern standards. Today that role is played by &lt;dfn&gt;Internet Explorer 6&lt;/dfn&gt;.&lt;/p&gt;

	&lt;p&gt;There&amp;#8217;s a sensation that I&amp;#8217;m sure you&amp;#8217;re familiar with. It&amp;#8217;s a horrible mixture of dread and nervousness. It&amp;#8217;s the feeling you get when—after working on a design for a while in a standards-compliant browser like Firefox, Safari or Opera—you decide that you can no longer put off the inevitable moment when you must check the site in IE6. Fingers are crossed, prayers are muttered, but alas, to no avail. The nemesis browser invariably screws something up.&lt;/p&gt;

	&lt;p&gt;What do you do next? If the differences in &lt;abbr title="Internet Explorer 6"&gt;IE6&lt;/abbr&gt; are minor, you could just leave it be. After all, websites don&amp;#8217;t need to look exactly the same in all browsers. But if there are major layout issues and a significant portion of your audience is still using IE6, you&amp;#8217;ll probably need to roll up your sleeves and start fixing the problems.&lt;/p&gt;

	&lt;p&gt;A common approach is to quarantine IE6-specific &lt;abbr title="Cascading Style Sheets"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/abbr&gt; in a separate stylesheet. This stylesheet can then be referenced from the &lt;abbr title="HyperText Markup Language"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/abbr&gt; document using conditional comments like this:&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;!--[if lt IE 7]&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;ie6.css&amp;quot; type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;![endif]--&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;That stylesheet will only be served up to Internet Explorer where the version number is less than 7.&lt;/p&gt;

	&lt;p&gt;You can put anything inside a conditional comment. You could put a &lt;code&gt;script&lt;/code&gt; element in there. So as well as serving up browser-specific &lt;span class="caps"&gt;CSS&lt;/span&gt;, it&amp;#8217;s possible to serve up browser-specific JavaScript.&lt;/p&gt;

	&lt;p&gt;A few years back, before Microsoft released Internet Explorer 7, JavaScript genius &lt;span class="vcard"&gt;&lt;a href="http://dean.edwards.name/" class="fn url"&gt;Dean Edwards&lt;/a&gt;&lt;/span&gt; wrote &lt;a href="http://dean.edwards.name/IE7/"&gt;a script called IE7&lt;/a&gt;. This amazing piece of code uses JavaScript to make Internet Explorer 5 and 6 behave like a standards-compliant browser. Dean used JavaScript to bootstrap IE&amp;#8217;s &lt;span class="caps"&gt;CSS&lt;/span&gt; support.&lt;/p&gt;

	&lt;p&gt;Because the script is specifically targeted at Internet Explorer, there&amp;#8217;s no point in serving it up to other browsers. Conditional comments to the rescue:&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;!--[if lt IE 7]&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;script src=&amp;quot;http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE7.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="cmnt"&gt;&lt;code&gt;&amp;lt;![endif]--&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Standards-compliant browsers won&amp;#8217;t fetch the script. Users of IE6, on the hand, will pay a kind of bad browser tax by having to download the JavaScript file.&lt;/p&gt;

	&lt;p&gt;So when should you develop an IE6-specific stylesheet and when should you just use Dean&amp;#8217;s JavaScript code? This is the question that myself and my co-worker &lt;span class="vcard"&gt;&lt;a href="http://natbat.net/" class="fn url"&gt;Natalie Downe&lt;/a&gt;&lt;/span&gt; set out to answer one morning at Clearleft. We realised that in order to answer that question you need to first answer two other questions, &lt;q&gt;how much time does it take to develop for IE6?&lt;/q&gt; and &lt;q&gt;how much of your audience is using IE6?&lt;/q&gt;&lt;/p&gt;

	&lt;p&gt;Let&amp;#8217;s say that &lt;kbd&gt;t&lt;/kbd&gt; represents the total development time. Let &lt;kbd&gt;t&lt;sub&gt;6&lt;/sub&gt;&lt;/kbd&gt; represent the portion of that time you spend developing for IE6. If your total audience is &lt;kbd&gt;a&lt;/kbd&gt;, then &lt;kbd&gt;a&lt;sub&gt;6&lt;/sub&gt;&lt;/kbd&gt; is the portion of your audience using IE6. With some algebraic help from our mathematically minded co-worker &lt;span class="vcard"&gt;&lt;a href="http://www.cennydd.co.uk/" class="fn url"&gt;&lt;span lang="cy"&gt;Cennydd&lt;/span&gt; Bowles&lt;/a&gt;&lt;/span&gt;, Natalie and I came up with the following equation to calculate the percentage likelihood that you should be using Dean&amp;#8217;s IE7 script:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/08/equation.gif" width="275" height="65" alt="" /&gt;&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;p = 50 [ log ( at6 / ta6 ) + 1 ]&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Try plugging in your own numbers. If you spend a lot of time developing for IE6 and only a small portion of your audience is using that browser, you&amp;#8217;ll get a very high number out of the equation; you should probably use the IE7 script. But if you only spend a little time developing for IE6 and a significant portion of you audience are still using that browser, you&amp;#8217;ll get a very small value for &lt;kbd&gt;p&lt;/kbd&gt;; you might as well write an IE6-specific stylesheet.&lt;/p&gt;

	&lt;p&gt;Of course this equation is somewhat disingenuous. While it&amp;#8217;s entirely possible to research the percentage of your audience still using IE6, it&amp;#8217;s not so easy to figure out how much of your development time will be spent developing for that one browser. You can&amp;#8217;t really know until you&amp;#8217;ve already done the development, by which time the equation is irrelevant.&lt;/p&gt;

	&lt;p&gt;Instead of using the equation, you could try imposing a limit on how long you will spend developing for IE6. Get your site working in standards-compliant browsers first, then give yourself a time limit to get it working in IE6. If you can&amp;#8217;t solve all the issues in that time limit, switch over to using Dean&amp;#8217;s script. You could even make the time limit directly proportional to the percentage of your audience using IE6. If 20% of your audience is still using IE6 and you&amp;#8217;ve just spent five days getting the site working in standards-compliant browsers, give yourself one day to get it working in IE6. But if 50% of your audience is still using IE6, be prepared to spend 2.5 days wrestling with your nemesis.&lt;/p&gt;

	&lt;p&gt;All of these different methods for dealing with IE6 demonstrate that there&amp;#8217;s no one single answer that works for everyone. They also highlight a problem with the current debate around dealing with IE6. There&amp;#8217;s no shortage of blog posts, articles and even &lt;a href="http://iedeathmarch.org/"&gt;entire websites&lt;/a&gt; discussing when to drop support for IE6. But very few of them take the time to &lt;a href="http://jeffcroft.com/blog/2008/sep/30/when-can-we-stop-talking-about-supporting-browsers/"&gt;define what they mean&lt;/a&gt; by &amp;#8220;support.&amp;#8221; This isn&amp;#8217;t a binary issue. There is no Boolean answer. Instead, there&amp;#8217;s a sliding scale of support:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Block IE6 users from your site.&lt;/li&gt;
		&lt;li&gt;Develop with web standards and don&amp;#8217;t spend any development time testing in IE6.&lt;/li&gt;
		&lt;li&gt;Use the Dean Edwards IE7 script to bootstrap &lt;span class="caps"&gt;CSS&lt;/span&gt; support in IE6.&lt;/li&gt;
		&lt;li&gt;Write an IE6 stylesheet to address layout issues.&lt;/li&gt;
		&lt;li&gt;Make your site look exactly the same in IE6 as in any other browser.&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;Each end of that scale is extreme. I don&amp;#8217;t think that anybody should be actively blocking any browser but neither do I think that users of an outdated browser should get exactly the same experience as users of a more modern browser. The real meanings of &amp;#8220;supporting&amp;#8221; or &amp;#8220;not supporting&amp;#8221; IE6 lie somewhere in-between those extremes.&lt;/p&gt;

	&lt;p&gt;Just as I think that semantics are important in markup, they are equally important in our discussion of web development. So let&amp;#8217;s try to come up with some better terms than using the catch-all verb &amp;#8220;support.&amp;#8221; If you say in your client contract that you &amp;#8220;support&amp;#8221; IE6, define exactly what that means. If you find yourself in a discussion about &amp;#8220;dropping support&amp;#8221; for IE6, take the time to explain what you think that entails.&lt;/p&gt;

	&lt;p&gt;The web developers at Yahoo! are on the right track with their concept of &lt;a href="http://developer.yahoo.com/yui/articles/gbs/"&gt;graded browser support&lt;/a&gt;. I&amp;#8217;m interested in hearing more ideas of how to frame this discussion. If we can all agree to use clear and precise language, we stand a better chance of defeating our nemesis.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=aMWCaJnINhY:AN14U6rDRnw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=aMWCaJnINhY:AN14U6rDRnw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=aMWCaJnINhY:AN14U6rDRnw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=aMWCaJnINhY:AN14U6rDRnw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=aMWCaJnINhY:AN14U6rDRnw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/aMWCaJnINhY" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://adactio.com/"&gt;Jeremy Keith&lt;/a&gt; does the maths and presents an interesting equation to help you to decide when to put the effort into providing support for Internet Explorer 6, and when to fall back on pre-existing shortcuts. Browser support is always a tricky business, so why not roll in some complex algebra too?&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/the-ie6-equation</feedburner:origLink></entry>
<entry>
		<author>
			<name>Henriette Weber</name>
		</author>
		<published>2008-12-07T00:00:08Z</published>
		<updated>2008-12-07T00:00:08Z</updated>
		<title type="html">How To Create Rockband'ism </title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/vZbfd7jhq9A/how-to-create-rockbandism" />
		<id>tag:24ways.org,2008-12-06:7e1577ceca7ea22e28af5c35ee62927a/8dde7a0bc77add5ce7f64399ce141c95</id>
		<category term="craft" />
		
		<content type="html">
&lt;p&gt;There are mysteries happening in the world of business these days. We want something else by now. The business of business has to become more than business. We want to be able to identify ourselves with the brands we purchase and we want them to do good things. We want to feel cool because we buy stuff, and we don&amp;#8217;t just want a shopping experience &amp;#8211; we want an engagement with a company we can relate to.&lt;/p&gt;

	&lt;p&gt;Let me get back to &amp;#8220;feeling cool&amp;#8221; &amp;#8211; if we want to feel cool, we might get the companies we buy from to support that. That&amp;#8217;s why I am on a mission to make companies into rockbands.&lt;/p&gt;

	&lt;p&gt;Now when I say rockbands &amp;#8211; I don&amp;#8217;t mean the puke-y, drunky, nasty stuff that some people would highlight is also a part of rockbands. Therefore I have created my own word &amp;#8220;rockband&amp;#8217;ism&amp;#8221;. This word is the definition of a childhood dream version of being in a rockband &amp;#8211; the feeling of being more respected and loved and cool, than a cockroach or a suit on the floor of a company.&lt;/p&gt;

	&lt;h3&gt;Rockband&amp;#8217;ism&lt;/h3&gt;

	&lt;p&gt;Rockband&amp;#8217;ism is what we aspire to, to feel cool and happy.&lt;/p&gt;

	&lt;p&gt;So basically what I am arguing is that companies should look upon themselves as rockbands. Because the world has changed, so business needs to change as well.&lt;/p&gt;

	&lt;p&gt;I have listed a couple of things you could do today to become a rockband, as a person or as a company.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt; &amp;#8211; Give your support to companies that make a difference to their surroundings &amp;#8211; if you are buying electronics look up what the electronic producers are doing of good in the world (check out the Greenpeace Guide to Greener Electronics).&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt; &amp;#8211; Implement good karma in your everyday life (and do well by doing good). What you give out you get back at some point in some shape &amp;#8211; this can also be implemented for business.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt; &amp;#8211; &lt;span class="caps"&gt;WWRD&lt;/span&gt;? &amp;#8211; &amp;#8220;what would a rockband do&amp;#8221;? or if you are into Kenny Rogers &amp;#8211; what would he do in any given situation? This will also show yourself where your business or personal integrity lies because you actually act as a person or a rockband you admire.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt; &amp;#8211; Start leading instead of managing &amp;#8211; If we can measure stuff why should we manage it? Leadership is key here instead of management. When you lead you tell people how to reach the stars, when you manage you keep them on the ground.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;5&lt;/strong&gt; &amp;#8211; Respect and confide in, that people are the best at what they do. If they aren&amp;#8217;t, they won&amp;#8217;t be around for long. If they are and you keep on buggin&amp;#8217; them, they won&amp;#8217;t be around for long either.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;6&lt;/strong&gt; &amp;#8211; Don&amp;#8217;t be arrogant &amp;#8211; Because audiences can&amp;#8217;t stand it &amp;#8211; talk to people as a person not as a company.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;7&lt;/strong&gt; &amp;#8211; Focus on your return on involvement &amp;#8211; know that you get a return on, what you involve yourself in. No matter if it&amp;#8217;s bingo, communities, talks, ornithology or un-conferences.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;8&lt;/strong&gt; &amp;#8211; Find out where you can make a difference and do it. Don&amp;#8217;t leave it up to everybody else to save the world.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;9&lt;/strong&gt; &amp;#8211; Find out what you can do to become an authentic, trustworthy and remarkable company. Maybe you could even think about this a lot and make these thoughts into an actionplan.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;10&lt;/strong&gt; &amp;#8211; Last but not least &amp;#8211; if you&amp;#8217;re not happy &amp;#8211; do something else, become another type of rockband, maybe a soloist of a sort, or an orchestra.&lt;/p&gt;

	&lt;h3&gt;No more business as usual&lt;/h3&gt;

	&lt;p&gt;This really isn&amp;#8217;t time for more business as usual, our environment (digital, natural, work or any other kind of environment) is changing. You are going to have to change too.&lt;/p&gt;

	&lt;p&gt;This article actually sprang from a talk I did at the Shift08 conference in Lisbon in October. In addition to this article for 24 ways I have turned the talk into an &lt;a href="http://www.toothlesstigerpress.com/rockbands"&gt;eBook&lt;/a&gt; that you can get on Toothless Tiger Press for free.&lt;/p&gt;

	&lt;p&gt;May you all have a sustainable and great Christmas full of great moments with your loved ones. December is a month for gratitude, enjoyment and love.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=vZbfd7jhq9A:7bUJMXZFJWs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=vZbfd7jhq9A:7bUJMXZFJWs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=vZbfd7jhq9A:7bUJMXZFJWs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=vZbfd7jhq9A:7bUJMXZFJWs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=vZbfd7jhq9A:7bUJMXZFJWs:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/vZbfd7jhq9A" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://www.toothlesstigerpress.com/rockbands"&gt;Henriette Weber&lt;/a&gt; argues that there&amp;#8217;s no more time for &amp;#8216;business as usual&amp;#8217;. Instead it&amp;#8217;s time to turn your company into a rockband and take it on tour. It&amp;#8217;s Sunday, so kick back with some tea and toast, put the newspaper to one side and ponder something a little different.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/how-to-create-rockbandism</feedburner:origLink></entry>
<entry>
		<author>
			<name>Matt Riggott</name>
		</author>
		<published>2008-12-06T00:01:06Z</published>
		<updated>2008-12-06T00:01:06Z</updated>
		<title type="html">Using Google App Engine as Your Own Content Delivery Network</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/y5slD2qkvyg/using-google-app-engine-as-your-own-cdn" />
		<id>tag:24ways.org,2008-12-05:7e1577ceca7ea22e28af5c35ee62927a/a1db24dfab01bfdfe7c771970d283975</id>
		<category term="performance" />
		
		<content type="html">
&lt;p&gt;Do you remember, years ago, when hosting was expensive, domain names were the province of the rich, and you hosted your web pages on Geocities? It seems odd to me now that there was a time when each and every geek didn&amp;#8217;t have his own top-level domain and super hosting setup. But as the parts became more and more affordable a man could become an outcast if he didn&amp;#8217;t have his own slightly surreal-sounding &lt;abbr title="Top-level domain"&gt;&lt;span class="caps"&gt;TLD&lt;/span&gt;&lt;/abbr&gt;.&lt;/p&gt;

	&lt;p&gt;And so it will be in the future when people realise with surprise there was a time before affordable content delivery networks.&lt;/p&gt;

	&lt;p&gt;A content delivery network, or &lt;abbr title="Content delivery network"&gt;&lt;span class="caps"&gt;CDN&lt;/span&gt;&lt;/abbr&gt;, is a system of servers spread around the world, serving files from the nearest physical location. Instead of waiting for a file to find its way from a server farm in Silicon Valley 8,000 kilometres away, I can receive it from London, Dublin, or Paris, cutting down the time I wait. The big names — Google, Yahoo, Amazon, et al — use &lt;abbr title="Content delivery networks"&gt;&lt;span class="caps"&gt;CDN&lt;/span&gt;s&lt;/abbr&gt; for their sites, but they&amp;#8217;ve always been far too expensive for us mere mortals. Until now.&lt;/p&gt;

	&lt;p&gt;There&amp;#8217;s a service out there ready for you to use as your very own &lt;abbr title="Content delivery network"&gt;&lt;span class="caps"&gt;CDN&lt;/span&gt;&lt;/abbr&gt;. You have the company&amp;#8217;s blessing, you won&amp;#8217;t need to write a line of code, and — best of all — it&amp;#8217;s free. The name? &lt;a href="http://appengine.google.com/" title="Google App Engine"&gt;Google App Engine&lt;/a&gt;.&lt;/p&gt;

	&lt;p&gt;In this article you&amp;#8217;ll find out how to set up a &lt;abbr title="Content delivery network"&gt;&lt;span class="caps"&gt;CDN&lt;/span&gt;&lt;/abbr&gt; on Google App Engine. You&amp;#8217;ll get the development software running on your own computer, tell App Engine what files to serve, upload them to a web site, and give everyone round the world access to them.&lt;/p&gt;

	&lt;h3&gt;Creating your first Google App Engine project&lt;/h3&gt;

	&lt;p&gt;Before we do anything else, you&amp;#8217;ll need to &lt;a href="http://code.google.com/appengine/downloads.html" title="Google's instructions on downloading the App Engine SDK"&gt;download the Google App Engine software development kit&lt;/a&gt; (&lt;abbr title="Software development kit"&gt;&lt;span class="caps"&gt;SDK&lt;/span&gt;&lt;/abbr&gt;). You&amp;#8217;ll need Python 2.5 too — you won&amp;#8217;t be writing any Python code but the App Engine &lt;abbr title="Software development kit"&gt;&lt;span class="caps"&gt;SDK&lt;/span&gt;&lt;/abbr&gt; will need it to run on your computer. If you don&amp;#8217;t have Python, App Engine will install it for you (if you use Mac OS X 10.5 or a Linux-based &lt;abbr title="Operating system"&gt;OS&lt;/abbr&gt; you&amp;#8217;ll have Python; if you use Windows you won&amp;#8217;t).&lt;/p&gt;

	&lt;p&gt;Done that? Excellent, because that&amp;#8217;s the hardest step. The rest is plain sailing.&lt;/p&gt;

	&lt;p&gt;You&amp;#8217;ll need to choose a unique &amp;#8216;application id&amp;#8217; — nothing more than a name — for your project. Make sure it consists only of lowercase letters and numbers. For this article I&amp;#8217;ll use &lt;code&gt;24ways2008&lt;/code&gt;, but you can choose anything you like.&lt;/p&gt;

	&lt;p&gt;On your computer, create a folder named after your application id. This folder can be anywhere you want: your desktop, your documents folder, or wherever you usually keep your web files. Within your new folder, create a folder called &lt;code&gt;assets&lt;/code&gt;, and within that folder create three folders called &lt;code&gt;images&lt;/code&gt;, &lt;code&gt;css&lt;/code&gt;, and &lt;code&gt;javascript&lt;/code&gt;. These three folders are the ones you&amp;#8217;ll fill with files and serve from your content delivery network. You can have other folders too, if you like.&lt;/p&gt;

	&lt;p&gt;That will leave you with a folder structure like this:&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;24ways2008/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;assets/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;css/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;images/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;javascript/&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Now you need to put a few files in these folders, so we can later see our &lt;abbr title="Content delivery network"&gt;&lt;span class="caps"&gt;CDN&lt;/span&gt;&lt;/abbr&gt; in action. You can put anything you want in these folders, but for this example we&amp;#8217;ll include an &lt;abbr title="Hypertext Markup Language"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/abbr&gt; file, a style sheet, an image, and a Javascript library.&lt;/p&gt;

	&lt;p&gt;In the top-level folder (the one I&amp;#8217;ve called &lt;code&gt;24ways2008&lt;/code&gt;), create a file called &lt;code&gt;index.html&lt;/code&gt;. Fill this with any content you want. In the &lt;code&gt;assets/css&lt;/code&gt; folder, create a file named &lt;code&gt;core.css&lt;/code&gt; and throw in a couple of &lt;abbr title="Cascading Style Sheets"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/abbr&gt; rules for good measure. In the &lt;code&gt;assets/images&lt;/code&gt; directory save any image that takes your fancy — I&amp;#8217;ve used the &lt;a href="http://code.google.com/appengine/images/appengine-silver-120x30.gif" title="'Powered by Google App Engine' image"&gt;silver badge from the App Engine download page&lt;/a&gt;. Finally, to fill the JavaScript folder, add in this &lt;a href="http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.2.6.min.js" title="Instructions on downloading the jQuery javascript library"&gt;jQuery library file&lt;/a&gt;. If you&amp;#8217;ve got the time and the inclination, you can build a page that uses all these elements.&lt;/p&gt;

	&lt;p&gt;So now we should have a set of files and folders that look something like this:&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;24ways2008/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;assets/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;index.html&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;css/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;core.css&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;images/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;appengine-silver-120x30.gif&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;javascript/&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;jquery-1.2.6.min.js&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Which leaves us with one last file to create. This is the important one: it tells App Engine what to do with your files. It&amp;#8217;s named &lt;code&gt;app.yaml&lt;/code&gt;, it sits at the top-level (inside the folder I&amp;#8217;ve named &lt;code&gt;24ways2008&lt;/code&gt;), and it needs to include these lines:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;application: 24ways2008&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;version: 1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;runtime: python&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;api_version: 1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;handlers:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;- url: /&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;static_files: assets/index.html&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;upload: assets/index.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;- url: /&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;static_dir: assets&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/using-google-app-engine-as-your-own-cdn/3.txt" title="Download the above code as a textfile"&gt;/code/using-google-app-engine-as-your-own-cdn/3.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;You need to make sure you change &lt;code&gt;24ways2008&lt;/code&gt; on the first line to whatever you chose as your application id, but otherwise the content of your &lt;code&gt;app.yaml&lt;/code&gt; file should be identical. And with that, you&amp;#8217;ve created your first App Engine project. If you want it, you can &lt;a href="http://24ways2008.appspot.com/project.zip" title="Zip file containing my App Engine project files"&gt;download a zip file containing my project&lt;/a&gt;.&lt;/p&gt;

	&lt;h3&gt;Testing your project&lt;/h3&gt;

	&lt;p&gt;As it stands, your project is ready to be uploaded to App Engine. But we couldn&amp;#8217;t call ourselves professionals if we didn&amp;#8217;t test it, could we? So, let&amp;#8217;s put that downloaded &lt;abbr title="Software development kit"&gt;&lt;span class="caps"&gt;SDK&lt;/span&gt;&lt;/abbr&gt; to good use and run the project from your own computer.&lt;/p&gt;

	&lt;p&gt;One of the files you&amp;#8217;ll find App Engine installed is named &lt;code&gt;dev_appserver.py&lt;/code&gt;, a Python script used to simulate App Engine on your computer. You&amp;#8217;ll find lots of information on how to do this in the &lt;a href="http://code.google.com/appengine/docs/thedevwebserver.html" title="Google's documentation on the App Engine development web server"&gt;documentation on the development web server&lt;/a&gt;, but it boils down to running the script like so (the space and the dot at the end are important):&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;dev_appserver.py .&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;You&amp;#8217;ll need to run this from the command-line: Mac users can run the Terminal application, Linux users can run their favourite shell, and Windows users will need to run it via the Command Prompt (open the Start menu, choose &amp;#8216;Run…&amp;#8217;, type &amp;#8216;&lt;kbd&gt;cmd&lt;/kbd&gt;&amp;#8216;, and click &amp;#8216;OK&amp;#8217;). Before you run the script you&amp;#8217;ll need to make sure you&amp;#8217;re in the project folder — in my case, as I saved it to my desktop I can go there by typing &lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;cd ~/Desktop/24ways2008&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;in my Mac&amp;#8217;s Terminal app; if you&amp;#8217;re using Windows you can type &lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;cd &amp;quot;C:\Documents and Settings\username\Desktop\24ways2008&amp;quot;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;If that&amp;#8217;s successful, you&amp;#8217;ll see a few lines of output, the last looking something like this:&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;INFO     2008-11-22 14:35:00,830 dev_appserver_main.py] Running application 24ways2008 on port 8080: http://localhost:8080&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Now you can power up your favourite browser, point it to &lt;a href="http://localhost:8080/"&gt;&lt;code&gt;http://localhost:8080/&lt;/code&gt;&lt;/a&gt;, and you&amp;#8217;ll see the page you saved as &lt;code&gt;index.html&lt;/code&gt;. You&amp;#8217;ll also find your &lt;abbr title="Cascading Style Sheets"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/abbr&gt; file at &lt;a href="http://localhost:8080/css/core.css"&gt;&lt;code&gt;http://localhost:8080/css/core.css&lt;/code&gt;&lt;/a&gt;. In fact, anything you put inside the assets folder in the project will be accessible from this domain. You&amp;#8217;re running our own App Engine web server!&lt;/p&gt;

	&lt;p&gt;Note that no-one else will be able to see your files: &lt;code&gt;localhost&lt;/code&gt; is a special domain that you can only see from your computer — and once you stop the development server (by pressing &lt;kbd&gt;Control–C&lt;/kbd&gt;) you&amp;#8217;ll not be able to see the files in your browser until you start it again.&lt;/p&gt;

	&lt;p&gt;You might notice a new file has turned up in your project: &lt;code&gt;index.yaml&lt;/code&gt;. App Engine creates this file when you run the development server, and it&amp;#8217;s for internal App Engine use only. If you delete it there are no ill effects, but it will reappear when you next run the development server. If you&amp;#8217;re using version control (e.g. Subversion) there&amp;#8217;s no need to keep a copy in your repository.&lt;/p&gt;

	&lt;p&gt;So you&amp;#8217;ve tested your project and you&amp;#8217;ve seen it working on your own machine; now all you need to do is upload your project and the world will be able to see your files too.&lt;/p&gt;

	&lt;h3&gt;Uploading your project&lt;/h3&gt;

	&lt;p&gt;If you don&amp;#8217;t have a Google account, &lt;a href="https://www.google.com/accounts/" title="Create a Google account"&gt;create one&lt;/a&gt; and then &lt;a href="http://appengine.google.com/" title="Sign in to Google App Engine"&gt;sign in to App Engine&lt;/a&gt;. Tell Google about your new project by clicking on the &amp;#8216;Create an Application&amp;#8217; button. Enter your application id, give the application a name, and agree to the terms and conditions. That&amp;#8217;s it. All we need do now is upload the files.&lt;/p&gt;

	&lt;p&gt;Open your Mac OS X Terminal, Windows Command Prompt, or Linux shell window again, move to the project folder, and type (again, the space and the dot at the end are important):&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;appcfg.py update .&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Enter your email address and password when prompted, and let App Engine do it&amp;#8217;s thing. It&amp;#8217;ll take no more than a few seconds, but in that time App Engine will have done the equivalent of logging in to an &lt;abbr title="File Transfer Protocol"&gt;&lt;span class="caps"&gt;FTP&lt;/span&gt;&lt;/abbr&gt; server and copying files across. It&amp;#8217;s fairly understated, but you now have your own project up and running. You can see mine at &lt;a href="http://24ways2008.appspot.com/"&gt;http://24ways2008.appspot.com/&lt;/a&gt;, and everyone can see yours at &lt;code&gt;http://your-application-id.appspot.com/&lt;/code&gt;. Your files are being served up over Google&amp;#8217;s content delivery network, at no cost to you!&lt;/p&gt;

	&lt;h3&gt;Benefits of using Google App Engine&lt;/h3&gt;

	&lt;p&gt;The benefits of App Engine as a &lt;abbr title="Content delivery network"&gt;&lt;span class="caps"&gt;CDN&lt;/span&gt;&lt;/abbr&gt; are obvious: your own server doesn&amp;#8217;t suck up the bandwidth, while your visitors will appreciate a faster site. But there are also less obvious benefits.&lt;/p&gt;

	&lt;p&gt;First, once you&amp;#8217;ve set up your site, updating it is an absolute breeze. Each time you update a file (or a batch of files) you need only run &lt;code&gt;appcfg.py&lt;/code&gt; to see the changes appear on your site. To &lt;a href="http://www.joelonsoftware.com/articles/fog0000000043.html" title="The Joel test: twelve steps to better code"&gt;paraphrase Joel Spolsky&lt;/a&gt;, a good web site must be able to be updated in a single step. Many designers and developers can&amp;#8217;t make that claim, but with App Engine, &lt;em&gt;you&lt;/em&gt; can.&lt;/p&gt;

	&lt;p&gt;App Engine also allows multiple people to work on one application. If you want a friend to be able to upload files to your site you can let him do so without giving him usernames and passwords — all he needs is his own Google account. App Engine also gives you a log of all actions taken by collaborators, so you can &lt;a href="http://googleappengine.blogspot.com/2008/10/new-admin-console-release.html" title="Google App Engine's admin logs"&gt;see who&amp;#8217;s made updates&lt;/a&gt;, and when.&lt;/p&gt;

	&lt;p&gt;Another bonus is the simple version control App Engine offers. Do you remember the file named &lt;code&gt;app.yaml&lt;/code&gt; you created a while back? The second line looked like this:&lt;/p&gt;

 &lt;ol class="code numberless"&gt;
&lt;li&gt;&lt;code&gt;version: 1&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;If you change the version number to 2 (or 3, or 4, etc), App Engine will keep a copy of the last version you uploaded. If anything goes wrong with your latest version, you can tell App Engine to revert back to that last saved version. It&amp;#8217;s no proper version control system, but it could get you out of a sticky situation.&lt;/p&gt;

	&lt;p&gt;One last thing to note: if you&amp;#8217;re not happy using &lt;code&gt;your-application-id.appspot.com&lt;/code&gt; as your domain, &lt;a href="http://code.google.com/appengine/articles/domains.html" title="Deploying your App Engine application on your own domain"&gt;App Engine will quite happily use any domain you own&lt;/a&gt;.&lt;/p&gt;

	&lt;h3&gt;The weak points of Google App Engine&lt;/h3&gt;

	&lt;p&gt;In the right circumstances, App Engine can be a real boon. I run &lt;a href="http://www.flother.com/"&gt;my own site&lt;/a&gt; using the method I&amp;#8217;ve discussed above, and I&amp;#8217;m very happy with it. But App Engine does have its disadvantages, most notably those discussed by Aral Balkan in his post &amp;#8216;&lt;a href="http://aralbalkan.com/1504" title="Aral Balkan on the shortcomings of Google App Engine"&gt;Why Google App Engine is broken and what Google must do to fix it&lt;/a&gt;&amp;#8216;.&lt;/p&gt;

	&lt;p&gt;Aral found the biggest problems while using App Engine as a web application platform; I wouldn&amp;#8217;t recommend using it as such either (at least for now) but for our purposes as a &lt;abbr title="Content delivery network"&gt;&lt;span class="caps"&gt;CDN&lt;/span&gt;&lt;/abbr&gt; for static files, it&amp;#8217;s much more worthy. Still, App Engine has two shortcomings you should be aware of.&lt;/p&gt;

	&lt;p&gt;The first is that you can&amp;#8217;t host a file larger than one megabyte. If you want to use App Engine to host that 4.3&lt;abbr title="Megabyte"&gt;MB&lt;/abbr&gt; download for your latest-and-greatest desktop software, you&amp;#8217;re out of luck. The only solution is to stick to smaller files.&lt;/p&gt;

	&lt;p&gt;The second problem is the quota system. &lt;a href="http://code.google.com/appengine/articles/quotas.html" title="Understanding App Engine's application quotas"&gt;Google&amp;#8217;s own documentation&lt;/a&gt; says you&amp;#8217;re allowed 650,000 requests a day and 10,000 megabytes of bandwidth in and out (20,000 megabytes in total), which should be plenty for most sites. But people have seen sites shut down temporarily for breaching quotas — in some cases after inexplicable jumps in Google&amp;#8217;s server &lt;abbr title="Central processing unit"&gt;&lt;span class="caps"&gt;CPU&lt;/span&gt;&lt;/abbr&gt; usage. Aral, who&amp;#8217;s seen it happen to his own sites, seemed genuinely frustrated by this, and if you measure your hits in the hundreds of thousands and don&amp;#8217;t want to worry about uptime, App Engine isn&amp;#8217;t for you.&lt;/p&gt;

	&lt;p&gt;That said, for most of us, App Engine offers a fantastic resource: the ability to host files on Google&amp;#8217;s own content delivery network, at no charge.&lt;/p&gt;

	&lt;h3&gt;Conclusion&lt;/h3&gt;

	&lt;p&gt;If you&amp;#8217;ve come this far, you&amp;#8217;ve seen how to create a Google App Engine project and host your own files on Google&amp;#8217;s &lt;abbr title="Content delivery network"&gt;&lt;span class="caps"&gt;CDN&lt;/span&gt;&lt;/abbr&gt;. You&amp;#8217;ve seen the great advantages App Engine offers — an excellent content delivery network, the ability to update your site with a single command, multiple authors, simple version control, and the use of your own domain — and you&amp;#8217;ve come across some of its weaknesses — most importantly the limit on file sizes and the quota system. All that&amp;#8217;s left to do is upload those applications — but not before you&amp;#8217;ve finished your Christmas shopping.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=y5slD2qkvyg:Gy3Vhp--_8E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=y5slD2qkvyg:Gy3Vhp--_8E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=y5slD2qkvyg:Gy3Vhp--_8E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=y5slD2qkvyg:Gy3Vhp--_8E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=y5slD2qkvyg:Gy3Vhp--_8E:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/y5slD2qkvyg" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://www.flother.com/"&gt;Matt Riggott&lt;/a&gt; demonstrates how to use Google App Engine as a &lt;span class="caps"&gt;CDN&lt;/span&gt; for serving your site&amp;#8217;s images, &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScript files from a location close to your users. Find out how using this free service from Google could be just the performance kick your site needs.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/using-google-app-engine-as-your-own-cdn</feedburner:origLink></entry>
<entry>
		<author>
			<name>Mark Boulton</name>
		</author>
		<published>2008-12-05T00:00:05Z</published>
		<updated>2008-12-05T00:00:05Z</updated>
		<title type="html">Art Directing with Looking Room</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/LH3DZwdNhxA/art-directing-with-looking-room" />
		<id>tag:24ways.org,2008-12-04:7e1577ceca7ea22e28af5c35ee62927a/0129301a4eab1423794c627a5857fdfa</id>
		<category term="design" />
		
		<content type="html">
&lt;h4&gt;Using photographic composition techniques to start to art direct on the template-driven web.&lt;/h4&gt;

	&lt;p&gt;Think back to last night. There you are, settled down in front of the TV, watching your favourite soap opera, with nice hot cup of tea in hand. Did you notice &amp;#8211; whilst engrossed in the latest love-triangle &amp;#8211; that the cameraman has worked very hard to support your eye&amp;#8217;s natural movement on-screen? He&amp;#8217;s carefully framed individual shots to create balance.&lt;/p&gt;

	&lt;p&gt;Think back to last week. There you were, sat with your mates watching the big match. Did you notice that the cameraman frames the shot to go with the direction of play? A player moving right will always be framed so that he is on the far left, with plenty of &amp;#8216;room&amp;#8217; to run into.&lt;/p&gt;

	&lt;p&gt;Both of these cameramen use a technique called Looking Room, sometimes called Lead Room. Looking Room is the space between the subject (be it a football, or a face), and the edge of the screen. Specifically, Looking Room is the negative space on the side the subject is looking or moving. The great thing is, it&amp;#8217;s not just limited to photography, film or television; we can use it in web design too.&lt;/p&gt;

	&lt;h3&gt;Basic Framing&lt;/h3&gt;

	&lt;p&gt;Before we get into Looking Room, and how it applies to web, we need to have a look at some basics of photographic composition.&lt;/p&gt;

	&lt;p&gt;Many web sites use imagery, or photographs, to enhance the content. But even with professionally shot photographs, without a basic understanding of framing or composition, you can damage how the image is perceived. &lt;/p&gt;

	&lt;p&gt;A simple, easy way to make photographs more interesting is to fill the frame. &lt;/p&gt;

	&lt;p&gt;Take this rather mundane photograph of a horse:&lt;/p&gt;

	&lt;p class="image"&gt;&lt;a href="http://flickr.com/photos/mikepedroncelli/114987037/"&gt;&lt;img src="http://media.24ways.org/2008/05/1_horse.jpg" width="700" height="525" alt="Horse" /&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;A typical point and click affair. But, we can work with this.&lt;/p&gt;

	&lt;p&gt;By closely cropping, and filling the frame, we can instantly change the mood of the shot.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;a href="http://flickr.com/photos/mikepedroncelli/114987037/"&gt;&lt;img src="http://media.24ways.org/2008/05/2_horsecropped.jpg" width="700" height="486" alt="cropped image of a horse" /&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;I&amp;#8217;ve also added Looking Room on the right of the horse. This is space that the horse would be walking into. It gives the photograph movement.&lt;/p&gt;

	&lt;h3&gt;Subject, Space, and Movement&lt;/h3&gt;

	&lt;p&gt;Generally speaking, a portrait photograph will have a subject and space around them. Visual interest in portrait photography can come from movement; how the eye moves around the shot. To get the eye moving, the photographer modifies the space around the subject.&lt;/p&gt;

	&lt;p&gt;Look at this portrait:&lt;/p&gt;

	&lt;p class="image"&gt;&lt;a href="http://flickr.com/photos/laenulfean/548688957/"&gt;&lt;img src="http://media.24ways.org/2008/05/3_portrait.jpg" width="700" height="509" alt="Portrait" /&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;The photography has framed the subject on the right, allowing for whitespace, or Looking Room, in the direction the subject is looking. The framing of the subject (1), with the space to the left (2) &amp;#8211; the Looking Room &amp;#8211; creates movement, shown by the arrow (3).&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/05/4_annotatedportrait.gif" width="700" height="509" alt="Annotated portrait" /&gt;&lt;/p&gt;

	&lt;p&gt;Note the subject is not framed centrally (shown by the lighter dotted line).&lt;/p&gt;

	&lt;p&gt;If the photographer had framed the subject with equal space either side, the resulting composition is static, like our horse.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/05/5_centredportrait.gif" width="700" height="509" alt="Centred portrait" /&gt;&lt;/p&gt;

	&lt;p&gt;If the photographer framed the subject way over on the left, as she is looking that way, the resulting whitespace on the right leads a very uncomfortable composition.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/05/6_leftportrait.gif" width="700" height="509" alt="Left portrait" /&gt;&lt;/p&gt;

	&lt;p&gt;The root of this discomfort is what the framing is telling our eye to do. The subject, looking to the left, suggests to us that we should do the same. However, the Looking Room on the right is telling our eye to occupy this space. The result is a confusing back and forth.&lt;/p&gt;

	&lt;h3&gt;How Looking Room applies to the web&lt;/h3&gt;

	&lt;p&gt;We can apply the same theory to laying out a web page or application. Taking the three same elements &amp;#8211; Subject, Space, and resulting Movement &amp;#8211; we can guide a user&amp;#8217;s eye to the elements we need to. As designers, or content editors, framing photographs correctly can have a subtle but important effect on how a page is visually scanned. Take this example:&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/05/7_bbchome.jpg" width="699" height="397" alt="BBC home" /&gt;&lt;/p&gt;

	&lt;p&gt;The &lt;a href="http://www.bbc.co.uk"&gt;&lt;span class="caps"&gt;BBC&lt;/span&gt;&lt;/a&gt; homepage uses great photography as a way of promoting content. Here, they have cropped the main photograph to guide the user&amp;#8217;s eye into the content. &lt;/p&gt;

	&lt;p&gt;By applying the same theory, the designer or content editor has applied considerable Looking Room (2) to the photograph to create balance with the overall page design, but also to create movement of the user&amp;#8217;s eye toward the content (1)&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/05/8_bbchome2.jpg" width="699" height="397" alt="BBC home 2" /&gt;&lt;/p&gt;

	&lt;p&gt;If the image was flipped horizontally. The Looking Room is now on the right. The subject of the photograph is looking off the page, drawing the user&amp;#8217;s eye away from the content. Once again, this results in a confusing back and forth as your eye fights its way over to the left of the page.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/05/9_bbchome3.jpg" width="699" height="397" alt="BBC home 3" /&gt;&lt;/p&gt;

	&lt;h3&gt;A little bit of Art Direction&lt;/h3&gt;

	&lt;p&gt;Art Direction can be described as the act or process of managing the visual presentation of content. Art Direction is difficult to do on the web, because content and presentation are, more often than not, separated. But where there are images, and when we know the templates that those images will populate, we can go a little way to bridging the gap between content and presentation.&lt;/p&gt;

	&lt;p&gt;By understanding the value of framing and Looking Room, and the fact that it extends beyond just a good looking photograph, we can start to see photography playing more of an integral role in the communication of content. &lt;/p&gt;

	&lt;p&gt;We won&amp;#8217;t just be populating templates. We&amp;#8217;ll be art directing.&lt;/p&gt;

	&lt;h4&gt;Photo credits: &lt;/h4&gt;

	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://flickr.com/photos/laenulfean/548688957/"&gt;Portrait&lt;/a&gt; by Carsten Tolkmit&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://flickr.com/photos/mikepedroncelli/114987037/"&gt;Horse&lt;/a&gt; by Mike Pedroncelli&lt;/li&gt;
	&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=LH3DZwdNhxA:iFtUm9SzEfs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=LH3DZwdNhxA:iFtUm9SzEfs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=LH3DZwdNhxA:iFtUm9SzEfs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=LH3DZwdNhxA:iFtUm9SzEfs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=LH3DZwdNhxA:iFtUm9SzEfs:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/LH3DZwdNhxA" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://www.markboulton.co.uk/"&gt;Mark Boulton&lt;/a&gt; borrows some techniques from photographic composition to give an insight into how art direction can be conducted on the web. Learn how we can begin to bridge the gap between template-driven pages and content that really communicates.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/art-directing-with-looking-room</feedburner:origLink></entry>
<entry>
		<author>
			<name>Christian Heilmann</name>
		</author>
		<published>2008-12-04T00:00:09Z</published>
		<updated>2008-12-04T00:00:09Z</updated>
		<title type="html">Sitewide Search On A Shoe String</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/TdZ4-RcA4ts/sitewide-search-on-a-shoestring" />
		<id>tag:24ways.org,2008-12-03:7e1577ceca7ea22e28af5c35ee62927a/649426037fdf90cca227ecd4522fe690</id>
		<category term="apis" />
		<category term="javascript" />
		<content type="html">
&lt;p&gt;One of the questions I got a lot when I was building web sites for smaller businesses was if I could create a search engine for their site. Visitors should be able to search only this site and find things without the maintainer having to put &amp;#8220;related articles&amp;#8221;  or &amp;#8220;featured content&amp;#8221; links on every page by hand. &lt;/p&gt;

	&lt;p&gt;Back when this was all fields this wasn&amp;#8217;t easy as you either had to write your own scraping tool, use &lt;a href="http://www.htdig.org/"&gt;ht://dig&lt;/a&gt; or a paid service from providers like Yahoo, Altavista or later on Google. In the former case you had to swallow the bitter pill of computing and indexing all your content and storing it in a database for quick access and in the latter it hurt your wallet.&lt;/p&gt;

	&lt;p&gt;Times have moved on and nowadays you can have the same functionality for free using Yahoo&amp;#8217;s &amp;#8220;Build your own search service&amp;#8221; &amp;#8211; &lt;span class="caps"&gt;BOSS&lt;/span&gt;. The cool thing about &lt;span class="caps"&gt;BOSS&lt;/span&gt; is that it allows for a massive amount of hits a day and you can mash up the returned data in any format you want. Another good feature of it is that it comes with &lt;span class="caps"&gt;JSON&lt;/span&gt;-P as an output format which makes it possible to use it without any server-side component!&lt;/p&gt;

	&lt;h3&gt;Starting with a working &lt;span class="caps"&gt;HTML&lt;/span&gt; form&lt;/h3&gt;

	&lt;p&gt;In order to add a search to your site, you start with a simple &lt;span class="caps"&gt;HTML&lt;/span&gt; form which you can use without JavaScript. Most search engines will allow you to filter results by domain. In this case we will search &amp;#8220;bbc.co.uk&amp;#8221;. If you use Yahoo as your standard search, this could be: &lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;form id=&amp;quot;customsearch&amp;quot; action=&amp;quot;http://search.yahoo.com/search&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;label for=&amp;quot;p&amp;quot;&amp;gt;Search this site:&amp;lt;/label&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;p&amp;quot; id=&amp;quot;term&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;vs&amp;quot; id=&amp;quot;site&amp;quot; value=&amp;quot;bbc.co.uk&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;go&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/sitewide-search-on-a-shoestring/1.txt" title="Download the above code as a textfile"&gt;/code/sitewide-search-on-a-shoestring/1.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;The Google equivalent is:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;form id=&amp;quot;customsearch&amp;quot; action=&amp;quot;http://www.google.co.uk/search&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;label for=&amp;quot;p&amp;quot;&amp;gt;Search this site:&amp;lt;/label&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;as_q&amp;quot; id=&amp;quot;term&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;as_sitesearch&amp;quot; id=&amp;quot;site&amp;quot; value=&amp;quot;bbc.co.uk&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;go&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/sitewide-search-on-a-shoestring/2.txt" title="Download the above code as a textfile"&gt;/code/sitewide-search-on-a-shoestring/2.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;In any case make sure to use the ID &lt;code&gt;term&lt;/code&gt; for the search term and &lt;code&gt;site&lt;/code&gt; for the site, as this is what we are going to use for the script. To make things easier, also have an ID called &lt;code&gt;customsearch&lt;/code&gt; on the form.&lt;/p&gt;

	&lt;p&gt;To use &lt;span class="caps"&gt;BOSS&lt;/span&gt;, you should get &lt;a href="https://developer.yahoo.com/wsregapp/"&gt;your own developer &lt;span class="caps"&gt;API&lt;/span&gt; for &lt;span class="caps"&gt;BOSS&lt;/span&gt;&lt;/a&gt; and replace the one in the demo code. There is click tracking on the search results to see how successful your app is, so you should make it your own.&lt;/p&gt;

	&lt;h3&gt;Adding the &lt;span class="caps"&gt;BOSS&lt;/span&gt; magic&lt;/h3&gt;

	&lt;p&gt;&lt;span class="caps"&gt;BOSS&lt;/span&gt; is a &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;, meaning you can use it in any &lt;span class="caps"&gt;HTTP&lt;/span&gt; request or in a browser by simply adding the right parameters to a &lt;span class="caps"&gt;URL&lt;/span&gt;. Say for example you want to search &amp;#8220;bbc.co.uk&amp;#8221; for &amp;#8220;christmas&amp;#8221; all you need to do is open the following &lt;span class="caps"&gt;URL&lt;/span&gt;:&lt;/p&gt;

	&lt;p&gt;&lt;a href="http://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&amp;format=xml&amp;appid=Kzv_lcHV34HIybw0GjVkQNnw4AEXeyJ9Rb1gCZSGxSRNrcif_HdMT9qTE1y9LdI-"&gt;http://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&amp;amp;format=xml&amp;amp;appid=YOUR-&lt;span class="caps"&gt;APPLICATION&lt;/span&gt;-ID&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;Try it out and click it to see the results in &lt;span class="caps"&gt;XML&lt;/span&gt;. We don&amp;#8217;t want &lt;span class="caps"&gt;XML&lt;/span&gt; though, which is why we get rid of the &lt;code&gt;format=xml&lt;/code&gt; parameter which gives us the same information in &lt;span class="caps"&gt;JSON&lt;/span&gt;:&lt;/p&gt;

	&lt;p&gt;&lt;a href="http://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&amp;appid=Kzv_lcHV34HIybw0GjVkQNnw4AEXeyJ9Rb1gCZSGxSRNrcif_HdMT9qTE1y9LdI-"&gt;http://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&amp;amp;appid=YOUR-&lt;span class="caps"&gt;APPLICATION&lt;/span&gt;-ID&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;&lt;span class="caps"&gt;JSON&lt;/span&gt; makes most sense when you can send the output to a function and immediately use it. For this to happen all you need is to add a &lt;code&gt;callback&lt;/code&gt; parameter and the &lt;span class="caps"&gt;JSON&lt;/span&gt; will be wrapped in a function call. Say for example we want to call &lt;code&gt;SITESEARCH.found()&lt;/code&gt; when the data was retrieved we can do it this way:&lt;/p&gt;

	&lt;p&gt;&lt;a href="http://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&amp;callback=SITESEARCH.found&amp;appid=Kzv_lcHV34HIybw0GjVkQNnw4AEXeyJ9Rb1gCZSGxSRNrcif_HdMT9qTE1y9LdI-"&gt;http://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&amp;amp;callback=SITESEARCH.found&amp;amp;appid=YOUR-&lt;span class="caps"&gt;APPLICATION&lt;/span&gt;-ID&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;You can &lt;a href="http://24ways.org/examples/sitewide-search-on-a-shoestring/script-node.html"&gt;use this immediately in a script node&lt;/a&gt; if you want to. The following code would display the total amount of search results for the term &lt;code&gt;christmas&lt;/code&gt; on &lt;code&gt;bbc.co.uk&lt;/code&gt; as an alert:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var SITESEARCH = {};&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;SITESEARCH.found = function(o){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;alert(o.ysearchresponse.totalhits);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&amp;amp;callback=SITESEARCH.found&amp;amp;appid=Kzv_lcHV34HIybw0GjVkQNnw4AEXeyJ9Rb1gCZSGxSRNrcif_HdMT9qTE1y9LdI-&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/sitewide-search-on-a-shoestring/3.txt" title="Download the above code as a textfile"&gt;/code/sitewide-search-on-a-shoestring/3.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;However, for our example, we need to be a bit more clever with this.&lt;/p&gt;

	&lt;h3&gt;Enhancing the search form&lt;/h3&gt;

	&lt;p&gt;Here&amp;#8217;s &lt;a href="http://24ways.org/examples/sitewide-search-on-a-shoestring/boss-site-search.js"&gt;the script&lt;/a&gt; that &lt;a href="http://24ways.org/examples/sitewide-search-on-a-shoestring/enhance-form.html"&gt;enhances a search form to show results below it.&lt;/a&gt;&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;SITESEARCH = function(){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var config = {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;IDs:{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;searchForm:'customsearch',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;term:'term',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;site:'site'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;loading:'Loading results...',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;noresults:'No results found.',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;appID:'YOUR-APP-ID',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;results:20&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var form;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var out;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;function init(){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;if(config.appID === 'YOUR-APP-ID'){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;alert('Please get a real application ID!');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;} else {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;form = document.getElementById(config.IDs.searchForm);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;if(form){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;form.onsubmit = function(){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;var site = document.getElementById(config.IDs.site).value;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;var term = document.getElementById(config.IDs.term).value;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;if(typeof site === 'string' &amp;amp;&amp;amp; typeof term === 'string'){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;if(typeof out !== 'undefined'){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab7"&gt;&lt;code&gt;out.parentNode.removeChild(out);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;out = document.createElement('p');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;out.appendChild(document.createTextNode(config.loading));&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;form.appendChild(out);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;var APIurl = 'http://boss.yahooapis.com/ysearch/web/v1/' + &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab13"&gt;&lt;code&gt;term + '?callback=SITESEARCH.found&amp;amp;sites=' + &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab13"&gt;&lt;code&gt;site + '&amp;amp;count=' + config.results + &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab13"&gt;&lt;code&gt;'&amp;amp;appid=' + config.appID;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;var s = document.createElement('script');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;s.setAttribute('src',APIurl);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;s.setAttribute('type','text/javascript');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;document.getElementsByTagName('head')[0].appendChild(s);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab6"&gt;&lt;code&gt;return false;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;function found(o){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;var list = document.createElement('ul');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;var results = o.ysearchresponse.resultset_web;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;if(results){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;var item,link,description;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;for(var i=0,j=results.length;i&amp;lt;j;i++){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;item = document.createElement('li');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;link = document.createElement('a');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;link.setAttribute('href',results[i].clickurl);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;link.innerHTML = results[i].title;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;item.appendChild(link);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;description = document.createElement('p');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;description.innerHTML = results[i]['abstract'];&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;item.appendChild(description);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;list.appendChild(item);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;} else {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;list = document.createElement('p');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;list.appendChild(document.createTextNode(config.noresults));&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;form.replaceChild(list,out);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;out = list;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;return{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;config:config,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;init:init,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;found:found&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}();&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/sitewide-search-on-a-shoestring/4.txt" title="Download the above code as a textfile"&gt;/code/sitewide-search-on-a-shoestring/4.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;&lt;strong&gt;Oooohhhh scary code!&lt;/strong&gt; Let&amp;#8217;s go through this one bit at a time:&lt;/p&gt;

	&lt;p&gt;We start by creating a module called &lt;code&gt;SITESEARCH&lt;/code&gt; and give it an configuration object: &lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;SITESEARCH = function(){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var config = {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;IDs:{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;searchForm:'customsearch',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;term:'term',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;site:'site'&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;},&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;loading:'Loading results...',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;appID:'YOUR-APP-ID',&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;results:20&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;&lt;a href="http://www.wait-till-i.com/2008/05/23/script-configuration/"&gt;Configuration objects are a great idea&lt;/a&gt; to make your code easy to change and also to override. In this case you can define different IDs than the one agreed upon earlier, define a message to show when the results are loading, when there aren&amp;#8217;t any results, the application ID and the number of results that should be displayed.&lt;/p&gt;

	&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; you need to replace &amp;#8220;&lt;span class="caps"&gt;YOUR&lt;/span&gt;-&lt;span class="caps"&gt;APP&lt;/span&gt;-ID&amp;#8221; with the &lt;a href="https://developer.yahoo.com/wsregapp/"&gt;real ID you retrieved from &lt;span class="caps"&gt;BOSS&lt;/span&gt;&lt;/a&gt;, otherwise the script will complain! &lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;var form;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;var out;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;function init(){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(config.appID === 'YOUR-APP-ID'){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;alert('Please get a real application ID!');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;} else {&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;We define &lt;code&gt;form&lt;/code&gt; and &lt;code&gt;out&lt;/code&gt; as variables to make sure that all the methods in the module have access to them. We then check if there was a real application ID defined. If there wasn&amp;#8217;t, the script complains and that&amp;#8217;s that.      &lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;form = document.getElementById(config.IDs.searchForm);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if(form){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;form.onsubmit = function(){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;var site = document.getElementById(config.IDs.site).value;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;var term = document.getElementById(config.IDs.term).value;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;if(typeof site === 'string' &amp;amp;&amp;amp; typeof term === 'string'){&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;
      

	&lt;p&gt;If the application ID was a winner, we check if the form with the provided ID exists and apply an onsubmit event handler. The first thing we get is the values of the site we want to search in and the term that was entered and check that those are strings.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;if(typeof out !== 'undefined'){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;out.parentNode.removeChild(out);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;out = document.createElement('p');&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;out.appendChild(document.createTextNode(config.loading));&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;form.appendChild(out);&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;
  

	&lt;p&gt;If both are strings we check of &lt;code&gt;out&lt;/code&gt; is undefined. We will create a loading message and subsequently the list of search results later on and store them in this variable. So if &lt;code&gt;out&lt;/code&gt; is defined, it&amp;#8217;ll be an old version of a search (as users will re-submit the form over and over again)  and we need to remove that old version.&lt;/p&gt;

	&lt;p&gt;We then create a paragraph with the loading message and append it to the form.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li class="tab5"&gt;&lt;code&gt;var APIurl = 'http://boss.yahooapis.com/ysearch/web/v1/' + &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab12"&gt;&lt;code&gt;term + '?callback=SITESEARCH.found&amp;amp;sites=' + &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab12"&gt;&lt;code&gt;site + '&amp;amp;count=' + config.results + &lt;/code&gt;&lt;/li&gt;
&lt;li class="tab12"&gt;&lt;code&gt;'&amp;amp;appid=' + config.appID;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;var s = document.createElement('script');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;s.setAttribute('src',APIurl);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;s.setAttribute('type','text/javascript');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;document.getElementsByTagName('head')[0].appendChild(s);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab5"&gt;&lt;code&gt;return false;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab4"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab3"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;Now it is time to call the &lt;span class="caps"&gt;BOSS&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; by assembling a correct &lt;span class="caps"&gt;REST&lt;/span&gt; &lt;span class="caps"&gt;URL&lt;/span&gt;, create a script node and apply it to the head of the document. We return &lt;code&gt;false&lt;/code&gt; to ensure the form does not get submitted as we want to stay on the page.&lt;/p&gt;

	&lt;p&gt;Notice that we are using &lt;code&gt;SITESEARCH.found&lt;/code&gt; as the callback method, which means that we need to define this one to deal with the data returned by the &lt;span class="caps"&gt;API&lt;/span&gt;.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;function found(o){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var list = document.createElement('ul');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;var results = o.ysearchresponse.resultset_web;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;if(results){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;var item,link,description;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;We create a new list and then get the &lt;code&gt;resultset_web&lt;/code&gt; array from the data returned from the &lt;span class="caps"&gt;API&lt;/span&gt;. If there aren&amp;#8217;t any results returned, this array will not exist which is why we need to check for it. Once we done that we can define three variables to repeatedly store the item title we want to display, the link to point to and the description of the link.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;for(var i=0,j=results.length;i&amp;lt;j;i++){&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;item = document.createElement('li');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;link = document.createElement('a');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;link.setAttribute('href',results[i].clickurl);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;link.innerHTML = results[i].title;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;item.appendChild(link);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;description = document.createElement('p');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;description.innerHTML = results[i]['abstract'];&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;item.appendChild(description);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;list.appendChild(item);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;We then loop over the results array and assemble a list of results with the titles in links and paragraphs with the abstract of the site. Notice the bracket notation for abstract as &lt;code&gt;abstract&lt;/code&gt; is a reserved word in JavaScript2 :).&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li class="tab1"&gt;&lt;code&gt;} else {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;list = document.createElement('p');&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;list.appendChild(document.createTextNode(config.noresults));&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;form.replaceChild(list,out);&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;out = list;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;
      

	&lt;p&gt;If there aren&amp;#8217;t any results, we define a paragraph with the no results message as &lt;code&gt;list&lt;/code&gt;. In any case we replace the old &lt;code&gt;out&lt;/code&gt; (the loading message) with the &lt;code&gt;list&lt;/code&gt; and re-define &lt;code&gt;out&lt;/code&gt; as the &lt;code&gt;list&lt;/code&gt;.  &lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li class="tab1"&gt;&lt;code&gt;return{&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;config:config,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;init:init,&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;found:found&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;};&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}();&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;All that is left to do is return the properties and methods we want to make public. In this case &lt;code&gt;found&lt;/code&gt; needs to be public as it is accessed by the &lt;span class="caps"&gt;API&lt;/span&gt; return. We return &lt;code&gt;init&lt;/code&gt; to make it accessible and &lt;code&gt;config&lt;/code&gt; to allow implementers to override any of the properties.&lt;/p&gt;

	&lt;h3&gt;Using the script&lt;/h3&gt;

	&lt;p&gt;In order to use this script, all you need to do is to add it &lt;strong&gt;after&lt;/strong&gt; the form in the document, override the &lt;span class="caps"&gt;API&lt;/span&gt; key with your own and call &lt;code&gt;init()&lt;/code&gt;:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;form id=&amp;quot;customsearch&amp;quot; action=&amp;quot;http://search.yahoo.com/search&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;label for=&amp;quot;p&amp;quot;&amp;gt;Search this site:&amp;lt;/label&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;p&amp;quot; id=&amp;quot;term&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;vs&amp;quot; id=&amp;quot;site&amp;quot; value=&amp;quot;bbc.co.uk&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab2"&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;go&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;boss-site-search.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;SITESEARCH.config.appID = 'copy-the-id-you-know-to-get-where';&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;SITESEARCH.init();&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/sitewide-search-on-a-shoestring/14.txt" title="Download the above code as a textfile"&gt;/code/sitewide-search-on-a-shoestring/14.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;h3&gt;Where to go from here&lt;/h3&gt;

	&lt;p&gt;This is just a very simple example of what you can do with &lt;span class="caps"&gt;BOSS&lt;/span&gt;. You can define languages and regions, retrieve and display images and news and mix the results with other data sources before displaying them. One very cool feature is that by adding a &lt;code&gt;view=keyterms&lt;/code&gt; parameter to the &lt;span class="caps"&gt;URL&lt;/span&gt; you can get the keywords of each of the results to drill deeper into the search. An example for this written in &lt;span class="caps"&gt;PHP&lt;/span&gt; &lt;a href="http://developer.yahoo.net/blog/archives/2008/11/build_your_own.html"&gt;is available on the &lt;span class="caps"&gt;YDN&lt;/span&gt; blog&lt;/a&gt;. For JavaScript solutions there is a handy wrapper called &lt;a href="http://icant.co.uk/sandbox/yboss/"&gt;yboss&lt;/a&gt; available to help you go nuts.&lt;/p&gt;

 &lt;div id="webkrauts"&gt;&lt;a href="http://www.webkrauts.de/2008/12/04/suche-mit-alles-und-scharf-boss/" title="This article available in German at webkrauts.de" rel="translation"&gt;&lt;img src="http://media.24ways.org/img/webkrauts.png" alt="This article available in German at webkrauts.de" width="250" height="70" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=TdZ4-RcA4ts:qto7ZGcnXIY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=TdZ4-RcA4ts:qto7ZGcnXIY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=TdZ4-RcA4ts:qto7ZGcnXIY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=TdZ4-RcA4ts:qto7ZGcnXIY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=TdZ4-RcA4ts:qto7ZGcnXIY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/TdZ4-RcA4ts" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://wait-till-i.com/"&gt;Christian Heilmann&lt;/a&gt; introduces a handy &amp;#8216;build your own search&amp;#8217; web service from Yahoo that enables ordinary developers to harness Yahoo&amp;#8217;s search technology for their own sites and web applications. Roll your sleeves up and get ready for some code.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/sitewide-search-on-a-shoestring</feedburner:origLink></entry>
<entry>
		<author>
			<name>Jon Hicks</name>
		</author>
		<published>2008-12-03T00:00:07Z</published>
		<updated>2008-12-03T00:00:07Z</updated>
		<title type="html">User Styling</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/6zEZ4B1QldU/user-styling" />
		<id>tag:24ways.org,2008-12-02:7e1577ceca7ea22e28af5c35ee62927a/dc18dd716e4db56e2f0c5db6391a0ea4</id>
		<category term="css" />
		
		<content type="html">
&lt;p&gt;During the recent US elections, Twitter decided to add an &amp;#8216;election bar&amp;#8217; as part of their site design. You could close it if it annoyed you, but the action wasn&amp;#8217;t persistent and the bar would always come back like a bad penny. &lt;/p&gt;

	&lt;p&gt;The solution to common browsing problems like this is &lt;span class="caps"&gt;CSS&lt;/span&gt;. &amp;#8216;User styling&amp;#8217; (or the creepy &amp;#8216;skinning&amp;#8217;) is the creation of &lt;span class="caps"&gt;CSS&lt;/span&gt; rules to customise and personalise a particular domain. Aside from hiding adverts and other annoyances, there are many reasons for taking the time and effort to do it:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Improving personal readability by changing text size and colour&lt;/li&gt;
		&lt;li&gt;Personalising the look of a web app like GMail to look less insipid&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://hicksdesign.co.uk/journal/highlight-microformats-with-css"&gt;Revealing microformats&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Sport! My dreams of site skinning tennis are not yet fully realised, but it&amp;#8217;ll be all the rage by next Christmas, believe me.&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;Hopefully you&amp;#8217;re now asking &amp;#8220;But how? &lt;span class="caps"&gt;HOW&lt;/span&gt;?!&amp;#8221;. The process of creating a site skin is roughly as follows:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;See something you want to change&lt;/li&gt;
		&lt;li&gt;Find out what it&amp;#8217;s called, and if any rules already apply to it&lt;/li&gt;
		&lt;li&gt;Write &lt;span class="caps"&gt;CSS&lt;/span&gt; rule(s) to override and/or enhance it.&lt;/li&gt;
		&lt;li&gt;Apply the rules&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p&gt;So let&amp;#8217;s get stuck in…&lt;/p&gt;

	&lt;h3&gt;See something&lt;/h3&gt;

	&lt;p&gt;Let&amp;#8217;s start small with Multimap.com. Look at that big header &amp;#8211; it takes up an awful lot of screen space doesn&amp;#8217;t it? &lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/03/mm-20081129-201711.jpg" title="Multimap Screenshot" alt="Multimap Screenshot" /&gt;&lt;/p&gt;

	&lt;p&gt;No matter, we can fix it.&lt;/p&gt;

	&lt;h4&gt;Tools&lt;/h4&gt;

	&lt;p&gt;Now we need to find out where that big assed header is in the &lt;span class="caps"&gt;DOM&lt;/span&gt;, and make overriding &lt;span class="caps"&gt;CSS&lt;/span&gt; rules. The best tool  I&amp;#8217;ve found yet is the Mac OS X app, &lt;a href="http://macrabbit.com/cssedit/"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt; Edit&lt;/a&gt;. It utilises a slick &amp;#8216;override stylesheets&amp;#8217; function and &lt;span class="caps"&gt;DOM&lt;/span&gt; Inspector. Rather than give you all the usual &lt;span class="caps"&gt;DOM&lt;/span&gt; inspection tools, &lt;span class="caps"&gt;CSS&lt;/span&gt; Edit&amp;#8217;s is solely concerned with style.  Go into &amp;#8216;X-Ray&amp;#8217; mode, click an element, and look at the inspector window to see every style rule governing it. Click the selector to be taken to where it lives in the &lt;span class="caps"&gt;CSS&lt;/span&gt;. It really is a user styling dream app.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/03/cssedit-20081129-202552.jpg" title="CSS Edit in action" alt="CSS Edit in action" /&gt;&lt;/p&gt;

	&lt;p&gt;Having said all that, you &lt;strong&gt;can&lt;/strong&gt; achieve all this with free, cross platform  tools &amp;#8211; namely Firefox with the &lt;a href="http://getfirebug.com/"&gt;Firebug&lt;/a&gt; and &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2108"&gt;Stylish&lt;/a&gt; extensions. We&amp;#8217;ll be using them for these examples, so make sure you have them installed if you want to follow along.&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/03/firebug-20081129-203555.jpg" title="inspecting the DOM with Firebug" alt="inspecting the DOM with Firebug" /&gt;&lt;/p&gt;

	&lt;p&gt;Using Firebug, we can see that the page is very helpfully marked up, and that whole top area is simply a div with an ID of &lt;strong&gt;header&lt;/strong&gt;. &lt;/p&gt;

	&lt;h3&gt;Change Something&lt;/h3&gt;

	&lt;p&gt;When you installed Stylish, it added a page and brush icon to your status bar. Click on that, and choose Write Style &amp;gt; for Multimap.com. The other options allow you to only create a style for a particular part of a website or &lt;span class="caps"&gt;URL&lt;/span&gt;, but we want this to apply to the whole of Multimap:&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/03/menu-20081129-204014.jpg" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;The &amp;#8216;Add Style&amp;#8217; window then pops up, with the @-moz-document query at the top:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;@namespace url(http://www.w3.org/1999/xhtml);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@-moz-document domain(&amp;quot;multimap.com&amp;quot;) {&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;All you need to do is add the &lt;span class="caps"&gt;CSS&lt;/span&gt; to hide the header, in between the curly brackets.&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;@namespace url(http://www.w3.org/1999/xhtml);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@-moz-document domain(&amp;quot;multimap.com&amp;quot;) {&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;        #header {display: none;} &lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/03/gone-20081129-205422.jpg" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;A click of the preview button shows us that it&amp;#8217;s worked! Now the map appears further up the page. The ethics of hiding adverts is a discussion for another time, but let&amp;#8217;s face it, when did you last whoop at the sight of a banner?&lt;/p&gt;

	&lt;h3&gt;Make Something Better&lt;/h3&gt;

	&lt;p&gt;If we&amp;#8217;re happy with our modifications, all we need to do is give it a name and save. Whenever you visit Multimap.com, the style will be available. Stylish also allows you to toggle a style on/off via the status bar menu. If you feel you want to share this style with the world, then &lt;a href="http://userstyles.org/"&gt;userstyles.org&lt;/a&gt; is the place to do it. It&amp;#8217;s a grand repository of customisations that Stylish connects with. Whenever you visit a site, you can see if anyone else has written a style for it, again, via the status bar menu &amp;#8220;Find Styles for this Page&amp;#8221;. Selecting this with &amp;#8220;&lt;span class="caps"&gt;BBC&lt;/span&gt; News&amp;#8221; shows that there are plenty of options, ranging from small layout tweaks to redesigns:&lt;/p&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/03/userstyles-20081129-211021.jpg" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;What&amp;#8217;s more, whenever a style is updated, Stylish will notify you, and offer a one-click process to update it. This does only work in Firefox and Flock, so I&amp;#8217;ll cover ways of applying site styles to other browsers later.&lt;/p&gt;

	&lt;h3&gt;Specific Techniques&lt;/h3&gt;

	&lt;h4&gt;Important!&lt;/h4&gt;

	&lt;p&gt;In the Multimap example there wasn&amp;#8217;t a &lt;code&gt;display&lt;/code&gt; specified on that element, but it isn&amp;#8217;t always going to be that easy. You may have spent most of your &lt;span class="caps"&gt;CSS&lt;/span&gt; life being a good designer and not resorting to adding &lt;code&gt;!important&lt;/code&gt; to give your rule priority. There&amp;#8217;s no way to avoid this in user styling &amp;#8211; if you&amp;#8217;re overriding an existing rule it&amp;#8217;s a necessity! Be prepared to be typing &lt;code&gt;!important&lt;/code&gt; a lot.&lt;/p&gt;

	&lt;h4&gt;Star Selector&lt;/h4&gt;

	&lt;p&gt;The &lt;a href="http://reference.sitepoint.com/css/universalselector"&gt;Universal Selector&lt;/a&gt; is a particularly useful way to start a style. For example, if we want to make Flickr use Helvetica before Arial (as they should&amp;#8217;ve done!), we can cover all occurrences with just one rule:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;* {font-family: &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif !important;}&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;You can also use it to select &amp;#8216;everything within an element&amp;#8217;, by placing it after the element name:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;#content * {font-family: &amp;quot;Helvetica Neue&amp;quot;, Helvetica, sans-serif !important;}&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;h4&gt;Swapping Images&lt;/h4&gt;

	&lt;p&gt;If you&amp;#8217;re changing something a little more complex, such as Google Reader, then at some point you&amp;#8217;ll probably want to change an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;. The technique for replacing an image involves:&lt;/p&gt;

	&lt;ol&gt;
		&lt;li&gt;making your replacement image the background of the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag&lt;/li&gt;
		&lt;li&gt;adding padding top and left to the size of you image to push the &amp;#8216;top&amp;#8217; image away&lt;/li&gt;
		&lt;li&gt;making the height and width zero.&lt;/li&gt;
	&lt;/ol&gt;

	&lt;p class="image"&gt;&lt;img src="http://media.24ways.org/2008/03/images-20081129-214834.jpg" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;The old image is then pushed out of the way and hidden from view, allowing the replacement in the background to be revealed.  Targeting the image may require using an attribute selector:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;img[src=&amp;quot;/reader/ui/3544433079-tree-view-folder-open.gif&amp;quot;] {&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;padding: 16px 0 0 16px;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;width: 0 !important;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;height: 0 !important;&lt;/code&gt;&lt;/li&gt;
&lt;li class="tab1"&gt;&lt;code&gt;background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAA&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Bx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VYdENyZWF0aW9uIFRpbWUAMjkvNi8wOJJ/BVgAAAG3SURBVDiNpZIhb5RBEIaf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2W+vpIagIITSBIHBgsGjEYQaFLYShcITDL+ABIPnh4BFN0GQNFA4Cnf3fbszL2L3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;jiuEVLDJbCazu8+8Mzsmif9ZBvDy7bvXlni0HRe8eXL/zuPzABng62J5kFKaAQS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;QgJAOgHMB9vDZq+d71689Hcyw9LfAZAYdioE10VSJo6OPL/KNvSuHD+7dhU&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0vHEsDUUWJChIlYJIjFx5BuMB2mJY/DnMoOJl/R147oBUR0QAm8LAGCOEh3IO&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ULiAl8jSOy/nPetGsbGRKjktEiBCEHMlQj4loCuu4zCXCi4lUHTNDtGqEiACTqAFSI&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OgAUAKv4bkWVy2g6tAbJtGy0TNugM3HADmlurKH27dVZSecxjboXggiAsMItR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h99wTILdewYRpXVJWtY85k7fPW8e1GpJFJacgesXs6VYYomz9G2yDhwPB7NEB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BDAMK7WYJlisYVBCpfaJBeB+eocFyVyAgCaoMCTJSTOOCWSyILrAnaXpSexRsx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GGAZ0AR+XT+5fjzyfwSpnUB/1w64xizVI/t6q3b+58+vJ96mWtLf9haxNoc8M&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;v7N3d+AT4XPcFIxghoAAAAAElFTkSuQmCC) no-repeat !important;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;}&lt;/code&gt;&lt;/li&gt;
&lt;li class="source"&gt;Source:  &lt;a href="http://24ways.org/code/user-styling/5.txt" title="Download the above code as a textfile"&gt;/code/user-styling/5.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


	&lt;p&gt;Woah boy! What was all that gubbins in the background-image? It was a Data &lt;span class="caps"&gt;URI&lt;/span&gt;, and you can create these easily with &lt;a href="http://software.hixie.ch/utilities/cgi/data/data"&gt;Hixie&amp;#8217;s online tool&lt;/a&gt;. It&amp;#8217;s simply the image translated into text so that it can be embedded in the &lt;span class="caps"&gt;CSS&lt;/span&gt;, cutting down on the number of http requests. It&amp;#8217;s also a necessity with Mozilla browsers, as they don&amp;#8217;t allow user &lt;span class="caps"&gt;CSS&lt;/span&gt; to reference images stored locally. Converting images to &lt;span class="caps"&gt;URI&lt;/span&gt;&amp;#8217;s avoids this, as well as making a style easily portable &amp;#8211; no images folder to pass around. &lt;/p&gt;

	&lt;p&gt;Don&amp;#8217;t forget all your other &lt;span class="caps"&gt;CSS&lt;/span&gt; techniques at your disposal: inserting your own content with &lt;code&gt;:before&lt;/code&gt; and &lt;code&gt;:after&lt;/code&gt; pseudo classes, make elements semi-transparent with &lt;code&gt;opacity&lt;/code&gt; and round box corners without hacking . You can have fun, and for once, enjoy the freedom of not worrying about IE!&lt;/p&gt;

	&lt;h3&gt;User styling without Stylish&lt;/h3&gt;

	&lt;p&gt;Instead of using the Stylish extension, you can add rules to the userContent.css file, or use @import in that file to load a separate stylesheet. You can find this is in /Library/Application Support/Camino/chrome/ on OS X, or C/Program Files/Mozilla Firefox/Chrome on Windows. This is only way to apply user styles in Camino, but what about other browsers?&lt;/p&gt;

	&lt;h4&gt;Opera &amp;amp; Omniweb: &lt;/h4&gt;

	&lt;p&gt;Both allow you to specify a custom &lt;span class="caps"&gt;CSS&lt;/span&gt; file as part of the site&amp;#8217;s preferences. Opera also allows custom javascript, using the same syntax as Greasemonkey scripts (more on that below)&lt;/p&gt;

	&lt;h4&gt;Safari&lt;/h4&gt;

	&lt;p&gt;There are a few options here: the &lt;a href="http://www.culater.net/software/PithHelmet/PithHelmet.php"&gt;PithHelmet&lt;/a&gt; and &lt;a href="http://hetima.com/safari/stand-e.html"&gt;SafariStand&lt;/a&gt; haxies both allow custom stylesheets, or alternatively, a Greasemonkey style user script can employed via &lt;a href="http://8-p.info/greasekit/"&gt;GreaseKit&lt;/a&gt;. The latter is my favoured solution on my &lt;a href="http://helvetireader.com/"&gt;Helvetireader&lt;/a&gt; theme, as it can allow for more prescriptive domain rules, just like the Mozilla @-moz-document method. User scripts are also the solution supported by the widest range of browsers.&lt;/p&gt;

	&lt;h4&gt;What now?&lt;/h4&gt;

	&lt;p&gt;Hopefully I&amp;#8217;ve given you enough information for you to be able start making your own styles. If you want to go straight in and tackle the &amp;#8216;Holy Grail&amp;#8217;, then off with you to GMail &amp;#8211; I get more requests to theme that than anything else!&lt;/p&gt;

	&lt;p&gt;If you&amp;#8217;re a site author and want to encourage this sort of tom foolery, a good way is to provide a unique class or ID name with the body tag:&lt;/p&gt;

 &lt;ol class="code"&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;body id=&amp;quot;journal&amp;quot; class=&amp;quot;hicksdesign-co-uk&amp;quot;&amp;gt;&lt;/code&gt;&lt;/li&gt;

&lt;/ol&gt;


	&lt;p&gt;This makes it very easy to write rules that only apply to that particular site. If you wanted to use Safari without any of the haxies mentioned above, this method means you can include rules in a general &lt;span class="caps"&gt;CSS&lt;/span&gt; file (chosen via Preferences &amp;gt; Advanced &amp;gt; Stylesheet) without affecting other sites. &lt;/p&gt;

	&lt;p&gt;One final revelation on user styling &amp;#8211; it&amp;#8217;s not just for web sites. You can tweak the UI of Firefox itself with the userChrome.css. You&amp;#8217;ll need to use the in-built &lt;span class="caps"&gt;DOM&lt;/span&gt; Inspector instead of Firebug to inspect the window chrome, instead of a page. Great if you want to make small tweaks (changing the size of tab text for example) without creating a full blown theme.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=6zEZ4B1QldU:XOBiy3pvyNs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=6zEZ4B1QldU:XOBiy3pvyNs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=6zEZ4B1QldU:XOBiy3pvyNs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=6zEZ4B1QldU:XOBiy3pvyNs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=6zEZ4B1QldU:XOBiy3pvyNs:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/6zEZ4B1QldU" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://hicksdesign.co.uk/"&gt;Jon Hicks&lt;/a&gt; takes a peek at using &lt;span class="caps"&gt;CSS&lt;/span&gt; to apply custom user styles to change the appearance of sites within your own browser. Put your existing knowledge of &lt;span class="caps"&gt;CSS&lt;/span&gt; to good use to make your own browsing experience more pleasant and productive.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/user-styling</feedburner:origLink></entry>
<entry>
		<author>
			<name>Veerle Pieters</name>
		</author>
		<published>2008-12-02T00:00:14Z</published>
		<updated>2008-12-02T00:00:14Z</updated>
		<title type="html">Geometric Background Patterns</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/p687PiXPeWQ/geometric-background-patterns" />
		<id>tag:24ways.org,2008-12-01:7e1577ceca7ea22e28af5c35ee62927a/4749823c4b9cb0140b60cdf06a1f9951</id>
		<category term="design" />
		
		<content type="html">
&lt;p&gt;When the design is finished and you&amp;#8217;re about to start the coding process, you have to prepare your graphics. If you&amp;#8217;re working with a pattern background you need to export only the repeating fragment. It can be a bit tricky to isolate a fragment to achieve a seamless pattern background. For geometric patterns there is a method I always follow and that I want to share with you. Take for example a perfect 45° diagonal line pattern. &lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-howto01.gif" alt="diagonal pattern background" width="500" height="200" /&gt;&lt;/p&gt;

	&lt;p&gt;How do you define this pattern fragment so it will be rendered seamlessly?&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-howto02.gif" alt="wrong pattern fragment" width="500" height="200" /&gt;&lt;/p&gt;

	&lt;p&gt;Here is the method I usually follow to avoid a mismatch. First, zoom in so you see enough detail and you can distinguish the pixels. Select the Rectangular Marquee Selection tool and start your selection at the intersection of 2 different colors of a diagonal line. Hold down the Shift key while dragging so you drag a perfect square.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-howto03.gif" alt="wrong pattern fragment" width="500" height="307" /&gt;&lt;/p&gt;

	&lt;p&gt;Release the mouse when you reach the exact same intesection (as your starting) point at the top right. &lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-howto04.gif" alt="wrong pattern fragment" width="500" height="307" /&gt;&lt;/p&gt;

	&lt;p&gt;Copy this fragment (using &lt;em&gt;Copy Merged: Cmd/Ctrl + Shift + C&lt;/em&gt;) and paste the fragment in a new layer. Give this layer the name &amp;#8216;pattern&amp;#8217;. Now hold down the &lt;em&gt;Command Key&lt;/em&gt; (&lt;em&gt;Control Key on Windows&lt;/em&gt;) and click on the &amp;#8216;pattern&amp;#8217; layer in the Layers Palette  to select the fragment. Now go to &lt;em&gt;Edit &amp;gt; Define Patter&lt;/em&gt;n, enter a name for your pattern and click OK. Test your pattern in a new document. Create a new document of 600 px by 400px, hit &lt;em&gt;Cmd/Ctrl + A&lt;/em&gt; and go to&lt;em&gt; Edit &amp;gt; Fill&amp;#8230;&lt;/em&gt; and choose your pattern. If the result is OK, you have created a perfect pattern fragment.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-howto05.gif" alt="wrong pattern fragment" width="500" height="200" /&gt;&lt;/p&gt;

	&lt;p&gt;Below you see this pattern enlarged. The guides show the boundaries of the pattern fragment and the red pixels are the reference points. The red pixels at the top right, bottom right and bottom left should match the red pixel at the top left.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-howto06.gif" alt="wrong pattern fragment" width="500" height="500" /&gt;&lt;/p&gt;

	&lt;p&gt;This technique should work for every geometric pattern. Some patterns are easier than others, but this, and the Photoshop pattern fill test, has always been my guideline.&lt;/p&gt;

	&lt;h3&gt;Other geometric pattern examples&lt;/h3&gt;

	&lt;h4&gt;Example 1&lt;/h4&gt;

	&lt;p&gt;Not all geometric pattern fragments are squares. Some patterns look easy at first sight, because they look very repetitive, but they can be a bit tricky.&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-example-1a.gif" alt="geometric pattern example" width="500" height="200" /&gt;&lt;/p&gt;

	&lt;p&gt;Zoomed in pattern fragment with point of reference shown:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-example-1b.gif" alt="geometric pattern example - zoomed in pattern fragment" width="500" height="500" /&gt;&lt;/p&gt;

	&lt;h4&gt;Example 2&lt;/h4&gt;

	&lt;p&gt;Some patterns have a clear repeating point that can guide you, such as the blue small circle of this pattern as you can see from this zoomed in screenshot:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-example-2a.gif" alt="geometric pattern example" width="500" height="200" /&gt;&lt;/p&gt;

	&lt;p&gt;Zoomed in pattern fragment with point of reference shown:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-example-2b.gif" alt="geometric pattern example - zoomed in pattern fragment" width="500" height="500" /&gt;&lt;/p&gt;

	&lt;h4&gt;Example 3&lt;/h4&gt;

	&lt;p&gt;The different diagonal colors makes a bit more tricky to extract the correct pattern fragment. &lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-example-3a.gif" alt="geometric pattern example" width="500" height="200" /&gt;&lt;/p&gt;

	&lt;p&gt;The orange dot, which is the starting point of the selection is captured a few times inside the fragment selection:&lt;/p&gt;

	&lt;p&gt;&lt;img src="http://media.24ways.org/2008/02/pattern-example-3b.gif" alt="geometric pattern example - zoomed in pattern fragment" width="500" height="500" /&gt;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=p687PiXPeWQ:KrNfSGHEVGM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=p687PiXPeWQ:KrNfSGHEVGM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=p687PiXPeWQ:KrNfSGHEVGM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=p687PiXPeWQ:KrNfSGHEVGM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=p687PiXPeWQ:KrNfSGHEVGM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/p687PiXPeWQ" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://veerle.duoh.com/"&gt;Veerle Pieters&lt;/a&gt; gets up close and personal with geometric patterns and presents us with a handy Photoshop technique for slicing and dicing seamless tiles. Keep your repeating geometric patterns deep and crisp and even with these simple steps.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/geometric-background-patterns</feedburner:origLink></entry>
<entry>
		<author>
			<name>Drew McLellan</name>
		</author>
		<published>2008-12-01T00:00:55Z</published>
		<updated>2008-12-01T09:42:40Z</updated>
		<title type="html">Easing The Path from Design to Development</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/24ways/~3/oNPsSVvgJPY/easing-the-path-from-design-to-development" />
		<id>tag:24ways.org,2008-11-30:7e1577ceca7ea22e28af5c35ee62927a/2ff35f064f88175f1bd8a111e944f9e9</id>
		<category term="productivity" />
		
		<content type="html">
&lt;p&gt;As a web developer, I have the pleasure of working with a lot of different designers. There has been a lot of industry discussion of late about designers and developers, focusing on how different we sometimes are and how the interface between our respective phases of a project (that is to say moving from a design phase into production) can sometimes become a battleground.&lt;/p&gt;

	&lt;p&gt;I don&amp;#8217;t believe it has to be a battleground. It&amp;#8217;s actually more like being a dance partner &amp;#8211; our steps are different, but as long as we know our own part and have a little knowledge of our partner&amp;#8217;s steps, it all goes together to form a cohesive dance. Albeit with less spandex and fewer sequins (although that may depend on the project in question).&lt;/p&gt;

	&lt;p&gt;As the process usually flows from design towards development, it&amp;#8217;s most important that designers have a little knowledge of how the site is going to be built. At the &lt;a href="http://edgeofmyseat.com/"&gt;specialist web development agency&lt;/a&gt; I&amp;#8217;m part of, we find that designs that have been well considered from a technical perspective help to keep the project on track and on budget.&lt;/p&gt;

	&lt;p&gt;Based on that experience, I&amp;#8217;ve put together my checklist of things that designers should consider before handing their work over to a developer to build.&lt;/p&gt;

	&lt;h3&gt;Layout&lt;/h3&gt;

	&lt;p&gt;One rookie mistake made by traditionally trained designers transferring to the web is to forget a web browser is not a fixed medium. Unlike designing a magazine layout or a piece of packaging, there are lots of available options to consider. Should the layout be fluid and resize with the window, or should it be set to a fixed width? If it&amp;#8217;s fluid, which parts expand and which not? If it&amp;#8217;s fixed, should it sit in the middle of the window or to one side?&lt;/p&gt;

	&lt;p&gt;If any part of the layout is going to be flexible (get wider and narrower as required), consider how any graphics are affected. Images don&amp;#8217;t usually look good if displayed at anything other that their original size, so should they behave? If a column is going to get wider than it&amp;#8217;s shown in the Photoshop comp, it may be necessary to provide separate wider versions of any background images.&lt;/p&gt;

	&lt;h3&gt;Text size and content volume&lt;/h3&gt;

	&lt;p&gt;A related issue is considering how the layout behaves with both different sizes of text and different volumes of content. Whilst text zooming rather than text resizing is becoming more commonplace as the default behaviour in browsers, it&amp;#8217;s still a fundamentally important principal of web design that we are suggesting and not dictating how something should look. Designs must allow for a little give and take in the text size, and how this affects the design needs to be taken into consideration.&lt;/p&gt;

	&lt;p&gt;Keep in mind that the same font can display differently in different places and platforms. Something as simple as Times will display wider on a Mac than on Windows. However, the main impact of text resizing is the change in how much vertical space copy takes up. This is particularly important where space is limited by the design (making text bigger causes many more problems than making text smaller). Each element from headings to box-outs to navigation items and buttons needs to be able to expand at least vertically, if not horizontally as well. This may require some thought about how elements on the page may wrap onto new lines, as well as again making sure to provide extended versions of any graphical elements.&lt;/p&gt;

	&lt;p&gt;Similarly, it&amp;#8217;s rare theses days to know exactly what content you&amp;#8217;re working with when a site is designed. Many, if not most sites are designed as a series of templates for some kind of content management system, and so designs cannot be tweaked around any specific item of content. Designs must be able to cope with both much greater and much lesser volumes of content that might be thrown in at the lorem ipsum phase.&lt;/p&gt;

	&lt;p&gt;Particular things to watch out for are things like headings (how do they wrap onto multiple lines) and any user-generated items like usernames. It can be very easy to forget that whilst you might expect something like a username to be 8-12 characters, if the systems powering your site allow for 255 characters they&amp;#8217;ll always be someone who&amp;#8217;ll go there. Expect them to do so.&lt;/p&gt;

	&lt;p&gt;Again, if your site is content managed or not, consider the possibility that the structure might be expanded in the future. Consider how additional items might be added to each level of navigation. Whilst it&amp;#8217;s rarely desirable to make significant changes without revisiting the site&amp;#8217;s information architecture more thoroughly, it&amp;#8217;s an inevitable fact of life that the structure needs a little bit of flexibility to change over time.&lt;/p&gt;

	&lt;h3&gt;Interactions with and without JavaScript&lt;/h3&gt;

	&lt;p&gt;A great number of sites now make good use of JavaScript to streamline the user interface and make everything just that touch more usable. Remember, though, that any developer worth their salt will start by building the interface without JavaScript, get it all working, and then layer that JavaScript on top. This is to allow for users viewing the site without JavaScript available or enabled in their browser.&lt;/p&gt;

	&lt;p&gt;Designers need to consider both states of any feature they&amp;#8217;re designing &amp;#8211; how it looks and functions with and without JavaScript. If the feature does something fancy with Ajax, consider how the same can be achieved with basic &lt;span class="caps"&gt;HTML&lt;/span&gt; forms, links and intermediary pages. These all need to be designed, because this is how some of your users will interact with the site.&lt;/p&gt;

	&lt;h3&gt;Logged in and logged out states&lt;/h3&gt;

	&lt;p&gt;When designing any type of web application or site that has a membership system &amp;#8211; that is to say users can create an account and log into the site &amp;#8211; the design will need to consider how any element is presented in both logged in and logged out states. For some items there&amp;#8217;ll be no difference, whereas for others there may be considerable differences.&lt;/p&gt;

	&lt;p&gt;Should an item be hidden completely not logged out users? Should it look different in some way? Perhaps it should look the same, but prompt the user to log in when they interact with it. If so, what form should that prompt take on and how does the user progress through the authentication process to arrive back at the task they were originally trying to complete?&lt;/p&gt;

	&lt;p&gt;Couple logged in and logged out states with the possible absence of JavaScript, and every feature needs to be designed in four different states:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Logged out with JavaScript available&lt;/li&gt;
		&lt;li&gt;Logged in with JavaScript available&lt;/li&gt;
		&lt;li&gt;Logged out without JavaScript available&lt;/li&gt;
		&lt;li&gt;Logged in without JavaScript available&lt;/li&gt;
	&lt;/ul&gt;

	&lt;h3&gt;Fonts&lt;/h3&gt;

	&lt;p&gt;There are three main causes of war in this world; religions, politics and fonts. I&amp;#8217;ve said publicly before that I believe the responsibility for this falls squarely at the feet of Adobe Photoshop. Photoshop, like a mistress at a brothel, parades a vast array of ropey, yet strangely enticing typefaces past the eyes of weak, lily-livered designers, who can&amp;#8217;t help but crumble to their curvy charms.&lt;/p&gt;

	&lt;p&gt;Yet, on the web, we have to be a little more restrained in our choice of typefaces. The purest solution is always to make the best use of the &lt;a href="http://24ways.org/2007/increase-your-font-stacks-with-font-matrix"&gt;available fonts&lt;/a&gt;, but this isn&amp;#8217;t always the most desirable solution from a design point of view. There are several technical solutions such as techniques that utilise Flash (like sIFR), dynamically generated images and even canvas in newer browsers. Discuss the best approach with your developer, as every different technique has different trade-offs, and this may impact the design in other ways.&lt;/p&gt;

	&lt;h3&gt;Messaging&lt;/h3&gt;

	&lt;p&gt;Any site that has interactive elements, from a simple contact form through to fully featured online software application, involves some kind of user messaging. By this I mean the error messages when something goes wrong and the success and thank-you messages when something goes right. These typically appear as the result of an interaction, so are easy to forget and miss off a Photoshop comp.&lt;/p&gt;

	&lt;p&gt;For every form, consider what gets displayed to the user if they make a mistake or miss something out, and also what gets displayed back when the interaction is successful. What do they see and where do the go next?&lt;/p&gt;

	&lt;p&gt;With Ajax interactions, the user doesn&amp;#8217;t get any visual feedback of the site waiting for a response from the server unless you design it that way. Consider using a &amp;#8216;waiting&amp;#8217; or &amp;#8216;in progress&amp;#8217; spinner to give the user some visual feedback of any background processes. How should these look? How do they animate?&lt;/p&gt;

	&lt;p&gt;Similarly, also consider the big error pages like a 404. With luck, these won&amp;#8217;t often be seen, but it&amp;#8217;s at the point that they are when careful design matters the most.&lt;/p&gt;

	&lt;h3&gt;Form fields&lt;/h3&gt;

	&lt;p&gt;Depending on the visual style of your site, the look of a browser&amp;#8217;s default form fields and buttons can sometimes jar. It&amp;#8217;s understandable that many a designer wants to change the way they look. Depending on the browser in question, various things can be done to style form fields and their buttons (although it&amp;#8217;s not as flexible as most would like).&lt;/p&gt;

	&lt;p&gt;A common request is to replace the default buttons with a graphical button. This is usually achievable in most cases, although it&amp;#8217;s not easy to get a consistent result across all browsers &amp;#8211; particularly when it comes to vertical positioning and the space surrounding the button. If the layout is very precise, or if space is at a premium, it&amp;#8217;s always best to try and live with the browser&amp;#8217;s default form controls.&lt;/p&gt;

	&lt;p&gt;Whichever way you go, it&amp;#8217;s important to remember that in general, each form field should have a label, and each form should have a submit button. If you find that your form breaks either of those rules, you should double check.&lt;/p&gt;

	&lt;h3&gt;Practical tips for handing files over&lt;/h3&gt;

	&lt;p&gt;There are a couple of basic steps that a design can carry out to make sure that the developer has the best chance of implementing the design exactly as envisioned.&lt;/p&gt;

	&lt;p&gt;If working with Photoshop of Fireworks or similar comping tool, it helps to &lt;strong&gt;group and label layers&lt;/strong&gt; to make it easy for a developer to see which need to be turned on and off to get to isolate parts of the page and different states of the design. Also, if you don&amp;#8217;t work in the same office as your developer (and so they can&amp;#8217;t quickly check with you), provide a &lt;span class="caps"&gt;PDF&lt;/span&gt; of each page and state so that your developer can see how each page should look aside from any confusion with quick layers are switched on or off. These also act as a handy quick reference that can be used without firing up Photoshop (which can kill both productivity and your machine).&lt;/p&gt;

	&lt;p&gt;Finally, &lt;strong&gt;provide a colour reference&lt;/strong&gt; showing the &lt;span class="caps"&gt;RGB&lt;/span&gt; values of all the key colours used throughout the design. Without this, the developer will end up colour-picking from the comps, and could potentially end up with different colours to those you intended. Remember, for a lot of developers, working in a tool like Photoshop is like presenting a designer with an &lt;span class="caps"&gt;SSH&lt;/span&gt; terminal into a web server. It&amp;#8217;s unfamiliar ground and easy to get things wrong. Be the expert of your own domain and help your colleagues out when they&amp;#8217;re out of their comfort zone. That goes both ways.&lt;/p&gt;

	&lt;h3&gt;In conclusion&lt;/h3&gt;

	&lt;p&gt;When asked the question of how to smooth hand-over between design and development, almost everyone who has experienced this situation could come up with their own list. This one is mine, based on some of the more common experiences we have at &lt;a href="http://edgeofmyseat.com/"&gt;edgeofmyseat.com&lt;/a&gt;. So in bullet point form, here&amp;#8217;s my checklist for handing a design over.&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Is the layout fixed, or fluid?&lt;/li&gt;
		&lt;li&gt;Does each element cope with expanding for larger text and more content?&lt;/li&gt;
		&lt;li&gt;Are all the graphics large enough to cope with an area expanding?&lt;/li&gt;
		&lt;li&gt;Does each interactive element have a state for with and without JavaScript?&lt;/li&gt;
		&lt;li&gt;Does each element have a state for logged in and logged out users?&lt;/li&gt;
		&lt;li&gt;How are any custom fonts being displayed? (and does the developer have the font to use?)&lt;/li&gt;
		&lt;li&gt;Does each interactive element have error and success messages designed?&lt;/li&gt;
		&lt;li&gt;Do all form fields have a label and each form a submit button?&lt;/li&gt;
		&lt;li&gt;Is your Photoshop comp document well organised?&lt;/li&gt;
		&lt;li&gt;Have you provided flat &lt;span class="caps"&gt;PDF&lt;/span&gt;s of each state?&lt;/li&gt;
		&lt;li&gt;Have you provided a colour reference?&lt;/li&gt;
		&lt;li&gt;Are we having fun yet?&lt;/li&gt;
	&lt;/ul&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/24ways?a=oNPsSVvgJPY:xywZ3tmslnY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=oNPsSVvgJPY:xywZ3tmslnY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=oNPsSVvgJPY:xywZ3tmslnY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?i=oNPsSVvgJPY:xywZ3tmslnY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/24ways?a=oNPsSVvgJPY:xywZ3tmslnY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/24ways?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/24ways/~4/oNPsSVvgJPY" height="1" width="1"/&gt;</content>
		<summary type="html">
&lt;p&gt;&lt;a href="http://allinthehead.com/"&gt;Drew McLellan&lt;/a&gt; sets our 2008 series rolling with some practical tips for helping a project smoothly transition from the design to the development phase. Consider it a designer&amp;#8217;s preflight check list to ease you into the festive season.&lt;/p&gt;
</summary>
<feedburner:origLink>http://24ways.org/2008/easing-the-path-from-design-to-development</feedburner:origLink></entry></feed>
