rowid,title,contents,year,author,author_slug,published,url,topic 314,Easy Ajax with Prototype,"There’s little more impressive on the web today than a appropriate touch of Ajax. Used well, Ajax brings a web interface much closer to the experience of a desktop app, and can turn a bear of an task into a pleasurable activity. But it’s really hard, right? It involves all the nasty JavaScript that no one ever does often enough to get really good at, and the browser support is patchy, and urgh it’s just so much damn effort. Well, the good news is that – ta-da – it doesn’t have to be a headache. But man does it still look impressive. Here’s how to amaze your friends. Introducing prototype.js Prototype is a JavaScript framework by Sam Stephenson designed to help make developing dynamic web apps a whole lot easier. In basic terms, it’s a JavaScript file which you link into your page that then enables you to do cool stuff. There’s loads of capability built in, a portion of which covers our beloved Ajax. The whole thing is freely distributable under an MIT-style license, so it’s good to go. What a nice man that Mr Stephenson is – friends, let us raise a hearty cup of mulled wine to his good name. Cheers! sluurrrrp. First step is to download the latest Prototype and put it somewhere safe. I suggest underneath the Christmas tree. Cutting to the chase Before I go on and set up an example of how to use this, let’s just get to the crux. Here’s how Prototype enables you to make a simple Ajax call and dump the results back to the page: var url = 'myscript.php'; var pars = 'foo=bar'; var target = 'output-div'; var myAjax = new Ajax.Updater(target, url, {method: 'get', parameters: pars}); This snippet of JavaScript does a GET to myscript.php, with the parameter foo=bar, and when a result is returned, it places it inside the element with the ID output-div on your page. Knocking up a basic example So to get this show on the road, there are three files we need to set up in our site alongside prototype.js. Obviously we need a basic HTML page with prototype.js linked in. This is the page the user interacts with. Secondly, we need our own JavaScript file for the glue between the interface and the stuff Prototype is doing. Lastly, we need the page (a PHP script in my case) that the Ajax is going to make its call too. So, to that basic HTML page for the user to interact with. Here’s one I found whilst out carol singing: Easy Ajax
As you can see, I’ve linked in prototype.js, and also a file called ajax.js, which is where we’ll be putting our glue. (Careful where you leave your glue, kids.) Our basic example is just going to take a name and then echo it back in the form of a seasonal greeting. There’s a form with an input field for a name, and crucially a DIV (greeting) for the result of our call. You’ll also notice that the form has a submit button – this is so that it can function as a regular form when no JavaScript is available. It’s important not to get carried away and forget the basics of accessibility. Meanwhile, back at the server So we need a script at the server which is going to take input from the Ajax call and return some output. This is normally where you’d hook into a database and do whatever transaction you need to before returning a result. To keep this as simple as possible, all this example here will do is take the name the user has given and add it to a greeting message. Not exactly Web 2-point-HoHoHo, but there you have it. Here’s a quick PHP script – greeting.php – that Santa brought me early. Season's Greetings, $the_name!

""; ?> You’ll perhaps want to do something a little more complex within your own projects. Just sayin’. Gluing it all together Inside our ajax.js file, we need to hook this all together. We’re going to take advantage of some of the handy listener routines and such that Prototype also makes available. The first task is to attach a listener to set the scene once the window has loaded. He’s how we attach an onload event to the window object and get it to call a function named init(): Event.observe(window, 'load', init, false); Now we create our init() function to do our evil bidding. Its first job of the day is to hide the submit button for those with JavaScript enabled. After that, it attaches a listener to watch for the user typing in the name field. function init(){ $('greeting-submit').style.display = 'none'; Event.observe('greeting-name', 'keyup', greet, false); } As you can see, this is going to make a call to a function called greet() onkeyup in the greeting-name field. That function looks like this: function greet(){ var url = 'greeting.php'; var pars = 'greeting-name='+escape($F('greeting-name')); var target = 'greeting'; var myAjax = new Ajax.Updater(target, url, {method: 'get', parameters: pars}); } The key points to note here are that any user input needs to be escaped before putting into the parameters so that it’s URL-ready. The target is the ID of the element on the page (a DIV in our case) which will be the recipient of the output from the Ajax call. That’s it No, seriously. That’s everything. Try the example. Amaze your friends with your 1337 Ajax sk1llz.",2005,Drew McLellan,drewmclellan,2005-12-01T00:00:00+00:00,https://24ways.org/2005/easy-ajax-with-prototype/,code 315,Edit-in-Place with Ajax,"Back on day one we looked at using the Prototype library to take all the hard work out of making a simple Ajax call. While that was fun and all, it didn’t go that far towards implementing something really practical. We dipped our toes in, but haven’t learned to swim yet. So here is swimming lesson number one. Anyone who’s used Flickr to publish their photos will be familiar with the edit-in-place system used for quickly amending titles and descriptions on photographs. Hovering over an item turns its background yellow to indicate it is editable. A simple click loads the text into an edit box, right there on the page. Prototype includes all sorts of useful methods to help reproduce something like this for our own projects. As well as the simple Ajax GETs we learned how to do last time, we can also do POSTs (which we’ll need here) and a whole bunch of manipulations to the user interface – all through simple library calls. Here’s what we’re building, so let’s do it. Getting Started There are two major components to this process; the user interface manipulation and the Ajax call itself. Our set-up is much the same as last time (you may wish to read the first article if you’ve not already done so). We have a basic HTML page which links in the prototype.js file and our own editinplace.js. Here’s what Santa dropped down my chimney: Edit-in-Place with Ajax

Edit-in-place

Dashing through the snow on a one horse open sleigh.

So that’s our page. The editable item is going to be the

called desc. The process goes something like this: Highlight the area onMouseOver Clear the highlight onMouseOut If the user clicks, hide the area and replace with a '; var button = ' OR '; new Insertion.After(obj, textarea+button); Event.observe(obj.id+'_save', 'click', function(){saveChanges(obj)}, false); Event.observe(obj.id+'_cancel', 'click', function(){cleanUp(obj)}, false); } The first thing to do is to hide the object. Prototype comes to the rescue with Element.hide() (and of course, Element.show() too). Following that, we build up the textarea and buttons as a string, and then use Insertion.After() to place our new editor underneath the (now hidden) editable object. The last thing to do before we leave the user to edit is it attach listeners to the Save and Cancel buttons to call either the saveChanges() function, or to cleanUp() after a cancel. In the event of a cancel, we can clean up behind ourselves like so: function cleanUp(obj, keepEditable){ Element.remove(obj.id+'_editor'); Element.show(obj); if (!keepEditable) showAsEditable(obj, true); } Saving the Changes This is where all the Ajax fun occurs. Whilst the previous article introduced Ajax.Updater() for simple Ajax calls, in this case we need a little bit more control over what happens once the response is received. For this purpose, Ajax.Request() is perfect. We can use the onSuccess and onFailure parameters to register functions to handle the response. function saveChanges(obj){ var new_content = escape($F(obj.id+'_edit')); obj.innerHTML = ""Saving...""; cleanUp(obj, true); var success = function(t){editComplete(t, obj);} var failure = function(t){editFailed(t, obj);} var url = 'edit.php'; var pars = 'id=' + obj.id + '&content=' + new_content; var myAjax = new Ajax.Request(url, {method:'post', postBody:pars, onSuccess:success, onFailure:failure}); } function editComplete(t, obj){ obj.innerHTML = t.responseText; showAsEditable(obj, true); } function editFailed(t, obj){ obj.innerHTML = 'Sorry, the update failed.'; cleanUp(obj); } As you can see, we first grab in the contents of the textarea into the variable new_content. We then remove the editor, set the content of the original object to “Saving…” to show that an update is occurring, and make the Ajax POST. If the Ajax fails, editFailed() sets the contents of the object to “Sorry, the update failed.” Admittedly, that’s not a very helpful way to handle the error but I have to limit the scope of this article somewhere. It might be a good idea to stow away the original contents of the object (obj.preUpdate = obj.innerHTML) for later retrieval before setting the content to “Saving…”. No one likes a failure – especially a messy one. If the Ajax call is successful, the server-side script returns the edited content, which we then place back inside the object from editComplete, and tidy up. Meanwhile, back at the server The missing piece of the puzzle is the server-side script for committing the changes to your database. Obviously, any solution I provide here is not going to fit your particular application. For the purposes of getting a functional demo going, here’s what I have in PHP. Not exactly rocket science is it? I’m just catching the content item from the POST and echoing it back. For your application to be useful, however, you’ll need to know exactly which record you should be updating. I’m passing in the ID of my

, which is not a fat lot of use. You can modify saveChanges() to post back whatever information your app needs to know in order to process the update. You should also check the user’s credentials to make sure they have permission to edit whatever it is they’re editing. Basically the same rules apply as with any script in your application. Limitations There are a few bits and bobs that in an ideal world I would tidy up. The first is the error handling, as I’ve already mentioned. The second is that from an idealistic standpoint, I’d rather not be using innerHTML. However, the reality is that it’s presently the most efficient way of making large changes to the document. If you’re serving as XML, remember that you’ll need to replace these with proper DOM nodes. It’s also important to note that it’s quite difficult to make something like this universally accessible. Whenever you start updating large chunks of a document based on user interaction, a lot of non-traditional devices don’t cope well. The benefit of this technique, though, is that if JavaScript is unavailable none of the functionality gets implemented at all – it fails silently. It is for this reason that this shouldn’t be used as a complete replacement for a traditional, universally accessible edit form. It’s a great time-saver for those with the ability to use it, but it’s no replacement. See it in action I’ve put together an example page using the inert PHP script above. That is to say, your edits aren’t committed to a database, so the example is reset when the page is reloaded.",2005,Drew McLellan,drewmclellan,2005-12-23T00:00:00+00:00,https://24ways.org/2005/edit-in-place-with-ajax/,code 318,Auto-Selecting Navigation,"In the article Centered Tabs with CSS Ethan laid out a tabbed navigation system which can be centred on the page. A frequent requirement for any tab-based navigation is to be able to visually represent the currently selected tab in some way. If you’re using a server-side language such as PHP, it’s quite easy to write something like class=""selected"" into your markup, but it can be even simpler than that. Let’s take the navigation div from Ethan’s article as an example.
As you can see we have a standard unordered list which is then styled with CSS to look like tabs. By giving each tab a class which describes it’s logical section of the site, if we were to then apply a class to the body tag of each page showing the same, we could write a clever CSS selector to highlight the correct tab on any given page. Sound complicated? Well, it’s not a trivial concept, but actually applying it is dead simple. Modifying the markup First thing is to place a class name on each li in the list:
Then, on each page of your site, apply the a matching class to the body tag to indicate which section of the site that page is in. For example, on your About page: ... Writing the CSS selector You can now write a single CSS rule to match the selected tab on any given page. The logic is that you want to match the ‘about’ tab on the ‘about’ page and the ‘products’ tab on the ‘products’ page, so the selector looks like this: body.home #navigation li.home, body.about #navigation li.about, body.work #navigation li.work, body.products #navigation li.products, body.contact #navigation li.contact{ ... whatever styles you need to show the tab selected ... } So all you need to do when you create a new page in your site is to apply a class to the body tag to say which section it’s in. The CSS will do the rest for you – without any server-side help.",2005,Drew McLellan,drewmclellan,2005-12-10T00:00:00+00:00,https://24ways.org/2005/auto-selecting-navigation/,code 336,Practical Microformats with hCard,"You’ve probably heard about microformats over the last few months. You may have even read the easily digestible introduction at Digital Web Magazine, but perhaps you’ve not found time to actually implement much yet. That’s understandable, as it can sometimes be difficult to see exactly what you’re adding by applying a microformat to a page. Sure, you’re semantically enhancing the information you’re marking up, and the Semantic Web is a great idea and all, but what benefit is it right now, today? Well, the answer to that question is simple: you’re adding lots of information that can be and is being used on the web here and now. The big ongoing battle amongst the big web companies if one of territory over information. Everyone’s grasping for as much data as possible. Some of that information many of us are cautious to give away, but a lot of is happy to be freely available. Of the data you’re giving away, it makes sense to give it as much meaning as possible, thus enabling anyone from your friends and family to the giant search company down the road to make the most of it. Ok, enough of the waffle, let’s get working. Introducing hCard You may have come across hCard. It’s a microformat for describing contact information (or really address book information) from within your HTML. It’s based on the vCard format, which is the format the contacts/address book program on your computer uses. All the usual fields are available – name, address, town, website, email, you name it. If you’re running Firefox and Greasemonkey (or if you can, just to try this out), install this user script. What it does is look for instances of the hCard microformat in a page, and then add in a link to pass any hCards it finds to a web service which will convert it to a vCard. Take a look at the About the author box at the bottom of this article. It’s a hCard, so you should be able to click the icon the user script inserts and add me to your Outlook contacts or OS X Address Book with just a click. So microformats are useful after all. Free microformats all round! Implementing hCard This is the really easy bit. All the hCard microformat is, is a bunch of predefined class names that you apply to the markup you’ve probably already got around your contact information. Let’s take the example of the About the author box from this article. Here’s how the markup looks without hCard:

About the author

Drew McLellan is a web developer, author and no-good swindler from just outside London, England. At the Web Standards Project he works on press, strategy and tools. Drew keeps a personal weblog covering web development issues and themes.

This is a really simple example because there’s only two key bits of address book information here:- my name and my website address. Let’s push it a little and say that the Web Standards Project is the organisation I work for – that gives us Name, Company and URL. To kick off an hCard, you need a containing object with a class of vcard. The div I already have with a class of bio is perfect for this – all it needs to do is contain the rest of the contact information. The next thing to identify is my name. hCard uses a class of fn (meaning Full Name) to identify a name. As is this case there’s no element surrounding my name, we can just use a span. These changes give us:

About the author

Drew McLellan is a web developer... The two remaining items are my URL and the organisation I belong to. The class names designated for those are url and org respectively. As both of those items are links in this case, I can apply the classes to those links. So here’s the finished hCard.

About the author

Drew McLellan is a web developer, author and no-good swindler from just outside London, England. At the Web Standards Project he works on press, strategy and tools. Drew keeps a personal weblog covering web development issues and themes.

OK, that was easy. By just applying a few easy class names to the HTML I was already publishing, I’ve implemented an hCard that right now anyone with Greasemonkey can click to add to their address book, that Google and Yahoo! and whoever else can index and work out important things like which websites are associated with my name if they so choose (and boy, will they so choose), and in the future who knows what. In terms of effort, practically nil. Where next? So that was a trivial example, but to be honest it doesn’t really get much more complex even with the most pernickety permutations. Because hCard is based on vCard (a mature and well thought-out standard), it’s all tried and tested. Here’s some good next steps. Play with the hCard Creator Take a deep breath and read the spec Start implementing hCard as you go on your own projects – it takes very little time hCard is just one of an ever-increasing number of microformats. If this tickled your fancy, I suggest subscribing to the microformats site in your RSS reader to keep in touch with new developments. What’s the take-away? The take-away is this. They may sound like just more Web 2-point-HoHoHo hype, but microformats are a well thought-out, and easy to implement way of adding greater depth to the information you publish online. They have some nice benefits right away – certainly at geek-level – but in the longer term they become much more significant. We’ve been at this long enough to know that the web has a long, long memory and that what you publish today will likely be around for years. But putting the extra depth of meaning into your documents now you can help guard that they’ll continue to be useful in the future, and not just a bunch of flat ASCII.",2005,Drew McLellan,drewmclellan,2005-12-06T00:00:00+00:00,https://24ways.org/2005/practical-microformats-with-hcard/,code 222,Golden Spirals,"As building blocks go, the rectangle is not one to overwhelm the designer with decisions. On the face of it, you have two options: you can set the width, and the height. But despite this apparent simplicity, there are combinations of width and height that can look unbalanced. If a rectangle is too tall and slim, it might appear precarious. If it is not tall enough, it may simply look flat. But like a guitar string that’s out of tune, you can tweak the proportions little by little until a rectangle feels, as Goldilocks said, just right. A golden rectangle has its height and width in the golden ratio, which is approximately 1:1.618. These proportions have long been recognised as being aesthetically harmonious. Whether through instruction or by intuition, artists have understood how to exploit these proportions over the centuries. Examples can be found in classical architecture, medieval book construction, and even in the recent #newtwitter redesign. A mathematical curiosity The golden rectangle is unique, in that if you remove a square section from it, what is left behind is itself a golden rectangle. The removal of a square can be repeated on the rectangle that is left behind, and then repeated again, as many times as you like. This means that the golden rectangle can be treated as a building block for recursive patterns. In this article, we will exploit this property to build a golden spiral, using only HTML and CSS. The markup The HTML we’ll use for this study is simply a series of nested
s.
The first of these has the class cycle, and so does every fourth ancestor thereafter. The spiral completes a cycle every four steps, so this class allows styles to be reused on
s that appear at the same position in each cycle. Golden proportions To create our spiral we are going to exploit the unique properties of the golden rectangle, so our first priority is to ensure that we have a golden rectangle to begin with. If we pick a length for the short edge – say, 288 pixels – we can then calculate the length of the long edge by multiplying this value by 1.618. In this case, 288 × 1.618 = 466, so our starting point will be a
with these properties: #container > div { width: 466px; height: 288px; } The greater than symbol is used here to single out the immediate child of the #container element, without affecting the grandchild or any of the more distant descendants. We could go on to specify the precise pixel dimensions of every child element, but that means doing a lot of sums. It would be much easier if we just specified the dimensions for each element as a percentage of the width and height of its parent. This also has the advantage that if you change the size of the outermost container, all nested elements would be resized automatically – something that we shall exploit later. The approximate value of 38.2% can be derived from (100 × 1 − phi) ÷ phi, where the Greek letter phi (ϕ) stands for the golden ratio. The value of phi can be expressed as phi = (1 + √5 ) ÷ 2, which is approximately 1.618. You don’t have to understand the derivation to use it. Just remember that if you start with a golden rectangle, you can slice 38.2% from it to create a new golden rectangle. This can be expressed in CSS quite simply: .cycle, .cycle > div > div { height: 38.2%; width: 100%; } .cycle > div, .cycle > div > div > div { width: 38.2%; height: 100%; } You can see the result so far by visiting Demo One. With no borders or shading, there is nothing to see yet, so let’s address that next. Shading with transparency We’ll need to apply some shading to distinguish each segment of the spiral from its neighbours. We could start with a white background, then progress through shades of grey: #eee, #ddd, #ccc and so on, but this means hard-coding the background-color for every element. A more elegant solution would be to use the same colour for every element, but to make each one slightly transparent. The nested
s that we are working with could be compared to layers in Photoshop. By applying a semi-transparent shade of grey, each successive layer can build on top of the darker layers beneath it. The effect accumulates, causing each successive layer to appear slightly darker than the last. In his 2009 article for 24 ways, Drew McLellan showed how to create a semi-transparent effect by working with RGBA colour. Here, we’ll use the colour black with an alpha value of 0.07. #container div { background-color: rgba(0,0,0,0.07) } Note that I haven’t used the immediate child selector here, which means that this rule will apply to all
elements inside the #container, no matter how deeply nested they are. You can view the result in Demo Two. As you can see, the golden rectangles alternate between landscape and portrait orientation. Demo Three). CSS3 specification indicates that a percentage can be used to set the border-radius property, but using percentages does not achieve consistent results in browsers today. Luckily, if you specify a border-radius in pixels using a value that is greater than the width and height of the element, then the resulting curve will use the shorter length side as its radius. This produces exactly the effect that we want, so we’ll use an arbitrarily high value of 10,000 pixels for each border-radius: .cycle { border-radius: 0px; border-bottom-left-radius: 10000px; } .cycle > div { border-radius: 0px; border-bottom-right-radius: 10000px; } .cycle > div > div { border-radius: 0px; border-top-right-radius: 10000px; } .cycle > div > div > div { border-radius: 0px; border-top-left-radius: 10000px; } Note that the specification for the border-radius property is still in flux, so it is advisable to use vendor-specific prefixes. I have omitted them from the example above for the sake of clarity, but if you view source on Demo Four then you’ll see that the actual styles are not quite as brief. Filling the available space We have created an approximation of the Golden Spiral using only HTML and CSS. Neat! It’s a shame that it occupies just a fraction of the available space. As a finishing touch, let’s make the golden spiral expand or contract to use the full space available to it. Ideally, the outermost container should use the full available width or height that could accomodate a rectangle of golden proportions. This behaviour is available for background images using the “ background-size: contain; property, but I know of no way to make block level HTML elements behave in this fashion (if I’m missing something, please enlighten me). Where CSS fails to deliver, JavaScript can usually provide a workaround. This snippet requires jQuery: $(document).ready(function() { var phi = (1 + Math.sqrt(5))/2; $(window).resize(function() { var goldenWidth = windowWidth = $(this).width(), goldenHeight = windowHeight = $(this).height(); if (windowWidth/windowHeight > phi) { // panoramic viewport – use full height goldenWidth = windowHeight * phi; } else { // portrait viewport – use full width goldenHeight = windowWidth / phi; }; $(""#container > div.cycle"") .width(goldenWidth) .height(goldenHeight); }).resize(); }); You can view the result by visiting Demo Five. Is it just me, or can you see an elephant in there? You can probably think of many ways to enhance this further, but for this study we’ll leave it there. It has been a good excuse to play with proportions, positioning and the immediate child selector, as well as new CSS3 features such as border-radius and RGBA colours. If you are not already designing with golden proportions, then perhaps this will inspire you to begin.",2010,Drew Neil,drewneil,2010-12-07T00:00:00+00:00,https://24ways.org/2010/golden-spirals/,design 323,Introducing UDASSS!,"Okay. What’s that mean? Unobtrusive Degradable Ajax Style Sheet Switcher! Boy are you in for treat today ‘cause we’re gonna have a whole lotta Ajaxifida Unobtrucitosity CSS swappin’ Fun! Okay are you really kidding? Nope. I’ve even impressed myself on this one. Unfortunately, I don’t have much time to tell you the ins and outs of what I actually did to get this to work. We’re talking JavaScript, CSS, PHP…Ajax. But don’t worry about that. I’ve always believed that a good A.P.I. is an invisible A.P.I… and this I felt I achieved. The only thing you need to know is how it works and what to do. A Quick Introduction Anyway… First of all, the idea is very simple. I wanted something just like what Paul Sowden put together in Alternative Style: Working With Alternate Style Sheets from Alistapart Magazine EXCEPT a few minor (not-so-minor actually) differences which I’ve listed briefly below: Allow users to switch styles without JavaScript enabled (degradable) Preventing the F.O.U.C. before the window ‘load’ when getting preferred styles Keep the JavaScript entirely off our markup (no onclick’s or onload’s) Make it very very easy to implement (ok, Paul did that too) What I did to achieve this was used server-side cookies instead of JavaScript cookies. Hence, PHP. However this isn’t a “PHP style switcher” – which is where Ajax comes in. For the extreme technical folks, no, there is no xml involved here, or even a callback response. I only say Ajax because everyone knows what ‘it’ means. With that said, it’s the Ajax that sets the cookies ‘on the fly’. Got it? Awesome! What you need Luckily, I’ve done the work for you. It’s all packaged up in a nice zip file (at the end…keep reading for now) – so from here on out, just follow these instructions As I’ve mentioned, one of the things we’ll be working with is PHP. So, first things first, open up a file called index and save it with a ‘.php’ extension. Next, place the following text at the top of your document (even above your DOCTYPE) add('css/global.css','screen,projection'); // [Global Styles] $styleSheet->add('css/preferred.css','screen,projection','Wog Standard'); // [Preferred Styles] $styleSheet->add('css/alternate.css','screen,projection','Tiny Fonts',true); // [Alternate Styles] $styleSheet->add('css/alternate2.css','screen,projection','Big O Fonts',true); // // [Alternate Styles] $styleSheet->getPreferredStyles(); ?> The way this works is REALLY EASY. Pay attention closely. Notice in the first line we’ve included our style-switcher.php file. Next we instantiate a PHP class called AlternateStyles() which will allow us to configure our style sheets. So for kicks, let’s just call our object $styleSheet As part of the AlternateStyles object, there lies a public method called add. So naturally with our $styleSheet object, we can call it to (da – da-da-da!) Add Style Sheets! How the add() method works The add method takes in a possible four arguments, only one is required. However, you’ll want to add some… since the whole point is working with alternate style sheets. $path can simply be a uri, absolute, or relative path to your style sheet. $media adds a media attribute to your style sheets. $title gives a name to your style sheets (via title attribute).$alternate (which shows boolean) simply tells us that these are the alternate style sheets. add() Tips For all global style sheets (meaning the ones that will always be seen and will not be swapped out), simply use the add method as shown next to // [Global Styles]. To add preferred styles, do the same, but add a ‘title’. To add the alternate styles, do the same as what we’ve done to add preferred styles, but add the extra boolean and set it to true. Note following when adding style sheets Multiple global style sheets are allowed You can only have one preferred style sheet (That’s a browser rule) Feel free to add as many alternate style sheets as you like Moving on Simply add the following snippet to the of your web document: drop(); ?> Nothing much to explain here. Just use your copy & paste powers. How to Switch Styles Whether you knew it or not, this baby already has the built in ‘ubobtrusive’ functionality that lets you switch styles by the drop of any link with a class name of ‘altCss‘. Just drop them where ever you like in your document as follows: Bog Standard Small Fonts Large Fonts Take special note where the file is linking to. Yep. Just linking right back to the page we’re on. The only extra parameters we pass in is a variable called ‘css’ – and within that we append the names of our style sheets. Also take very special note on the names of the style sheets have an under_score to take place of any spaces we might have. Go ahead… play around and change the style sheet on the example page. Try disabling JavaScript and refreshing your browser. Still works! Cool eh? Well, I put this together in one night so it’s still a work in progress and very beta. If you’d like to hear more about it and its future development, be sure stop on by my site where I’ll definitely be maintaining it. Download the beta anyway Well this wouldn’t be fun if there was nothing to download. So we’re hooking you up so you don’t go home (or logoff) unhappy Download U.D.A.S.S.S | V0.8 Merry Christmas! Thanks for listening and I hope U.D.A.S.S.S. has been well worth your time and will bring many years of Ajaxy Style Switchin’ Fun! Many Blessings, Merry Christmas and have a great new year!",2005,Dustin Diaz,dustindiaz,2005-12-18T00:00:00+00:00,https://24ways.org/2005/introducing-udasss/,code 62,Being Customer Supportive,"Every day in customer support is an inbox, a Twitter feed, or a software forum full of new questions. Each is brimming with your customers looking for advice, reassurance, or fixes for their software problems. Each one is an opportunity to take a break from wrestling with your own troublesome tasks and assist someone else in solving theirs. Sometimes the questions are straightforward and can be answered in a few minutes with a short greeting, a link to a help page, or a prewritten bit of text you use regularly: how to print a receipt, reset a password, or even, sadly, close your account. More often, a support email requires you to spend some time unpacking the question, asking for more information, and writing a detailed personal response, tailored to help that particular user on this particular day. Here I offer a few of my own guidelines on how to make today’s email the best support experience for both me and my customer. And even if you don’t consider what you do to be customer support, you might still find the suggestions useful for the next time you need to communicate with a client, to solve a software problem with teammates, or even reach out and ask for help yourself. (All the examples appearing in this article are fictional. Any resemblance to quotes from real, software-using persons is entirely coincidental. Except for the bit about Star Wars. That happened.) Who’s TAHT girl I’ll be honest: I briefly tried making these recommendations into a clever mnemonic like FAST (facial drooping, arm weakness, speech difficulties, time) or PAD (pressure, antiseptic, dressing). But instead, you get TAHT: tone, ask, help, thank. Ah, well. As I work through each message in my support queue, I listen to the tone of the email ask clarifying questions bring in extra help as needed and thank the customer when the problem is solved. Let’s open an email and get started! Leave your message at the sound of the tone With our enthusiasm for emoji, it can be very hard to infer someone’s tone from plain text. How much time have you spent pondering why your friend responded with “Thanks.” instead of “Thanks!”? I mean, why didn’t she :grin: or :wink: too? Our support customers, however, are often direct about how they’re feeling: I’m working against a deadline. Need this fixed ASAP!!!! This hasn’t worked in a week and I am getting really frustrated. I’ve done this ten times before and it’s always worked. I must be missing something simple. They want us to understand the urgency of this from their point of view, just as much as we want to help them in a timely manner. How this information is conveyed gives us an instant sense of whether they are frustrated, angry, or confused—and, just as importantly, how frustrated-angry-confused they are. Listen to this tone before you start writing your reply. Here are two ways I might open an email: “I’m sorry that you ran into trouble with this.” “Sorry you ran into trouble with this!” The content is largely the same, but the tone is markedly different. The first version is a serious, staid reaction to the problem the customer is having; the second version is more relaxed, but no less sincere. Matching the tone to the sender’s is an important first step. Overusing exclamation points or dropping in too-casual language may further upset someone who is already having a crummy time with your product. But to a cheerful user, a formal reply or an impersonal form response can be off-putting, and damage a good relationship. When in doubt, I err on the side of being too formal, rather than sending a reply that may be read as flip or insincere. But whichever you choose, matching your correspondent’s tone will make for a more comfortable conversation. Catch the ball and throw it back Once you’ve got that tone on lock, it’s time to tackle the question at hand. Let’s see what our customer needs help with today: I tried everything in the troubleshooting page but I can’t get it to work again. I am on a Mac. Please help. Hmm, not much information here. Now, if I got this short email after helping five other people with the same problem on Mac OS X, I would be sorely tempted to send this customer that common solution in my first reply. I’ve found it’s important to resist the urge to assume this sixth person needs the same answer as the other five, though: there isn’t enough to connect this email to the ones that came before hers. Instead, ask a few questions to start. Invest some time to see if there are other symptoms in common, like so: I’m sorry that you ran into trouble with this! I’ll need a little more information to see what’s happening here. [questions] Thank you for your help. Those questions are customized for the customer’s issue as much as possible, and can be fairly wide-ranging. They may include asking for log files, getting some screenshots, or simply checking the browser and operating system version she’s using. I’ll ask anything that might make a connection to the previous cases I’ve answered—or, just as importantly, confirm that there isn’t a connection. What’s more, a few well-placed questions may save us both from pursuing the wrong path and building additional frustration. (A note on that closing: “Thank you for your help”–I often end an email this way when I’ve asked for a significant amount of follow up information. After all, I’m imposing on my customer’s time to run any number of tests. It’s a necessary step, but I feel that thanking them is a nice acknowledgment we’re in this together.) Having said that, though, let’s bring tone back into the mix: I tried everything in the troubleshooting but I can’t get it to work again. I am on a Mac. I’m working against a deadline. Need this fixed ASAP!!!! This customer wants answers now. I’ll still ask for more details, but would consider including the solution to the previous problem in my initial reply as well. (But only if doing so can’t make the situation worse!) I’m sorry that you ran into trouble with this! I’ll need a little more information to see what’s happening here. [questions] If you’d like to try something in the meantime, delete the file named xyz.txt. (If this isn’t the cause of the problem, deleting the file won’t hurt anything.) Here’s how to find that file on your computer: [steps] Let me know how it goes! In the best case, the suggestion works and the customer is on her way. If it doesn’t solve the problem, you will get more information in answer to your questions and can explore other options. And you’ve given the customer an opportunity to be involved in fixing the issue, and some new tools which might come in handy again in the future. Bring in help The support software I use counts how many emails the customer and I have exchanged, and reports it in a summary line in my inbox. It’s an easy, passive reminder of how long the customer and I have been working together on a problem, especially first thing in the morning when I’m reacquainting myself with my open support cases. Three is the smallest number I’ll see there: the customer sends the initial question (1 email); I reply with an answer (2 emails); the customer confirms the problem is solved (3 emails). But the most complicated, stickiest tickets climb into double-digit replies, and anything that stretches beyond a dozen is worthy of a cheer in Slack when we finally get to the root of the problem and get it fixed. While an extra round of questions and answers will nudge that number higher, it gives me the chance to feel out the technical comfort level of the person I’m helping. If I ask the customer to send some screenshots or log files and he isn’t sure how to do that, I will use that information to adjust my instructions on next steps. I may still ask him to try running a traceroute on his computer, but I’ll break down the steps into a concise, numbered list, and attach screenshots of each step to illustrate it. If the issue at hand is getting complicated, take note if the customer starts to feel out of their depth technically—either because they tell you so directly or because you sense a shift in tone. If that happens, propose bringing some outside help into the conversation: Do you have a network firewall or do you use any antivirus software? One of those might be blocking a connection that the software needs to work properly; here’s a list of the required connections [link]. If you have an IT department in-house, they should be able to help confirm that none of those are being blocked. or: This error message means you don’t have permission to install the software on your own computer. Is there a systems administrator in the office that may be able to help with this? For email-based support cases, I’ll even offer to add someone from their IT department to the thread, so we can discuss the problem together rather than have the customer relay questions and answers back and forth. Similarly, there are occasionally times when my way of describing things doesn’t fit how the customer understands them. Rather than bang our heads against our keyboards, I will ask one of my support colleagues to join the conversation from our side, and see if he can explain things more clearly than I’ve been able to do. We appreciate your business. Please call again And then, o frabjous day, you get your reward: the reply which says the problem has been solved. That worked!! Thank you so much for saving my day! I wish I could send you some cookies! If you were here, I would give you my tickets to Star Wars. [Reply is an animated gif.] Sometimes the reply is a bit more understated: That fixed it. Thanks. Whether the customer is elated, satisfied, or frankly happy to be done with emailing support, I like to close longer email threads or short, complicated issues with a final thanks and reminder that we’re here to help: Thank you for the update; I’m glad to hear that solved the problem for you! I hope everything goes smoothly for you now, but feel free to email us again if you run into any other questions or problems. Best, Then mark that support case closed, and move on to the next question. Because even with the most thoughtfully designed software product, there will always be customers with questions for your capable support team to answer. Tone, ask, help, thank So there you have it: TAHT. Pay attention to tone; ask questions; bring in help; thank your customer. (Lack of) catchy mnemonics aside, good customer support is about listening, paying attention, and taking care in your replies. I think it can be summed up beautifully by this quote from Pamela Marie (as tweeted by Chris Coyier): Golden rule asking a question: imagine trying to answer it Golden rule in answering: imagine getting your answer You and your teammates are applying a variation of this golden rule in every email you write. You’re the software ambassadors to your customers and clients. You get the brunt of the problems and complaints, but you also get to help fix them. You write the apologies, but you also have the chance to make each person’s experience with your company or product a little bit better for next time. I hope that your holidays are merry and bright, and may all your support inboxes be light.",2015,Elizabeth Galle,elizabethgalle,2015-12-02T00:00:00+00:00,https://24ways.org/2015/being-customer-supportive/,process 99,A Christmas hCard From Me To You,"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’s details are up date and that you’ve deleted all those nasty clients who never paid on time? It’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… vCard! (See what I did there?) Just in case you’ve been working in a magical toy factory in the upper reaches of Scandinavia for the last few years, I’m going to tell you that now would also be the perfect time to get into microformats. Using the hCard format, we’ll build a very simple web page and markup our contact details in such a way that they’ll be understood by microformats plugins, like Operator or Tails for Firefox, or the cross-browser Microformats Bookmarklet. Oh, and because Christmas is all about dressing up and being silly, we’ll make the whole thing look nice and have a bit of fun with some CSS3 progressive enhancement. If you can’t wait to see what we end up with, you can preview it here. Step 1: Contact Details First, let’s decide what details we want to put on the page. I’d put my full name, my email address, my phone number, and my postal address, but I’d rather not get surprise visits from strangers when I’m fannying about with my baubles, so I’m going to use Father Christmas instead (that’s Santa to you Yanks). Father Christmas fatherchristmas@elliotjaystocks.com 25 Laughingallthe Way Snow Falls Lapland Finland 010 60 58 000 Step 2: hCard Creator Now I’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 hCard Creator and put those pixies to work! Pop in your details and they’ll give you some nice microformatted HTML in turn.
Father Christmas fatherchristmas@elliotjaystocks.com
25 Laughingallthe Way
Snow Falls , Lapland , FI-00101 Finland
010 60 58 000

This hCard created with the hCard creator.

Step 3: Editing The Code One of the great things about microformats is that you can use pretty much whichever HTML tags you want, so just because the hCard Creator Fairies say something should be wrapped in a doesn’t mean you can’t change it to a . Actually, no, don’t do that. That’s not even excusable at Christmas. I personally have a penchant for marking up each line of an address inside a
  • tag, where the parent url retains the class of adr. As long as you keep the class names the same, you’ll be fine.

    Father Christmas

    fatherchristmas@elliotjaystocks.com
    • 25 Laughingallthe Way
    • Snow Falls
    • Lapland
    • FI-00101
    • Finland
    010 60 58 000
    Step 4: Testing The Microformats With our microformats in place, now would be a good time to test that they’re working before we start making things look pretty. If you’re on Firefox, you can install the Operator or Tails extensions, but if you’re on another browser, just add the Microformats Bookmarklet. Regardless of your choice, the results is the same: if you’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’ll never forget where to send those Christmas lists! Step 5: Some Extra Markup One of the first things we’re going to do is put a photo of Father Christmas on the hCard. We’ll be using CSS to apply a background image to a div, so we’ll be needing an extra div with a class name of “photo”. In turn, we’ll wrap the text-based elements of our hCard inside a div cunningly called “text”. Unfortunately, because of the float technique we’ll be using, we’ll have to use one of those nasty float-clearing techniques. I shall call this “christmas-cheer”, since that is what its presence will inevitably bring, of course. Oh, and let’s add a bit of text to give the page context, too:

    Send your Christmas lists my way...

    Father Christmas

    fatherchristmas@elliotjaystocks.com
    • 25 Laughingallthe Way
    • Snow Falls
    • Lapland
    • FI-00101
    • Finland
    010 60 58 000

    A tutorial by Elliot Jay Stocks for 24 Ways

    Background: stock.xchng | Father Christmas: iStockPhoto

    Step 6: Some Christmas Sparkle So far, our hCard-housing web page is slightly less than inspiring, isn’t it? It’s time to add a bit of CSS. There’s nothing particularly radical going on here; just a simple layout, some basic typographic treatment, and the placement of the Father Christmas photo. I’d usually use a more thorough CSS reset like the one found in the YUI or Eric Meyer’s, but for this basic page, the simple * solution will do. Check out the step 6 demo to see our basic styles in place. From this… … to this: Step 7: Fun With imagery Now it’s time to introduce a repeating background image to the element. This will seamlessly repeat for as wide as the browser window becomes. But that’s fairly straightforward. How about having some fun with the Father Christmas image? If you look at the image file itself, you’ll see that it’s twice as wide as the area we can see and contains a ‘hidden’ photo of our rather camp St. Nick. As a light-hearted visual… er… ‘treat’ for users who move their mouse over the image, we move the position of the background image on the “photo” div. Check out the step 7 demo to see it working. Step 8: Progressive Enhancement Finally, this fun little project is a great opportunity for us to mess around with some advanced CSS features (some from the CSS3 spec) that we rarely get to use on client projects. (Don’t forget: no Christmas pressies for clients who want you to support IE6!) Here are the rules we’re using to give some browsers a superior viewing experience: @font-face allows us to use Jos Buivenga’s free font ‘Fertigo Pro’ on all text; text-shadow adds a little emphasis on the opening paragraph; body > p:first-child causes only the first paragraph to receive this treatment; border-radius created rounded corners on our main div and the links within it; and webkit-transition allows us to gently fade in between the default and hover states of those links. And with that, we’re done! You can see the results here. It’s time to customise the page to your liking, upload it to your site, and send out the URL. And do it quickly, because I’m sure you’ve got some last-minute Christmas shopping to finish off!",2008,Elliot Jay Stocks,elliotjaystocks,2008-12-10T00:00:00+00:00,https://24ways.org/2008/a-christmas-hcard-from-me-to-you/,code 145,The Neverending (Background Image) Story,"Everyone likes candy for Christmas, and there’s none better than eye candy. Well, that, and just more of the stuff. Today we’re going to combine both of those good points and look at how to create a beautiful background image that goes on and on… forever! Of course, each background image is different, so instead of agonising over each and every pixel, I’m going to concentrate on five key steps that you can apply to any of your own repeating background images. In this example, we’ll look at the Miami Beach background image used on the new FOWA site, which I’m afraid is about as un-festive as you can get. 1. Choose your image wisely I find there are three main criteria when judging photos you’re considering for repetition manipulation (or ‘repetulation’, as I like to say)… simplicity (beware of complex patterns) angle and perspective (watch out for shadows and obvious vanishing points) consistent elements (for easy cloning) You might want to check out this annotated version of the image, where I’ve highlighted elements of the photo that led me to choose it as the right one. The original image purchased from iStockPhoto. The Photoshopped version used on the FOWA site. 2. The power of horizontal lines With the image chosen and your cursor poised for some Photoshop magic, the most useful thing you can do is drag out the edge pixels from one side of the image to create a kind of rough colour ‘template’ on which to work over. It doesn’t matter which side you choose, although you might find it beneficial to use the one with the simplest spread of colour and complex elements. Click and hold on the marquee tool in the toolbar and select the ‘single column marquee tool’, which will span the full height of your document but will only be one pixel wide. Make the selection right at the edge of your document, press ctrl-c / cmd-c to copy the selection you made, create a new layer, and hit ctrl-v / cmd-v to paste the selection onto your new layer. using free transform (ctrl-t / cmd-t), drag out your selection so that it becomes as wide as your entire canvas. A one-pixel-wide selection stretched out to the entire width of the canvas. 3. Cloning It goes without saying that the trusty clone tool is one of the most important in the process of creating a seamlessly repeating background image, but I think it’s important to be fairly loose with it. Always clone on to a new layer so that you’ve got the freedom to move it around, but above all else, use the eraser tool to tweak your cloned areas: let that handle the precision stuff and you won’t have to worry about getting your clones right first time. In the example below, you can see how I overcame the problem of the far-left tree shadow being chopped off by cloning the shadow from the tree on its right. The edge of the shadow is cut off and needs to be ‘made’ from a pre-existing element. The successful clone completes the missing shadow. The two elements are obviously very similar but it doesn’t look like a clone because the majority of the shape is ‘genuine’ and only a small part is a duplicate. Also, after cloning I transformed the duplicate, erased parts of it, used gradients, and — ooh, did someone mention gradients? 4. Never underestimate a gradient For this image, I used gradients in a similar way to a brush: covering large parts of the canvas with a colour that faded out to a desired point, before erasing certain parts for accuracy. Several of the gradients and brushes that make up the ‘customised’ part of the image, visible when the main photograph layer is hidden. The full composite. Gradients are also a bit of an easy fix: you can use a gradient on one side of the image, flip it horizontally, and then use it again on the opposite side to make a more seamless join. Speaking of which… 5. Sewing the seams No matter what kind of magic Photoshop dust you sprinkle over your image, there will still always be the area where the two edges meet: that scary ‘loop’ point. Fret ye not, however, for there’s help at hand in the form of a nice little cheat. Even though the loop point might still be apparent, we can help hide it by doing something to throw viewers off the scent. The seam is usually easy to spot because it’s a blank area with not much detail or colour variation, so in order to disguise it, go against the rule: put something across it! This isn’t quite as challenging as it may sound, because if we intentionally make our own ‘object’ to span the join, we can accurately measure the exact halfway point where we need to split it across the two sides of the image. This is exactly what I did with the FOWA background image: I made some clouds! A sky with no clouds in an unhappy one. A simple soft white brush creates a cloud-like formation in the sky. After taking the cloud’s opacity down to 20%, I used free transform to highlight the boundaries of the layer. I then moved it over to the right, so that the middle of the layer perfectly aligned with the right side of the canvas. Finally, I duplicated the layer and did the same in reverse: dragging the layer over to the left and making sure that the middle of the duplicate layer perfectly aligned with the left side of the canvas. And there you have it! Boom! Ta-da! Et Voila! To see the repeating background image in action, visit futureofwebapps.com on a large widescreen monitor or see a simulation of the effect. Thanks for reading, folks. Have a great Christmas!",2007,Elliot Jay Stocks,elliotjaystocks,2007-12-03T00:00:00+00:00,https://24ways.org/2007/the-neverending-background-image-story/,code 170,"A Pet Project is For Life, Not Just for Christmas","I’m excited: as December rolls on, I’m winding down from client work and indulging in a big pet project I’ve been dreaming up for quite some time, with the aim of releasing it early next year. I’ve always been a bit of a sucker for pet projects and currently have a few in the works: the big one, two collaborations with friends, and my continuing (and completely un-web-related) attempt at music. But when I think about the other designers and developers out there whose work I admire, one thing becomes obvious: they’ve all got pet projects! Look around the web and you’ll see that anyone worth their salt has some sort of side project on the go. If you don’t have yours yet, now’s the time! Have a pet project to collaborate with your friends It’s not uncommon to find me staring at my screen, looking at beautiful websites my friends have made, grinning inanely because I feel so honoured to know such talented individuals. But one thing really frustrates me: I hardly ever get to work with these people! Sure, there are times when it’s possible to do so, but due to various project situations, it’s a rarity. So, in order to work with my friends, I’ve found the best way is to instigate the collaboration outside of client work; in other words, have a pet project together! Free from the hard realities of budgets, time restraints, and client demands, you and your friends can come up with something purely for your own pleasures. If you’ve been looking for an excuse to work with other designers or developers whose work you love, the pet project is that excuse. They don’t necessarily have to be friends, either: if the respect is mutual, it can be a great way of breaking the ice and getting to know someone. Figure 1: A forthcoming secret love-child from myself and Tim Van Damme Have a pet project to escape from your day job We all like to moan about our clients and bosses, don’t we? But if leaving your job or firing your evil client just isn’t an option, why not escape from all that and pour your creative energies into something you genuinely enjoy? It’s not just about reacting to negativity, either: a pet project is a great way to give yourself a bit of variety. As web designers, our day-to-day work forces us to work within a set of web-related contraints and sometimes it can be demoralising to spend so many hours fixing IE bugs. The perfect antidote? Go and do some print design! If it’s not possible in your day job or client work, the pet project is the perfect place to exercise your other creative muscles. Yes, print design (or your chosen alternative) has its own constraints, but if they’re different to those you experience on a daily basis, it’ll be a welcome relief and you’ll return to your regular work feeling refreshed. Figure 2: Ligature, Loop & Stem, from Scott Boms & Luke Dorny Have a pet project to fulfill your own needs Many pet projects come into being because the designers and/or developers behind them are looking for a tool to accomplish a task and find that it doesn’t exist, thus prompting them to create their own solution. In fact, the very app I’m using to write this article — Ommwriter, from Herraiz Soto & Co — was originally a tool they’d created for their internal staff, before releasing it to the public so that it could be enjoyed by others. Just last week, Tina Roth Eisenberg launched Teux Deux, a pet project she’d designed to meet her own requirements for a to-do list, having found that no existing apps fulfilled her needs. Oh, and it was a collaboration with her studio mate Cameron. Remember what I was saying about working with your friends? Figure 3: Teux Deux, the GTD pet project that launched just last week Have a pet project to help people out Ommwriter and Teux Deux are free for anyone to use. Let’s just think about that for a moment: the creators have invested their time and effort in the project, and then given it away to be used by others. That’s very cool and something we’re used to seeing a lot of in the web community (how lucky we are)! People love free stuff and giving away the fruits of your labour will earn you major kudos. Of course, there’s nothing wrong with making some money, either — more on that in a second. Figure 4: Dan Rubin‘s extremely helpful Make Photoshop Faster Have a pet project to raise your profile So, giving away free stuff earns you kudos. And kudos usually helps you raise your profile in the industry. We all like a bit of shameless fame, don’t we? But seriously, if you want to become well known, make something cool. It could be free (to buy you the love and respect of the community) or it could be purchasable (if you’ve made something that’s cool enough to deserve hard-earned cash), but ultimately it needs to be something that people will love. Figure 5: Type designer Jos Buivenga has shot to fame thanks to his beautiful typefaces and ‘freemium’ business model If you’re a developer with no design skills, team up with a good designer so that the design community appreciate its aesthetic. If you’re a designer with no development skills, team up with a good developer so that it works. Oh, and not that I’d recommend you ever do this for selfish reasons, but collaborating with someone you admire — whose work is well-respected by the community — will also help raise your profile. Have a pet project to make money In spite of our best hippy-esque intentions to give away free stuff to the masses, there’s also nothing wrong with making a bit of money from your pet project. In fact, if your project involves you having to make a considerable financial investment, it’s probably a good idea to try and recoup those costs in some way. Figure 6: The success of Shaun Inman‘s various pet projects — Mint, Fever, Horror Vacui, etc. — have allowed him to give up client work entirely. A very common way to do that in both the online and offline worlds is to get some sort of advertising. For a slightly different approach, try contacting a company who are relevant to your audience and ask them if they’d be interesting in sponsoring your project, which would usually just mean having their brand associated with yours in some way. This is still a form of advertising but tends to allow for a more tasteful implementation, so it’s worth pursuing. Advertising is a great way to cover your own costs and keep things free for your audience, but when costs are considerably higher (like if you’re producing a magazine with high production values, for instance), there’s nothing wrong with charging people for your product. But, as I mentioned above, you’ve got to be positive that it’s worth paying for! Have a pet project just for fun Sometimes there’s a very good reason for having a pet project — and sometimes even a viable business reason — but actually you don’t need any reason at all. Wanting to have fun is just as worthy a motivation, and if you’re not going to have fun doing it, then what’s the point? Assuming that almost all pet projects are designed, developed, written, printed, marketed and supported in our free time, why not do something enjoyable? Figure 7: Jessica Hische‘s beautiful Daily Drop Cap In conclusion The fact that you’re reading 24 ways shows that you have a passion for the web, and that’s something I’m happy to see in abundance throughout our community. Passion is a term that’s thrown about all over the place, but it really is evident in the work that people do. It’s perhaps most evident, however, in the pet projects that people create. Don’t forget that the very site you’re reading this article on is… a pet project. If you’ve yet to do so, make it a new year’s resolution for 2010 to have your own pet project so that you can collaborate with your friends, escape from your day job, fulfil your own needs, help people out, raise your profile, make money, and — above all — have fun.",2009,Elliot Jay Stocks,elliotjaystocks,2009-12-18T00:00:00+00:00,https://24ways.org/2009/a-pet-project-is-for-life-not-just-for-christmas/,business 270,From Side Project to Not So Side Project,"In the last article I wrote for 24 ways, back in 2009, I enthused about the benefits of having a pet project, suggesting that we should all have at least one so that we could collaborate with our friends, escape our day jobs, fulfil our own needs, help others out, raise our profiles, make money, and — most importantly — have fun. I don’t think I need to offer any further persuasions: it seems that designers and developers are launching their own pet projects left, right and centre. This makes me very happy. However, there still seems to be something of a disconnect between having a side project and turning it into something that is moderately successful; in particular, the challenge of making enough money to sustain the project and perhaps even elevating it from the sidelines so that it becomes something not so on the side at all. Before we even begin this, let’s spend a moment talking about money, also known as… Evil, nasty, filthy money Over the last couple of years, I’ve started referring to myself as an accidental businessman. I say accidental because my view of the typical businessman is someone who is driven by money, and I usually can’t stand such people. Those who are motivated by profit, obsessed with growth, and take an active interest in the world’s financial systems don’t tend to be folks with whom I share a beer, unless it’s to pour it over them. Especially if they’re wearing pinstriped suits. That said, we all want to make money, don’t we? And most of us want to make a relatively decent amount, too. I don’t think there’s any harm in admitting that, is there? Hello, I’m Elliot and I’m a capitalist. The key is making money from doing what we love. For most people I know in our community, we’ve already achieved that — I’m hard-pressed to think of anyone who isn’t extremely passionate about working in our industry and I think it’s one of the most positive, unifying benefits we enjoy as a group of like-minded people — but side projects usually arise from another kind of passion: a passion for something other than what we do as our day jobs. Perhaps it’s because your clients are driving you mental and you need a break; perhaps it’s because you want to create something that is truly your own; perhaps it’s because you’re sick of seeing your online work disappear so fast and you want to try your hand at print in order to make a more permanent mark. The three factors I listed there led me to create 8 Faces, a printed magazine about typography that started as a side project and is now a very significant part of my yearly output and income. Like many things that prove fruitful, 8 Faces’ success was something of an accident, too. For a start, the magazine was never meant to be profitable; its only purpose at all was to scratch my own itch. Then, after the first issue took off and I realized how much time I needed to spend in order to make the next one decent, it became clear that I would have to cover more than just the production costs: I’d have to take time out from client work as well. Doing this meant I’d have to earn some money. Probably not enough to equate to the exact amount of time lost when I could be doing client work (not that you could ever describe time as being lost when you work on something you love), but enough to survive; for me to feel that I was getting paid while doing all of the work that 8 Faces entailed. The answer was to raise money through partnerships with some cool companies who were happy to be associated with my little project. A sustainable business model Business model! I can’t believe I just wrote those words! But a business model is really just a loose plan for how not to screw up. And all that stuff I wrote in the paragraph above about partnering with companies so I could get some money in while I put the magazine together? Well, that’s my business model. If you’re making any product that has some sort of production cost, whether that’s physical print run expenses or up-front dev work to get an app built, covering those costs before you even release your product means that you’ll be in profit from the first copy you sell. This is no small point: production expenses are pretty much the only cost you’ll ever need to recoup, so having them covered before you launch anything is pretty much the best possible position in which you could place yourself. Happy days, as Jamie Oliver would say. Obtaining these initial funds through partnerships has another benefit. Sure, it’s a form of advertising but, done right, your partners can potentially provide you with great content, too. In the case of 8 Faces, the ads look as nice as the rest of the magazine, and a couple of our partners also provide proper articles: genuinely meaningful, relevant, reader-pleasing articles at that. You’d be amazed at how many companies are willing to become partners and, as the old adage goes, if you don’t ask, you don’t get. With profit comes responsibility Don’t forget about the responsibility you have to your audience if you engage in a relationship with a partner or any type of advertiser: although I may have freely admitted my capitalist leanings, I’m still essentially a hairy hippy, and I feel that any partnership should be good for me as a publisher, good for the partner and — most importantly — good for the reader. Really, the key word here is relevance, and that’s where 99.9% of advertising fails abysmally. (99.9% is not a scientific figure, but you know what I’m on about.) The main grey area when a side project becomes profitable is how you share that profit, partly because — in my opinion, at least — the transition from non-profitable side project to relatively successful source of income can be a little blurred. Asking for help for nothing when there’s no money to be had is pretty normal, but sometimes it’s easy to get used to that free help even once you start making money. I believe the best approach is to ask for help with the promise that it will always be rewarded as soon as there’s money available. (Oh, god: this sounds like one of those nightmarish client proposals. It’s not, honest.) If you’re making something cool, people won’t mind helping out while you find your feet. Events often think that they’re exempt from sharing profit. Perhaps that’s because many event organizers think they’re doing the speakers a favour rather than the other way around (that’s a whole separate article), but it’s shocking to see how many people seem to think they can profit from content-makers — speakers, for example — and yet not pay for that content. It was for this reason that Keir and I paid all of our speakers for our Insites: The Tour side project, which we ran back in July. We probably could’ve got away without paying them, especially as the gig was so informal, but it was the right thing to do. In conclusion: money as a by-product Let’s conclude by returning to the slightly problematic nature of money, because it’s the pivot on which your side project’s success can swing, regardless of whether you measure success by monetary gain. I would argue that success has nothing to do with profit — it’s about you being able to spend the time you want on the project. Unfortunately, that is almost always linked to money: money to pay yourself while you work on your dream idea; money to pay for more servers when your web app hits the big time; money to pay for efforts to get the word out there. The key, then, is to judge success on your own terms, and seek to generate as much money as you see fit, whether it’s purely to cover your running costs, or enough to buy a small country. There’s nothing wrong with profit, as long as you’re ethical about it. (Pro tip: if you’ve earned enough to buy a small country, you’ve probably been unethical along the way.) The point at which individuals and companies fail — in the moral sense, for sure, but often in the competitive sense, too — is when money is the primary motivation. It should never be the primary motivation. If you’re not passionate enough about something to do it as an unprofitable side project, you shouldn’t be doing it all. Earning money should be a by-product of doing what you love. And who doesn’t want to spend their life doing what they love?",2011,Elliot Jay Stocks,elliotjaystocks,2011-12-22T00:00:00+00:00,https://24ways.org/2011/from-side-project-to-not-so-side-project/,business 17,Bringing Design and Research Closer Together,"The ‘should designers be able to code’ debate has raged for some time, but I’m interested in another debate: should designers be able to research? Are you a designer who can do research? Good research and the insights you uncover inspire fresh ways of thinking and get your creative juices flowing. Good research brings clarity to a woolly brief. Audience insight helps sharpen your focus on what’s really important. Experimentation through research and design brings a sense of playfulness and curiosity to your work. Good research helps you do good design. Being a web designer today is pretty tough, particularly if you’re a freelancer and work on your own. There are so many new ideas, approaches to workflow and trends and tools to keep up with. How do you decide which things to do and which to ignore? A modern web designer needs to be able to consider the needs of the audience, design appropriate IAs and layouts, choose colour palettes, pick appropriate typefaces and type layouts, wrangle with content, style, code, dabble in SEO, and the list goes on and on. Not only that, but today’s web designer also has to keep up with the latest talking points in the industry: responsive design, Agile, accessibility, Sass, Git, lean UX, content first, mobile first, blah blah blah. Any good web designer doesn’t need to be persuaded about the merits of including research in their toolkit, but do you really have time to include research too? Who is responsible for research? Generally, research in the web industry forms part of other disciplines and isn’t so much a discipline in its own right. It’s very often thought of as part of UX, or activities that make up a process such as IA or content strategy. Research is often undertaken by UX designers, information architects or content strategists and isn’t something designers or developers get that involved in. Some people lump all of these activities together and label it design research and have design researchers to do it. Some companies, such as the one I run with my husband Mark, are lucky enough to have someone with specialist research knowledge (yup, that would be me folks) who can lead all or most of the research work undertaken by the company. See also Mule Design, GOV.UK, the BBC, Mailchimp, Facebook and Twitter. What if you’re not lucky enough to have your own researcher or team of researchers? Often research is the kind of thing that’s nice to have, or it can be cut from scope when doing the budget dance with a client. It often forms part of the discovery phase of a project and sometimes just becomes a tick-box exercise. But research isn’t just user testing and it shouldn’t just live in a report on Basecamp that no one reads. I would argue that research and experimentation is a way of working or an approach to how you design. Research can be used during the whole design process and must be a vital part of a designer’s workflow on every project. Even if you work in a small studio, you can still create a culture of audience insight. Even if you work on your own, you can still absorb yourself in as much audience data as you can throughout the project life cycle. Here’s how. Research is everyone’s job There is a subtle difference between writing a research report and delivering it to a client, and them actually using it and applying the insights to their thought process. In my experience of working in the audiences team at the BBC, research was most effective when the role was embedded in the production team and insights were used as part of the editorial process. In this section I’ll talk through some common problems you might encounter in a typical project life cycle and show you ways you can use research to help you. For the sake of this article, let’s imagine that we’re talking about a particular project here and not ongoing product development. The same principles can of course be applied then, but even if you work in-house rather than on the agency side, you’re probably used to working on distinct projects or phases of work. 1. Problem: I want to come up with a new product idea. Solution: Inspiration through insights. Before you begin a new project, a good way of quickly absorbing all the existing knowledge that there maybe about a theme, product type or website is to literally surround yourself with it. This is especially relevant for new ideas or product development. Create an incident room if you can: fill the walls of your meeting room, the walls near your desk, or even just use a pinboard or online pinboard if space is tight or you’re working with a dispersed team. The same process can be used throughout a project’s or product life cycle — read about how MailChimp has applied this idea. Let’s take a new product idea as an example. Say you wanted to develop a responsive tool for web designers but you weren’t sure what aspect of responsive design to focus on. First of all, you should pose a hypothesis or problem statement to gather ideas around. For example: “How to speed up a designer’s responsive workflow.” You would then need to gather insights around this topic. You could run some interviews with freelance designers about how they work responsively. You could shadow a development team for the day to understand their processes. You could observe conversations on Twitter or IRC or wherever your target audience interact to see what people talk about. You could search out industry data and articles currently available. The next stage is to comb through this data and extract insights from it. You can use good old Post-it notes and a sharpie: capture one insight or thought per Post-it. If one insight leads into another, use two Post-its. The objective is volume. Try to ensure clarity in each Post-it so you don’t have to go back and reference material again (maybe you could use a key if you think it’ll get confusing). After this, stick them all up and synthesise the same way you would for any kind of cluster or affinity sort. Organise into broad themes. These themes then become springboards for further exploration and idea generation. You might see a gap or opportunity in one particular area, both from a workflow perspective but also from a business perspective. Bingo. Your insights then become the fuel for ideas generation. This method doesn’t just have to be used for new products — it works particularly well in a discovery phase for new projects or for new features in an existing product. We’re doing something similar for our own responsive tool, Gridset at the moment. Resources: Sticky Wisdom by Dave Allan, Matt Kingdon, Kris Murrin, Daz Rudkin The Science of Serendipity by Matt Kingdon The Art of Innovation by Tom Kelley 2. Problem: You’re starting a new project and need to know the basics before you get headlong into designing or building. Solution: Quantitative survey. Common questions might be: Who are the users? How many are there? What are they like? Why do they use the site? What do they need from the site? What are their goals? Print out and stick up what you already know and have in your project space or ‘incident room’: any reports you have found or been given, analytics graphs, personas, pen portraits, as well as screengrabs of the current website, product or branding. Spend time looking through it all and identify the gaps. If you have very little existing audience data, a quick and easy way to get some baseline information is to run a quick user survey on a current website. You can establish basic demographic information, appreciation and views of the website as it stands, as well as delve a little deeper into needs and wants. This is also vital if you want some kind of trackable measures to go back to once you have designed and built your shiny new website for your client — read more in my article for 24 ways last year.) We use surveys a lot at Mark Boulton Design for our client work. Here’s a screen grab of one we ran in March on http://info.cern.ch before we redesigned the site and did the work on the First Website Project. We repeated the survey after the new website went live and were able to compare the results. Both surveys were a great source of insight to the project team as well as for the project stakeholders who needed to pitch the idea of the hack days and fundraise for them. Once you’ve run your survey, you should always write up a short summary for yourself and your client to refer to. If you’re not a trained researcher, you should try to read up on analysis techniques or data visualisation. It can be easy to misinterpret data and make it bend to the story you are trying to tell. You should be looking for the story in the data and present it without bias. If you’re using the ‘incident room’ method I mentioned earlier on, you can also extract the insights onto post it notes and add them to your growing body of knowledge. Resources: Using Questionnaires for Design Research by Emma Boulton Data-driven Design with an Annual Survey by Aarron Walter Research Methods for Product Design by Alex Milton and Paul Rodgers A Practical Guide to Designing with Data by Brian Suda 3. Problem: You have a prototype of a new design and you need some feedback from real users. Solution: User interviews and task based testing. Interviewing is a staple research method that every designer should master as it can be used throughout a project life cycle. Erika Hall recently wrote a great article on the basics for A List Apart. From stakeholder interviews in a discovery phase, to initial user research, right through to task based testing and iteration, interviews can be enormously helpful. They are very time-consuming, however, and although speaking to someone is better than speaking to no one, it’s always better to plan to do a few interviews at once, rather than one or two. I generally find that patterns only start to emerge after I’ve spoken to 4 or 5 people. Interviews are another thing we do a lot of at Mark Boulton Design. Most of the interviews we do are remote due to the location of our clients and their users. Rigour is an important consideration in all research activities and especially if you’re a non-researcher. Interviews particularly can be easily skewed by an inexperienced facilitator, which is why pairing can be a good approach. Building rapport, questioning, time keeping, note taking and thinking on your feet can be difficult to do all at once, so having a colleague take notes while you concentrate on leading the conversation can work really well. It’s important for the note taker to sit in on more than one interview so that they get a more rounded view of the feedback. The same person should also be involved in the analysis of the data. Interviews can be analysed and written up in a report or summary as with other types of research. I often use the same kind of collaborative process detailed earlier for deciding on themes, particularly if multiple members of the team have been involved in interviewing. Interviews are particularly useful for our incident room and can provide much colour and insight to an exploratory process. I often find verbatim quotes to be the most insightful type of data. You might find that an inexperienced researcher (or designer who is used to solving problems) will jump to interpretation too soon and forget to just listen to what the interviewee is saying. Capturing the exact form of words a person uses can help get away from this. Resources: Interviewing Humans by Erika Hall A Pocket Guide to Interviewing for Research by Andrew Travers Interviewing Users by Steve Portigal 4. Problem: How successful have I been with this new design? Solution: Key performance indicators Once your new design has been realised, it’s important to evaluate it. What works, what doesn’t work so well? As well as a straightforward design crit, don’t forget to introduce audience insights into a review meeting or project wash up. Work out what your KPIs — your key performance indicators — will be beforehand and then you can start to track them over time. For example, number of visits, appreciation of the site, willingness to recommend the site to a friend, number of sales, and number of conversions are all sensible measures to track. Interviews can again be helpful but cold, hard numbers are often better here. Read Corey Vilhauer’s take on this on A List Apart. Consistency is key here. If you have looked at your analytics and done a survey beforehand, you will have a baseline to start from. Don’t keep changing your measures and questions, or your data will not be comparable. Pick a few key questions or a set of measures, create a survey and then run it once a month, once a quarter, every six months or annually. You’ll start to see changes over time as the design beds in. You may see seasonal trends and spot patterns in the data related to other activities like marketing, promotion and so on. Keeping a record of all of this will increase your understanding of your audience. We’ve created a satisfaction survey for Gridset with a number of measures that we track on an ongoing basis. MailChimp has also created an annual survey with the aim of tracking their audience measures over time Resources: Search Analytics by Louis Rosenfeld A Primer on A/B Testing by Lara Swanson Lean UX by Jeff Gothelf Anyone can do research Research can be brought into the project life cycle at any stage. And of course, anyone can do research — you don’t need to be a researcher. Some of the main skills most designers possess are also key research skills: inquisitive nature, problem solving, playfulness, empathy, and so on. We have a small team at Mark Boulton Design. Most of the team are designers and the rest of us focus on supporting the team and clients both in terms of billable work (research, content strategy, project management) as well as the non-billable things like finance and studio management. Despite my best intentions, in the past I’ve undertaken research for clients in isolation — first being briefed by the design lead, carrying out the research and then delivering the findings back, trusting the design team to take the findings on board. This was often due to time and availability of resources. We’ve been trying hard to join up our processes and collaborate even more across the team. Undertaking heuristic or design reviews collaboratively; taking part in frequent critiques of our work and the work of others together; pairing a researcher and a designer to run interviews; workshopping results from interviews to come up with recommendations; working closely together on questionnaire design; shadowing each other on tasks that don’t fall within our core skills. A little thing like moving our desks around has also helped us have more conversations that we can all be a part of. I’ve come to the conclusion that my role as the research director at Mark Boulton Design is actually a facilitator of research. As well as carrying out research, I am responsible for ensuring that research happens consistently across the team. I am responsible for empowering and training our designers so they feel confident in carrying out their own user, audience or design research for clients. So they know what to look for, when to listen, when to probe and when to take note of something. So they know how to look for themes, how to synthesise insights from research and how to apply them to their work. Better research leads to better design So, are you a designer who can do research? Are you a researcher who can design? The best designers are a lucky combination of researcher and designer. If you’re not one of those, look at ways of enhancing the skills you lack. Because there’s no doubt in my mind, that becoming a better researcher will make you a better designer. General resources: Seeing the Elephant by Louis Rosenfeld Connected UX by Aarron Walter Beyond Usability Testing by Devan Goldstein Just Enough Research by Erika Hall The User Experience Team of One by Leah Buley Undercover User Experience Design by Cennydd Bowles and James Box A Pocket Guide to Psychology for Designers by Joe Leech A Pocket Guide to International User Research by Chui Chui Tan Remote Research by Nate Bolt and Tony Tulathimutte A Pocket Guide to Experiments for Designers by Colin McFarland",2013,Emma Boulton,emmaboulton,2013-12-22T00:00:00+00:00,https://24ways.org/2013/bringing-design-and-research-closer-together/,ux 94,Using Questionnaires for Design Research,"How do you ask the right questions? In this article, I share a bunch of tips and practical advice on how to write and use your own surveys for design research. I’m an audience researcher – I’m not a designer or developer. I’ve spent much of the last thirteen years working with audience data both in creative agencies and on the client-side. I’m also a member of the Market Research Society. I run user surveys and undertake user research for our clients at the design studio I run with my husband – Mark Boulton Design. So let’s get started! Who are you designing for? Good web designers and developers appreciate the importance of understanding the audience they are designing or building a website or app for. I’m assuming that because you are reading a quality publication like 24 ways that you fall into this category, and so I won’t begin this article with a lecture. Suffice it to say, it’s a good idea to involve research of some sort during the life cycle of every project you undertake. I don’t just mean visual or competitor research, which of course is also very important. I mean looking at or finding your own audience or user data. Whether that be auditing existing data or research available from the client, carrying out user interviews, A/B testing, or conducting a simple questionnaire with users, any research is better than none. If you create personas as a design tool, they should always be based on research, so you will need to have plenty of data to hand for that. Where do I start? In the initial kick-off stages of a project, it’s a good idea to start by asking your client (when working in-house you still have a client – you might even be the client) what research or audience data they have available. Some will have loads – analytics, surveys, focus groups and insights – from talking to customers. Some won’t have much at all and you’ll be hard pressed to find out much about the audience. It’s best to review existing research first without rushing headlong into doing new research. Get a picture of what the data tells you and perhaps get this into a document – who, what, why and how are they using this website or app? What gaps are there in existing research? What else do you need to know? Then you can decide what else you need to do to plug these gaps. Think about the information first before deciding on the methodology. The rest of my article talks mostly about running self-completion online surveys. You can of course do face-to-face surveys, self-completion written questionnaires or phone polls, but I won’t cover those here. That’s for another article. Why run a survey? Surveys are great for getting a broad picture of your audience. As long as they are designed carefully, you can create an overview of them, how they use the site and their opinions of it, with an idea of which parts of this picture are more important than others. By using a limited amount of open-ended questions, you can also get some more qualitative feedback or insights on your website or app. The clients we work with surprisingly often don’t have much in the way of audience research available, even basic analytics, so I will often suggest running a short survey, just to create a picture of who is out there. OK, what should I do first? Before you rush into writing questions, stop and think about what you’re trying to find out. Remember being in school when you studied science and you had to propose a hypothesis? This could be a starting point – something to prove or disprove. Or, even better, write a research brief. It doesn’t have to be long; it can be just a sentence that encapsulates what you’re trying to do, like a good creative brief. For the purposes of this article, I created a short, slightly silly survey on Christmas and beliefs in Father Christmas. My research brief was: To find out more about people’s beliefs about Father Christmas and their experiences of Christmas. Inevitably, as you start thinking of what questions to ask, you will find that you go off at tangents or your client will want you to add in everything but the kitchen sink. In order for your questionnaire not to get too long and lose focus, you could write lists of what it is and what it’s not. This is how I’d apply it to my Christmas questionnaire example: What it is about How people communicate with Father Christmas If someone’s background has affected their likelihood of believing in Father Christmas What it is not about What colour to change Father Christmas’s coat to Father Christmas’s elves Let’s get down to business: the questions. Kinds of questions There are two basic kinds of questions: open-ended and closed. Closed questions limit answers by giving the respondent a number of predefined lists of options to choose from. Typically, these are multiple-choice questions with a list of responses. You can either select one or tick all that apply. Another useful type of closed question I often use is a rating scale, where a respondent can assess a situation along a continuum of values. These can also be useful as a measure of advocacy or strength of feeling about something. There is a standard measure called the Net Promoter score, which measures how likely someone is to recommend your product or service to a friend or acquaintance. It’s a useful benchmark as you can compare your scores to others in a similar sector. Open-ended questions often take the form of a statement which requires a response. Generally, respondents are given a text box to fill in. It’s useful to limit this in some way so that people have an idea of how long the expected response should be; for example, a single line for an email address (Q18), or a larger text area for a longer response (Q6). If you plan to send your survey out to a large number of people, I would suggest using mostly closed questions, unless you want to spend a long time wading through comments and hand-coded responses. I’d always advise adding a general request at the end of a survey (‘Is there anything else you’d like to tell us?’). You’d be surprised how many interesting and insightful comments people will add. There are times when it’s better to provide an open-ended text box rather than a predefined list makes assumptions about your audience’s groupings. For example, we ran a short survey for our Gridset beta testers and rather than assume we knew who they were, we decided to ask an open-ended question: “What is your current job title?” The analysis took quite a bit longer than responses using a predefined list, but it meant that we were able to make sure we didn’t miss anyone. And next time we run a survey for Gridset, I can use the responses gathered from this survey to help create a predefined list to make analysis easier. What to ask The questions to ask depend on what you want to know, but your brief and lists of what the survey is and isn’t should help here. I always ask the design team and client to give me ideas of what they are interested in finding out, and combine this with a mix of new and standard questions I have used in other surveys. I find Survey Monkey’s question bank a very useful source of example questions and help with tricky wording. I always include simple demographics so I can compare my results to the population at large or internet users as a whole – just going on age, gender and location can be quite illuminating. For example, with the Christmas survey, I can see that the respondents were typical of the online design and dev community, mainly young and male. If appropriate, I add questions on disability, ethnic background, religion and community of interest. Questions about ethnicity, religion, sexual preference, disability and other sensitive subjects can feel awkward and difficult to ask. This is not a good reason to not ask them. Perhaps you’re working for a public sector client, like a local council, so it’s likely you will need to consider groups of people who maybe under-represented, who may have differing views to others, or who you need to look at specifically as a subset. How to ask Although they may seem clunky and wordy, it’s often best to use the census wording or professional body wording for such demographic questions. For example, I used the UK census 2011 wording for Wales on my Christmas questionnaire in my questions on religion [PDF] (Q16) and ethnicity [PDF] (Q17). I had to adapt them slightly for the Survey Monkey format – self-completion online, rather than pen and paper – which is why “White Welsh” came up as the first option for the ethnicity question. For similar questions for US audiences, try the Census Bureau website. When conducting a survey for a project that has a global audience, you need to consider who your primary audience is. For example, I recently created a questionnaire for a global news website. A large proportion of its audience is based in the USA, so I was careful to word things in a way Americans would find familiar. I used the US ethnic background census question wording and options, and looked at data for US competitor news websites to decide which to include. You should also consider people whose first language isn’t English. Working as an audience researcher at BBC Wales, every survey we did was bilingual. I’ve also recently run a user survey in Arabic using Google Forms. During this project, we found that while Survey Monkey supports different languages, including Arabic, the text ran left to right with no option to change it to right to left – an essential when it comes to reading Arabic! If research is a deliverable in a client project, and you know you’ll need to conduct it in a foreign language, always build in extra time for translation at both the questionnaire design and analysis stages. Make sure you also allow for plenty of checks. In this case we had to change to Google Forms after initially creating our survey with Survey Monkey to get the functionality we needed. Look and feel Think about the survey as another way your audience will experience your brand. Take care getting the tone of voice right. There are plenty of great articles and books out there about tone of voice – try Letting Go of the Words by Ginny Redish for starters, or Brand Language by Liz Doig. The basic rule of thumb is to sound like a human, and use clear and friendly language. If, like me, you are lucky enough to work with journalists or copy editors, you should ask for their help, particularly in the preamble, linking text and closing statements. I find it helpful to break my questions down into sections and to have a page for each. I then have an introductory piece of text for each section to guide the respondent through the survey. You should also make sure you check with your designers how your survey looks – use a company logo and branding, and make the typography legible. Many survey apps like Survey Monkey and Google Forms have a progress bar. This is helpful for users to see how far through your survey they are. I generally time the survey and give an indication in the preamble: “This survey will only take five minutes of your time.” You also need to think about how you will technically serve the questionnaire. For example, will it be via email, social media, a pop-up or lightbox on your website, or (not recommended but possible) in an ad space? Ethical considerations Something else to think about are any local laws that govern how you collect and store data, such as the Data Protection Act in the UK. As a member of the Market Research Society, I am also obliged to consider its guidelines, but even if you’re not, it’s always a good idea to deal with personal data ethically. If you collect personal data that can identify individuals, you must ask their permission to share it with others, and store it securely for no longer than two years. If you want to contact people afterwards, you must ask for their permission. If you ask for email addresses, as I did in question 18, you have a ready-made sample for a further survey, interviews or focus groups. Remember, you shouldn’t survey people under sixteen years old without the permission of their parents or legal guardians, so if you know your website is likely to be used by children, you must ask for verification of age early on, and your survey should close someone answers that they are under sixteen. The ESOMAR guidelines for online research [PDF] are well worth reading, as they go into detail about such issues, as well as privacy guidelines – using cookies, storing IP addresses, and so on. Tools Unless you work in-house and have proprietary software, or at a market research agency and you’re using specialist software such as Snap or IBM SPSS Statistics (previously just SPSS), you will need to use a good tool to run your survey, collect your responses and, ideally, help with the analysis. I like Survey Monkey because of the question bank and analysis tools. The software graphs your results and does simple cross-tabbing and filtering. What this means is you can slice the data in more interesting ways and delve a bit deeper. For example, in the Gridset questionnaire I mentioned earlier, I cross-tabbed responses to questions against whether a person worked in-house, for an agency or as a freelancer. Other well known online tools that I also use from time to time are Wufoo and Google Forms. Smart Surveys is a similar service to Survey Monkey and it’s used by many leading brands in the UK. Snap Surveys mentioned above is a well-established player in the market research scene, used a lot for face-to-face surveys and also on tablets and smartphones. Analysis Analysis is often overlooked but is as important as the design of the questionnaire. Don’t just rely on looking at the summary report and charts generated as standard by your form or survey software. Spend time with your data. Spend at least a week now and then if you can, looking at the data. Keep coming back to it and tweaking or cutting it a different way to see if there are any different pictures. Slice it up in different ways to reveal new insights. Here is the data from my dummy survey (apart from the open-ended responses). For open-ended questions, you can analyse collaboratively. Print and cut out the open-ended responses and do a cluster analysis or affinity sort with a colleague. Discussing the comments helps you to understand them. You will also find the design team are more likely to buy into the research as they have uncovered the insights for themselves. Always make sure to treat open-ended responses sensitively and don’t share anything publicly in a way that identifies the respondent. Write a report Never hand over a dataset to your client without a summary of the findings. Data on its own can be skewed to suit the reader’s needs, and not everyone is able to find the story in a dataset. Even if it’s not a deliverable, it’s always a good idea to capture your findings in a report of some sort. Use graphs sparingly to show really interesting things or to aid the reader’s understanding. I have written a quick dummy report using the data from the Christmas questionnaire so you can see how it’s done. I highly recommend Brian Suda’s book A Practical Guide to Designing with Data for tips on how to present data effectively, but that’s a subject that benefits a whole article (indeed book) in itself. I am not a designer. I am a researcher, so I never write design recommendations in a report unless they have been talked about or suggested by the designers I work with. More often, I write up the results and we talk about them and what impact they have on the project or design. Often they lead to more questions or further research. So that’s it: a brief introduction to using questionnaires for design research. Here’s a quick summary to remind you what I have talked about, and a list of resources if you’re interested in reading further. Top 10 things to remember when using questionnaires for design research: Start by auditing existing research to identify gaps in data. Write a research brief. Work out exactly what you’re trying to find out – what is the survey about, and what is it not about? The two basic kinds of questions are open-ended and closed. Closed questions limit responses by giving the respondent a number of predefined lists of options to choose from (multiple choice, rating scales, and so on). Open-ended questions are often in the form of a statement which requires a response. Always ask one at the end of a questionnaire. Always include simple demographics to enable you to compare your sample against the population in general. It’s best to use official census or professional body wording for questions on ethnicity, disability and religion. Be sure to think carefully about your tone of voice and the look of your questionnaire. Pay attention to guidelines and laws on storing personal data, cookies and privacy. Invest plenty of time in analysis and report writing. Don’t just look at the obvious – dig deep for more interesting insights. Some useful resources for further study Online research Design Research: Methods and Perspectives edited by Brenda Laurel Online Research Essentials by Brenda Russell and John Purcell Handbook of Online and Social Media Research by Ray Poynter ESOMAR guidelines for online research [PDF] Online questionnaires Market research books on questionnaire design Using Questionnaires in Small-Scale Research: A Beginner’s Guide by Pamela Munn Questionnaire Design by A N Oppenheim Developing a Questionnaire by Bill Gillham",2012,Emma Boulton,emmaboulton,2012-12-14T00:00:00+00:00,https://24ways.org/2012/using-questionnaires-for-design-research/,business 15,Git for Grown-ups,"You are a clever and talented person. You create beautiful designs, or perhaps you have architected a system that even my cat could use. Your peers adore you. Your clients love you. But, until now, you haven’t *&^#^! been able to make Git work. It makes you angry inside that you have to ask your co-worker, again, for that *&^#^! command to upload your work. It’s not you. It’s Git. Promise. Yes, this is an article about the popular version control system, Git. But unlike just about every other article written about Git, I’m not going to give you the top five commands that you need to memorize; and I’m not going to tell you all your problems would be solved if only you were using this GUI wrapper or that particular workflow. You see, I’ve come to a grand realization: when we teach Git, we’re doing it wrong. Let me back up for a second and tell you a little bit about the field of adult education. (Bear with me, it gets good and will leave you feeling both empowered and righteous.) Andragogy, unlike pedagogy, is a learner-driven educational experience. There are six main tenets to adult education: Adults prefer to know why they are learning something. The foundation of the learning activities should include experience. Adults prefer to be able to plan and evaluate their own instruction. Adults are more interested in learning things which directly impact their daily activities. Adults prefer learning to be oriented not towards content, but towards problems. Adults relate more to their own motivators than to external ones. Nowhere in this list does it include “memorize the five most popular Git commands”. And yet this is how we teach version control: init, add, commit, branch, push. You’re an expert! Sound familiar? In the hierarchy of learning, memorizing commands is the lowest, or most basic, form of learning. At the peak of learning you are able to not just analyze and evaluate a problem space, but create your own understanding in relation to your existing body of knowledge. “Fine,” I can hear you saying to yourself. “But I’m here to learn about version control.” Right you are! So how can we use this knowledge to master Git? First of all: I give you permission to use Git as a tool. A tool which you control and which you assign tasks to. A tool like a hammer, or a saw. Yes, your mastery of your tools will shape the kinds of interactions you have with your work, and your peers. But it’s yours to control. Git was written by kernel developers for kernel development. The web world has adopted Git, but it is not a tool designed for us and by us. It’s no Sass, y’know? Git wasn’t developed out of our frustration with managing CSS files in an increasingly complex ecosystem of components and atomic design. So, as you work through the next part of this article, give yourself a bit of a break. We’re in this together, and it’s going to be OK. We’re going to do a little activity. We’re going to create your perfect Git cheatsheet. I want you to start by writing down a list of all the people on your code team. This list may include: developers designers project managers clients Next, I want you to write down a list of all the ways you interact with your team. Maybe you’re a solo developer and you do all the tasks. Maybe you only do a few things. But I want you to write down a list of all the tasks you’re actually responsible for. For example, my list looks like this: writing code reviewing code publishing tested code to your server(s) troubleshooting broken code The next list will end up being a series of boxes in a diagram. But to start, I want you to write down a list of your tools and constraints. This list potentially has a lot of noun-like items and verb-like items: code hosting system (Bitbucket? GitHub? Unfuddle? self-hosted?) server ecosystem (dev/staging/live) automated testing systems or review gates automated build systems (that Jenkins dude people keep referring to) Brilliant! Now you’ve got your actors and your actions, it’s time to shuffle them into a diagram. There are many popular workflow patterns. None are inherently right or wrong; rather, some are more or less appropriate for what you are trying to accomplish. Centralized workflow Everyone saves to a single place. This workflow may mean no version control, or a very rudimentary version control system which only ever has a single copy of the work available to the team at any point in time. Branching workflow Everyone works from a copy of the same place, merging their changes into the main copy as their work is completed. Think of the branches as a motorcycle sidecar: they’re along for the ride and probably cannot exist in isolation of the main project for long without serious danger coming to the either the driver or sidecar passenger. Branches are a fundamental concept in version control — they allow you to work on new features, bug fixes, and experimental changes within a single repository, but without forcing the changes onto others working from the same branch. Forking workflow Everyone works from their own, independent repository. A fork is an exact duplicate of a repository that a developer can make their own changes to. It can be kept up to date with additional changes made in other repositories, but it cannot force its changes onto another’s repository. A fork is a complete repository which can use its own workflow strategies. If developers wish to merge their work with the main project, they must make a request of some kind (submit a patch, or a pull request) which the project collaborators may choose to adopt or reject. This workflow is popular for open source projects as it enforces a review process. Gitflow workflow A specific workflow convention which includes five streams of parallel coding efforts: master, development, feature branches, release branches, and hot fixes. This workflow is often simplified down to a few elements by web teams, but may be used wholesale by software product teams. The original article describing this workflow was written by Vincent Driessen back in January 2010. But these workflows aren’t about you yet, are they? So let’s make the connections. From the list of people on your team you identified earlier, draw a little circle. Give each of these circles some eyes and a smile. Now I want you to draw arrows between each of these people in the direction that code (ideally) flows. Does your designer create responsive prototypes which are pushed to the developer? Draw an arrow to represent this. Chances are high that you don’t just have people on your team, but you also have some kind of infrastructure. Hopefully you wrote about it earlier. For each of the servers and code repositories in your infrastructure, draw a square. Now, add to your diagram the relationships between the people and each of the machines in the infrastructure. Who can deploy code to the live server? How does it really get there? I bet it goes through some kind of code hosting system, such as GitHub. Draw in those arrows. But wait! The code that’s on your development machine isn’t the same as the live code. This is where we introduce the concept of a branch in version control. In Git, a repository contains all of the code (sort of). A branch is a fragment of the code that has been worked on in isolation to the other branches within a repository. Often branches will have elements in common. When we compare two (or more) branches, we are asking about the difference (or diff) between these two slivers. Often the master branch is used on production, and the development branch is used on our dev server. The difference between these two branches is the untested code that is not yet deployed. On your diagram, see if you can colour-code according to the branch names at each of the locations within your infrastructure. You might find it useful to make a few different copies of the diagram to isolate each of the tasks you need to perform. For example: our team has a peer review process that each branch must go through before it is merged into the shared development branch. Finally, we are ready to add the Git commands necessary to make sense of the arrows in our diagram. If we are bringing code to our own workstation we will issue one of the following commands: clone (the first time we bring code to our workstation) or pull. Remembering that a repository contains all branches, we will issue the command checkout to switch from one branch to another within our own workstation. If we want to share a particular branch with one of our team mates, we will push this branch back to the place we retrieved it from (the origin). Along each of the arrows in your diagram, write the name of the command you are are going to use when you perform that particular task. From here, it’s up to you to be selfish. Before asking Git what command it would like you to use, sketch the diagram of what you want. Git is your tool, you are not Git’s tool. Draw the diagram. Communicate your tasks with your team as explicitly as you can. Insist on being a selfish adult learner — demand that others explain to you, in ways that are relevant to you, how to do the things you need to do today.",2013,Emma Jane Westby,emmajanewestby,2013-12-04T00:00:00+00:00,https://24ways.org/2013/git-for-grownups/,code 31,Dealing with Emergencies in Git,"The stockings were hung by the chimney with care, In hopes that version control soon would be there. This summer I moved to the UK with my partner, and the onslaught of the Christmas holiday season began around the end of October (October!). It does mean that I’ve had more than a fair amount of time to come up with horrible Git analogies for this article. Analogies, metaphors, and comparisons help the learner hook into existing mental models about how a system works. They only help, however, if the learner has enough familiarity with the topic at hand to make the connection between the old and new information. Let’s start by painting an updated version of Clement Clarke Moore’s Christmas living room. Empty stockings are hung up next to the fireplace, waiting for Saint Nicholas to come down the chimney and fill them with small treats. Holiday treats are scattered about. A bowl of mixed nuts, the holiday nutcracker, and a few clementines. A string of coloured lights winds its way up an evergreen. Perhaps a few of these images are familiar, or maybe they’re just settings you’ve seen in a movie. It doesn’t really matter what the living room looks like though. The important thing is to ground yourself in your own experiences before tackling a new subject. Instead of trying to brute-force your way into new information, as an adult learner constantly ask yourself: ‘What is this like? What does this remind me of? What do I already know that I can use to map out this new territory?’ It’s okay if the map isn’t perfect. As you refine your understanding of a new topic, you’ll outgrow the initial metaphors, analogies, and comparisons. With apologies to Mr. Moore, let’s give it a try. Getting Interrupted in Git When on the roof there arose such a clatter! You’re happily working on your software project when all of a sudden there are freaking reindeer on the roof! Whatever you’ve been working on is going to need to wait while you investigate the commotion. If you’ve got even a little bit of experience working with Git, you know that you cannot simply change what you’re working on in times of emergency. If you’ve been doing work, you have a dirty working directory and you cannot change branches, or push your work to a remote repository while in this state. Up to this point, you’ve probably dealt with emergencies by making a somewhat useless commit with a message something to the effect of ‘switching branches for a sec’. This isn’t exactly helpful to future you, as commits should really contain whole ideas of completed work. If you get interrupted, especially if there are reindeer on the roof, the chances are very high that you weren’t finished with what you were working on. You don’t need to make useless commits though. Instead, you can use the stash command. This command allows you to temporarily set aside all of your changes so that you can come back to them later. In this sense, stash is like setting your book down on the side table (or pushing the cat off your lap) so you can go investigate the noise on the roof. You aren’t putting your book away though, you’re just putting it down for a moment so you can come back and find it exactly the way it was when you put it down. Let’s say you’ve been working in the branch waiting-for-st-nicholas, and now you need to temporarily set aside your changes to see what the noise was on the roof: $ git stash After running this command, all uncommitted work will be temporarily removed from your working directory, and you will be returned to whatever state you were in the last time you committed your work. With the book safely on the side table, and the cat safely off your lap, you are now free to investigate the noise on the roof. It turns out it’s not reindeer after all, but just your boss who thought they’d help out by writing some code on the project you’ve been working on. Bless. Rolling your eyes, you agree to take a look and see what kind of mischief your boss has gotten themselves into this time. You fetch an updated list of branches from the remote repository, locate the branch your boss had been working on, and checkout a local copy: $ git fetch $ git branch -r $ git checkout -b helpful-boss-branch origin/helpful-boss-branch You are now in a local copy of the branch where you are free to look around, and figure out exactly what’s going on. You sigh audibly and say, ‘Okay. Tell me what was happening when you first realised you’d gotten into a mess’ as you look through the log messages for the branch. $ git log --oneline $ git log By using the log command you will be able to review the history of the branch and find out the moment right before your boss ended up stuck on your roof. You may also want to compare the work your boss has done to the main branch for your project. For this article, we’ll assume the main branch is named master. $ git diff master Looking through the commits, you may be able to see that things started out okay but then took a turn for the worse. Checking out a single commit Using commands you’re already familiar with, you can rewind through history and take a look at the state of the code at any moment in time by checking out a single commit, just like you would a branch. Using the log command, locate the unique identifier (commit hash) of the commit you want to investigate. For example, let’s say the unique identifier you want to checkout is 25f6d7f. $ git checkout 25f6d7f Note: checking out '25f6d7f'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using @-b@ with the checkout command again. Example: $ git checkout -b new_branch_name HEAD is now at 25f6d7f... Removed first paragraph. This is usually where people start to panic. Your boss screwed something up, and now your HEAD is detached. Under normal circumstances, these words would be a very good reason to panic. Take a deep breath. Nothing bad is going to happen. Being in a detached HEAD state just means you’ve temporarily disconnected from a known chain of events. In other words, you’re currently looking at the middle of a story (or branch) about what happened – and you’re not at the endpoint for this particular story. Git allows you to view the history of your repository as a timeline (technically it’s a directed acyclic graph). When you make commits which are not associated with a branch, they are essentially inaccessible once you return to a known branch. If you make commits while you’re in a detached HEAD state, and then try to return to a known branch, Git will give you a warning and tell you how to save your work. $ git checkout master Warning: you are leaving 1 commit behind, not connected to any of your branches: 7a85788 Your witty holiday commit message. If you want to keep them by creating a new branch, this may be a good time to do so with: $ git branch new_branch_name 7a85788 Switched to branch 'master' Your branch is up-to-date with 'origin/master'. So, if you want to save the commits you’ve made while in a detached HEAD state, you simply need to put them on a new branch. $ git branch saved-headless-commits 7a85788 With this trick under your belt, you can jingle around in history as much as you’d like. It’s not like sliding around on a timeline though. When you checkout a specific commit, you will only have access to the history from that point backwards in time. If you want to move forward in history, you’ll need to move back to the branch tip by checking out the branch again. $ git checkout helpful-boss-branch You’re now back to the present. Your HEAD is now pointing to the endpoint of a known branch, and so it is no longer detached. Any changes you made while on your adventure are safely stored in a new branch, assuming you’ve followed the instructions Git gave you. That wasn’t so scary after all, now, was it? Back to our reindeer problem. If your boss is anything like the bosses I’ve worked with, chances are very good that at least some of their work is worth salvaging. Depending on how your repository is structured, you’ll want to capture the good work using one of several different methods. Back in the living room, we’ll use our bowl of nuts to illustrate how you can rescue a tiny bit of work. Saving just one commit About that bowl of nuts. If you’re like me, you probably had some favourite kinds of nuts from an assorted collection. Walnuts were generally the most satisfying to crack open. So, instead of taking the entire bowl of nuts and dumping it into a stocking (merging the stocking and the bowl of nuts), we’re just going to pick out one nut from the bowl. In Git terms, we’re going to cherry-pick a commit and save it to another branch. First, checkout the main branch for your development work. From this branch, create a new branch where you can copy the changes into. $ git checkout master $ git checkout -b rescue-the-boss From your boss’s branch, helpful-boss-branch locate the commit you want to keep. $ git log --oneline helpful-boss-branch Let’s say the commit ID you want to keep is e08740b. From your rescue branch, use the command cherry-pick to copy the changes into your current branch. $ git cherry-pick e08740b If you review the history of your current branch again, you will see you now also have the changes made in the commit in your boss’s branch. At this point you might need to make a few additional fixes to help your boss out. (You’re angling for a bonus out of all this. Go the extra mile.) Once you’ve made your additional changes, you’ll need to add that work to the branch as well. $ git add [filename(s)] $ git commit -m ""Building on boss's work to improve feature X."" Go ahead and test everything, and make sure it’s perfect. You don’t want to introduce your own mistakes during the rescue mission! Uploading the fixed branch The next step is to upload the new branch to the remote repository so that your boss can download it and give you a huge bonus for helping you fix their branch. $ git push -u origin rescue-the-boss Cleaning up and getting back to work With your boss rescued, and your bonus secured, you can now delete the local temporary branches. $ git branch --delete rescue-the-boss $ git branch --delete helpful-boss-branch And settle back into your chair to wait for Saint Nicholas with your book, your branch, and possibly your cat. $ git checkout waiting-for-st-nicholas $ git stash pop Your working directory has been returned to exactly the same state you were in at the beginning of the article. Having fun with analogies I’ve had a bit of fun with analogies in this article. But sometimes those little twists on ideas can really help someone pick up a new idea (git stash: it’s like when Christmas comes around and everyone throws their fashion sense out the window and puts on a reindeer sweater for the holiday party; or git bisect: it’s like trying to find that one broken light on the string of Christmas lights). It doesn’t matter if the analogy isn’t perfect. It’s just a way to give someone a temporary hook into a concept in a way that makes the concept accessible while the learner becomes comfortable with it. As the learner’s comfort increases, the analogies can drop away, making room for the technically correct definition of how something works. Or, if you’re like me, you can choose to never grow old and just keep mucking about in the analogies. I’d argue it’s a lot more fun to play with a string of Christmas lights and some holiday cheer than a directed acyclic graph anyway.",2014,Emma Jane Westby,emmajanewestby,2014-12-02T00:00:00+00:00,https://24ways.org/2014/dealing-with-emergencies-in-git/,code 52,Git Rebasing: An Elfin Workshop Workflow,"This year Santa’s helpers have been tasked with making a garland. It’s a pretty simple task: string beads onto yarn in a specific order. When the garland reaches a specific length, add it to the main workshop garland. Each elf has a specific sequence they’re supposed to chain, which is given to them via a work order. (This is starting to sound like one of those horrible calculus problems. I promise it isn’t. It’s worse; it’s about Git.) For the most part, the system works really well. The elves are able to quickly build up a shared chain because each elf specialises on their own bit of garland, and then links the garland together. Because of this they’re able to work independently, but towards the common goal of making a beautiful garland. At first the elves are really careful with each bead they put onto the garland. They check with one another before merging their work, and review each new link carefully. As time crunches on, the elves pour a little more cheer into the eggnog cooler, and the quality of work starts to degrade. Tensions rise as mistakes are made and unkind words are said. The elves quickly realise they’re going to need a system to change the beads out when mistakes are made in the chain. The first common mistake is not looking to see what the latest chain is that’s been added to the main garland. The garland is huge, and it sits on a roll in one of the corners of the workshop. It’s a big workshop, so it is incredibly impractical to walk all the way to the roll to check what the last link is on the chain. The elves, being magical, have set up a monitoring system that allows them to keep a local copy of the main garland at their workstation. It’s an imperfect system though, so the elves have to request a manual refresh to see the latest copy. They can request a new copy by running the command git pull --rebase=preserve (They found that if they ran git pull on its own, they ended up with weird loops of extra beads off the main garland, so they’ve opted to use this method.) This keeps the shared garland up to date, which makes things a lot easier. A visualisation of the rebase process is available. The next thing the elves noticed is that if they worked on the main workshop garland, they were always running into problems when they tried to share their work back with the rest of the workshop. It was fine if they were working late at night by themselves, but in the middle of the day, it was horrible. (I’ve been asked not to talk about that time the fight broke out.) Instead of trying to share everything on their local copy of the main garland, the elves have realised it’s a lot easier to work on a new string and then knot this onto the main garland when their pattern repeat is finished. They generate a new string by issuing the following commands: git checkout master git checkout -b 1234_pattern-name 1234 represents the work order number and pattern-name describes the pattern they’re adding. Each bead is then added to the new link (git add bead.txt) and locked into place (git commit). Each elf repeats this process until the sequence of beads described in the work order has been added to their mini garland. To combine their work with the main garland, the elves need to make a few decisions. If they’re making a single strand, they issue the following commands: git checkout master git merge --ff-only 1234_pattern-name To share their work they publish the new version of the main garland to the workshop spool with the command git push origin master. Sometimes this fails. Sharing work fails because the workshop spool has gotten new links added since the elf last updated their copy of the main workshop spool. This makes the elves both happy and sad. It makes them happy because it means the other elves have been working too, but it makes them sad because they now need to do a bit of extra work to close their work order. To update the local copy of the workshop spool, the elf first unlinks the chain they just linked by running the command: git reset --merge ORIG_HEAD This works because the garland magic notices when the elves are doing a particularly dangerous thing and places a temporary, invisible bookmark to the last safe bead in the chain before the dangerous thing happened. The garland no longer has the elf’s work, and can be updated safely. The elf runs the command git pull --rebase=preserve and the changes all the other elves have made are applied locally. With these new beads in place, the elf now has to restring their own chain so that it starts at the right place. To do this, the elf turns back to their own chain (git checkout 1234_pattern-name) and runs the command git rebase master. Assuming their bead pattern is completely unique, the process will run and the elf’s beads will be restrung on the tip of the main workshop garland. Sometimes the magic fails and the elf has to deal with merge conflicts. These are kind of annoying, so the elf uses a special inspector tool to figure things out. The elf opens the inspector by running the command git mergetool to work through places where their beads have been added at the same points as another elf’s beads. Once all the conflicts are resolved, the elf saves their work, and quits the inspector. They might need to do this a few times if there are a lot of new beads, so the elf has learned to follow this update process regularly instead of just waiting until they’re ready to close out their work order. Once their link is up to date, the elf can now reapply their chain as before, publish their work to the main workshop garland, and close their work order: git checkout master git merge --ff-only 1234_pattern-name git push origin master Generally this process works well for the elves. Sometimes, though, when they’re tired or bored or a little drunk on festive cheer, they realise there’s a mistake in their chain of beads. Fortunately they can fix the beads without anyone else knowing. These tools can be applied to the whole workshop chain as well, but it causes problems because the magic assumes that elves are only ever adding to the main chain, not removing or reordering beads on the fly. Depending on where the mistake is, the elf has a few different options. Let’s pretend the elf has a sequence of five beads she’s been working on. The work order says the pattern should be red-blue-red-blue-red. If the sequence of beads is wrong (for example, blue-blue-red-red-red), the elf can remove the beads from the chain, but keep the beads in her workstation using the command git reset --soft HEAD~5. If she’s been using the wrong colours and the wrong pattern (for example, green-green-yellow-yellow-green), she can remove the beads from her chain and discard them from her workstation using the command git reset --hard HEAD~5. If one of the beads is missing (for example, red-blue-blue-red), she can restring the beads using the first method, or she can use a bit of magic to add the missing bead into the sequence. Using a tool that’s a bit like orthoscopic surgery, she first selects a sequence of beads which contains the problem. A visualisation of this process is available. Start the garland surgery process with the command: git rebase --interactive HEAD~4 A new screen comes up with the following information (the oldest bead is on top): pick c2e4877 Red bead pick 9b5555e Blue bead pick 7afd66b Blue bead pick e1f2537 Red bead The elf adjusts the list, changing “pick” to “edit” next to the first blue bead: pick c2e4877 Red bead edit 9b5555e Blue bead pick 7afd66b Blue bead pick e1f2537 Red bead She then saves her work and quits the editor. The garland magic has placed her back in time at the moment just after she added the first blue bead. She needs to manually fix up her garland to add the new red bead. If the beads were files, she might run commands like vim beads.txt and edit the file to make the necessary changes. Once she’s finished her changes, she needs to add her new bead to the garland (git add --all) and lock it into place (git commit). This time she assigns the commit message “Red bead – added” so she can easily find it. The garland magic has replaced the bead, but she still needs to verify the remaining beads on the garland. This is a mostly automatic process which is started by running the command git rebase --continue. The new red bead has been assigned a position formerly held by the blue bead, and so the elf must deal with a merge conflict. She opens up a new program to help resolve the conflict by running git mergetool. She knows she wants both of these beads in place, so the elf edits the file to include both the red and blue beads. With the conflict resolved, the elf saves her changes and quits the mergetool. Back at the command line, the elf checks the status of her work using the command git status. rebase in progress; onto 4a9cb9d You are currently rebasing branch '2_RBRBR' on '4a9cb9d'. (all conflicts fixed: run ""git rebase --continue"") Changes to be committed: (use ""git reset HEAD ..."" to unstage) modified: beads.txt Untracked files: (use ""git add ..."" to include in what will be committed) beads.txt.orig She removes the file added by the mergetool with the command rm beads.txt.orig and commits the edits she just made to the bead file using the commands: git add beads.txt git commit --message ""Blue bead -- resolved conflict"" With the conflict resolved, the elf is able to continue with the rebasing process using the command git rebase --continue. There is one final conflict the elf needs to resolve. Once again, she opens up the visualisation tool and takes a look at the two conflicting files. She incorporates the changes from the left and right column to ensure her bead sequence is correct. Once the merge conflict is resolved, the elf saves the file and quits the mergetool. Once again, she cleans out the backup file added by the mergetool (rm beads.txt.orig) and commits her changes to the garland: git add beads.txt git commit --message ""Red bead -- resolved conflict"" and then runs the final verification steps in the rebase process (git rebase --continue). The verification process runs through to the end, and the elf checks her work using the command git log --oneline. 9269914 Red bead -- resolved conflict 4916353 Blue bead -- resolved conflict aef0d5c Red bead -- added 9b5555e Blue bead c2e4877 Red bead She knows she needs to read the sequence from bottom to top (the oldest bead is on the bottom). Reviewing the list she sees that the sequence is now correct. Sometimes, late at night, the elf makes new copies of the workshop garland so she can play around with the bead sequencer just to see what happens. It’s made her more confident at restringing beads when she’s found real mistakes. And she doesn’t mind helping her fellow elves when they run into trouble with their beads. The sugar cookies they leave her as thanks don’t hurt either. If you would also like to play with the bead sequencer, you can get a copy of the branches the elf worked. Our lessons from the workshop: By using rebase to update your branches, you avoid merge commits and keep a clean commit history. If you make a mistake on one of your local branches, you can use reset to take commits off your branch. If you want to save the work, but uncommit it, add the parameter --soft. If you want to completely discard the work, use the parameter, --hard. If you have merged working branch changes to the local copy of your master branch and it is preventing you from pushing your work to a remote repository, remove these changes using the command reset with the parameter --merge ORIG_HEAD before updating your local copy of the remote master branch. If you want to make a change to work that was committed a little while ago, you can use the command rebase with the parameter --interactive. You will need to include how many commits back in time you want to review.",2015,Emma Jane Westby,emmajanewestby,2015-12-07T00:00:00+00:00,https://24ways.org/2015/git-rebasing/,code 262,Be the Villain,"Inclusive Design is the practice of making products and services accessible to, and usable by as many people as reasonably possible without the need for specialized accommodations. The practice was popularized by author and User Experience Design Director Kat Holmes. If getting you to discover her work is the only thing this article succeeds in doing then I’ll consider it a success. As a framework for creating resilient solutions to problems, Inclusive Design is incredible. However, the aimless idealistic aspirations many of its newer practitioners default to can oftentimes run into trouble. Without outlining concrete, actionable outcomes that are then vetted by the people you intend to serve, there is the potential to do more harm than good. When designing, you take a user flow and make sure it can’t be broken. Ensuring that if something is removed, it can be restored. Or that something editable can also be updated at a later date—you know, that kind of thing. What we want to do is avoid surprises. Much like a water slide with a section of pipe missing, a broken flow forcibly ejects a user, to great surprise and frustration. Interactions within a user flow also have to be small enough to be self-contained, so as to avoid creating a none pizza with left beef scenario. Lately, I’ve been thinking about how to expand on this practice. Watertight user flows make for a great immediate experience, but it’s all too easy to miss the forest for the trees when you’re a product designer focused on cranking out features. What I’m concerned about is while to trying to envision how a user flow could be broken, you also think about how it could be subverted. In addition to preventing the removal of a section of water slide, you also keep someone from mugging the user when they shoot out the end. If you pay attention, you’ll start to notice this subversion with increasing frequency: Domestic abusers using internet-controlled devices to spy on and control their partner. Zealots tanking a business’ rating on Google because its owners spoke out against unchecked gun violence. Forcing people to choose between TV or stalking because the messaging center portion of a cable provider’s entertainment package lacks muting or blocking features. White supremacists tricking celebrities into endorsing anti-Semitic conspiracy theories. Facebook repeatedly allowing housing, credit, and employment advertisers to discriminate against users by their race, ability, and religion. White supremacists also using a video game chat service as a recruiting tool. The unchecked harassment of minors on Instagram. Swatting. If I were to guess why we haven’t heard more about this problem, I’d say that optimistically, people have settled out of court. Pessimistically, it’s most likely because we ignore, dismiss, downplay, and suppress those who try to bring it to our attention. Subverted design isn’t the practice of employing Dark Patterns to achieve your business goals. If you are not familiar with the term, Dark Patterns are the use of cheap user interface tricks and psychological manipulation to get users to act against their own best interests. User Experience consultant Chris Nodder wrote Evil By Design, a fantastic book that unpacks how to detect and think about them, if you’re interested in this kind of thing Subverted design also isn’t beholden design, or simple lack of attention. This phenomenon isn’t even necessarily premeditated. I think it arises from naïve (or willfully ignorant) design decisions being executed at a historically unprecedented pace and scale. These decisions are then preyed on by the shrewd and opportunistic, used to control and inflict harm on the undeserving. Have system, will game. This is worth discussing. As the field of design continues to industrialize empathy, it also continues to ignore the very established practice of threat modeling. Most times, framing user experience in terms of how to best funnel people into a service comes with an implicit agreement that the larger system that necessitates the service is worth supporting. To achieve success in the eyes of their superiors, designers may turn to emotional empathy exercises. By projecting themselves into the perceived surface-level experiences of others, they play-act at understanding how to nudge their targeted demographics into a conversion funnel. This roleplaying exercise has the effect of scoping concerns to the immediate, while simultaneously reinforcing the idea of engagement at all cost within the identified demographic. The thing is, pure engagement leaves the door wide open for bad actors. Even within the scope of a limited population, the assumption that everyone entering into the funnel is acting with good intentions is a poor one. Security researchers, network administrators, and other professionals who practice threat modeling understand that the opposite is true. By preventing everyone save for well-intentioned users from operating a system within the parameters you set for them, you intentionally limit the scope of abuse that can be enacted. Don’t get me wrong: being able to escort as many users as you can to the happy path is a foundational skill. But we should also be having uncomfortable conversations about why something unthinkable may in fact not be. They’re not going to be fun conversations. It’s not going to be easy convincing others that these aren’t paranoid delusions best tucked out of sight in the darkest, dustiest corner of the backlog. Realistically, talking about it may even harm your career. But consider the alternative. The controlled environment of the hypothetical allows us to explore these issues without propagating harm. Better to be viewed as the office’s resident villain than to have to live with something like this: If the past few years have taught us anything, it’s that the choices we make—or avoid making—have consequences. Design has been doing a lot of growing up as of late, including waking up to the idea that technology isn’t neutral. You’re going to have to start thinking the way a monster does—if you can imagine it, chances are someone else can as well. To get into this kind of mindset, inverting the Inclusive Design Principles is a good place to start: Providing a comparable experience becomes forcing a single path. Considering situation becomes ignoring circumstance. Being consistent becomes acting capriciously. Giving control becomes removing autonomy. Offering choice becomes limiting options. Prioritizing content becomes obfuscating purpose. Adding value becomes filling with gibberish. Combined, these inverted principles start to paint a picture of something we’re all familiar with: a half-baked, unscrupulous service that will jump at the chance to take advantage of you. This environment is also a perfect breeding ground for spawning bad actors. These kinds of services limit you in the ways you can interact with them. They kick you out or lock you in if you don’t meet their unnamed criteria. They force you to parse layout, prices, and policies that change without notification or justification. Their controls operate in ways that are unexpected and may shift throughout the experience. Their terms are dictated to you, gaslighting you to extract profit. Heaps of jargon and flashy, unnecessary features are showered on you to distract from larger structural and conceptual flaws. So, how else can we go about preventing subverted design? Marli Mesibov, Content Strategist and Managing Editor of UX Booth, wrote a brilliant article about how to use Dark Patterns for good—perhaps the most important takeaway being admitting you have a problem in the first place. Another exercise is asking the question, “What is the evil version of this feature?” Ask it during the ideation phase. Ask it as part of acceptance criteria. Heck, ask it over lunch. I honestly don’t care when, so long as the question is actually raised. In keeping with the spirit of this article, we can also expand on this line of thinking. Author, scientist, feminist, and pacifist Ursula Franklin urges us to ask, “Whose benefits? Whose risks?” instead of “What benefits? What risks?” in her talk, When the Seven Deadly Sins Became the Seven Cardinal Virtues. Inspired by the talk, Ethan Marcotte discusses how this relates to the web platform in his powerful post, Seven into seven. Few things in this world are intrinsically altruistic or good—it’s just the nature of the beast. However, that doesn’t mean we have to stand idly by when harm is created. If we can add terms like “anti-pattern” to our professional vocabulary, we can certainly also incorporate phrases like “abuser flow.” Design finally got a seat at the table. We should use this newfound privilege wisely. Listen to women. Listen to minorities, listen to immigrants, the unhoused, the less economically advantaged, and the less technologically-literate. Listen to the underrepresented and the underprivileged. Subverted design is a huge problem, likely one that will never completely go away. However, the more of us who put the hard work into being the villain, the more we can lessen the scope of its impact.",2018,Eric Bailey,ericbailey,2018-12-06T00:00:00+00:00,https://24ways.org/2018/be-the-villain/,ux 65,The Accessibility Mindset,"Accessibility is often characterized as additional work, hard to learn and only affecting a small number of people. Those myths have no logical foundation and often stem from outdated information or misconceptions. Indeed, it is an additional skill set to acquire, quite like learning new JavaScript frameworks, CSS layout techniques or new HTML elements. But it isn’t particularly harder to learn than those other skills. A World Health Organization (WHO) report on disabilities states that, [i]ncluding children, over a billion people (or about 15% of the world’s population) were estimated to be living with disability. Being disabled is not as unusual as one might think. Due to chronic health conditions and older people having a higher risk of disability, we are also currently paving the cowpath to an internet that we can still use in the future. Accessibility has a very close relationship with usability, and advancements in accessibility often yield improvements in the usability of a website. Websites are also more adaptable to users’ needs when they are built in an accessible fashion. Beyond the bare minimum In the time of table layouts, web developers could create code that passed validation rules but didn’t adhere to the underlying semantic HTML model. We later developed best practices, like using lists for navigation, and with HTML5 we started to wrap those lists in nav elements. Working with accessibility standards is similar. The Web Content Accessibility Guidelines (WCAG) 2.0 can inform your decision to make websites accessible and can be used to test that you met the success criteria. What it can’t do is measure how well you met them. W3C developed a long list of techniques that can be used to make your website accessible, but you might find yourself in a situation where you need to adapt those techniques to be the most usable solution for your particular problem. The checkbox below is implemented in an accessible way: The input element has an id and the label associated with the checkbox refers to the input using the for attribute. The hover area is shown with a yellow background and a black dotted border: Open video The label is clickable and the checkbox has an accessible description. Job done, right? Not really. Take a look at the space between the label and the checkbox: Open video The gutter is created using a right margin which pushes the label to the right. Users would certainly expect this space to be clickable as well. The simple solution is to wrap the label around the checkbox and the text: Open video You can also set the label to display:block; to further increase the clickable area: Open video And while we’re at it, users might expect the whole box to be clickable anyway. Let’s apply the CSS that was on a wrapping div element to the label directly: Open video The result enhances the usability of your form element tremendously for people with lower dexterity, using a voice mouse, or using touch interfaces. And we only used basic HTML and CSS techniques; no JavaScript was added and not one extra line of CSS.
    Button Example The button below looks like a typical edit button: a pencil icon on a real button element. But if you are using a screen reader or a braille keyboard, the button is just read as “button” without any indication of what this button is for. Open video A screen reader announcing a button. Contains audio. The code snippet shows why the button is not properly announced: An icon font is used to display the icon and no text alternative is given. A possible solution to this problem is to use the title or aria-label attributes, which solves the alternative text use case for screen reader users: Open video A screen reader announcing a button with a title. However, screen readers are not the only way people with and without disabilities interact with websites. For example, users can reset or change font families and sizes at will. This helps many users make websites easier to read, including people with dyslexia. Your icon font might be replaced by a font that doesn’t include the glyphs that are icons. Additionally, the icon font may not load for users on slow connections, like on mobile phones inside trains, or because users decided to block external fonts altogether. The following screenshots show the mobile GitHub view with and without external fonts: The mobile GitHub view with and without external fonts. Even if the title/aria-label approach was used, the lack of visual labels is a barrier for most people under those circumstances. One way to tackle this is using the old-fashioned img element with an appropriate alt attribute, but surprisingly not every browser displays the alternative text visually when the image doesn’t load. Providing always visible text is an alternative that can work well if you have the space. It also helps users understand the meaning of the icons. This also reads just fine in screen readers: Open video A screen reader announcing the revised button. Clever usability enhancements don’t stop at a technical implementation level. Take the BBC iPlayer pages as an example: when a user navigates the “captioned videos” or “audio description” categories and clicks on one of the videos, captions or audio descriptions are automatically switched on. Small things like this enhance the usability and don’t need a lot of engineering resources. It is more about connecting the usability dots for people with disabilities. Read more about the BBC iPlayer accessibility case study. More information W3C has created several documents that make it easier to get the gist of what web accessibility is and how it can benefit everyone. You can find out “How People with Disabilities Use the Web”, there are “Tips for Getting Started” for developers, designers and content writers. And for the more seasoned developer there is a set of tutorials on web accessibility, including information on crafting accessible forms and how to use images in an accessible way. Conclusion You can only produce a web project with long-lasting accessibility if accessibility is not an afterthought. Your organization, your division, your team need to think about accessibility as something that is the foundation of your website or project. It needs to be at the same level as performance, code quality and design, and it needs the same attention. Users often don’t notice when those fundamental aspects of good website design and development are done right. But they’ll always know when they are implemented poorly. If you take all this into consideration, you can create accessibility solutions based on the available data and bring accessibility to people who didn’t know they’d need it: Open video In this video from the latest Apple keynote, the Apple TV is operated by voice input through a remote. When the user asks “What did she say?” the video jumps back fifteen seconds and captions are switched on for a brief time. All three, the remote, voice input and captions have their roots in assisting people with disabilities. Now they benefit everyone.",2015,Eric Eggert,ericeggert,2015-12-17T00:00:00+00:00,https://24ways.org/2015/the-accessibility-mindset/,code 154,Diagnostic Styling,"We’re all used to using CSS to make our designs live and breathe, but there’s another way to use CSS: to find out where our markup might be choking on missing accessibility features, targetless links, and just plain missing content. Note: the techniques discussed here mostly work in Firefox, Safari, and Opera, but not Internet Explorer. I’ll explain why that’s not really a problem near the end of the article — and no, the reason is not “everyone should just ignore IE anyway”. Basic Diagnostics To pick a simple example, suppose you want to call out all holdover font and center elements in a site. Simple: you just add the following to your styles. font, center {outline: 5px solid red;} You could take it further and add in a nice lime background or some such, but big thick red outlines should suffice. Now you’ll be able to see the offenders wherever as you move through the site. (Of course, if you do this on your public server, everyone else will see the outlines too. So this is probably best done on a development server or local copy of the site.) Not everyone may be familiar with outlines, which were introduced in CSS2, so a word on those before we move on. Outlines are much like borders, except outlines don’t affect layout. Eh? Here’s a comparison. On the left, you have a border. On the right, an outline. The border takes up layout space, pushing other content around and generally being a nuisance. The outline, on the other hand, just draws into quietly into place. In most current browsers, it will overdraw any content already onscreen, and will be overdrawn by any content placed later — which is why it overlaps the images above it, and is overlapped by those below it. Okay, so we can outline deprecated elements like font and center. Is that all? Oh no. Attribution Let’s suppose you also want to find any instances of inline style — that is, use of the style attribute on elements in the markup. This is generally discouraged (outside of HTML e-mails, which I’m not going to get anywhere near), as it’s just another side of the same coin of using font: baking the presentation into the document structure instead of putting it somewhere more manageable. So: *[style], font, center {outline: 5px solid red;} Adding that attribute selector to the rule’s grouped selector means that we’ll now be outlining any element with a style attribute. There’s a lot more that attribute selectors will let use diagnose. For example, we can highlight any images that have empty alt or title text. img[alt=""""] {border: 3px dotted red;} img[title=""""] {outline: 3px dotted fuchsia;} Now, you may wonder why one of these rules calls for a border, and the other for an outline. That’s because I want them to “add together” — that is, if I have an image which possesses both alt and title, and the values of both are empty, then I want it to be doubly marked. See how the middle image there has both red and fuchsia dots running around it? (And am I the only one who sorely misses the actual circular dots drawn by IE5/Mac?) That’s due to its markup, which we can see here in a fragment showing the whole table row. empty title Right, that’s all well and good, but it misses a rather more serious situation: the selector img[alt=""""] won’t match an img element that doesn’t even have an alt attribute. How to tackle this problem? Not a Problem Well, if you want to select something based on a negative, you need a negative selector. img:not([alt]) {border: 5px solid red;} This is really quite a break from the rest of CSS selection, which is all positive: “select anything that has these characteristics”. With :not(), we have the ability to say (in supporting browsers) “select anything that hasn’t these characteristics”. In the above example, only img elements that do not have an alt attribute will be selected. So we expand our list of image-related rules to read: img[alt=""""] {border: 3px dotted red;} img[title=""""] {outline: 3px dotted fuchsia;} img:not([alt]) {border: 5px solid red;} img:not([title]) {outline: 5px solid fuchsia;} With the following results: We could expand this general idea to pick up tables who lack a summary, or have an empty summary attribute. table[summary=""""] {outline: 3px dotted red;} table:not([summary]) {outline: 5px solid red;} When it comes to selecting header cells that lack the proper scope, however, we have a trickier situation. Finding headers with no scope attribute is easy enough, but what about those that have a scope attribute with an incorrect value? In this case, we actually need to pull an on-off maneuver. This has us setting all th elements to have a highlight style, and then turn it off for the elements that meet our criteria. th {border: 2px solid red;} th[scope=""col""], th[scope=""row""] {border: none;} This was necessary because of the way CSS selectors work. For example, consider this: th:not([scope=""col""]), th:not([scope=""row""]) {border: 2px solid red;} That would select…all th elements, regardless of their attrributes. That’s because every th element doesn’t have a scope of col, doesn’t have a scope of row, or doesn’t have either. There’s no escaping this selector o’ doom! This limitation arises because :not() is limited to containing a single “thing” within its parentheses. You can’t, for example, say “select all elements except those that are images which descend from list items”. Reportedly, this limitation was imposed to make browser implementation of :not() easier. Still, we can make good use of :not() in the service of further diagnosing. Calling out links in trouble is a breeze: a[href]:not([title]) {border: 5px solid red;} a[title=""""] {outline: 3px dotted red;} a[href=""#""] {background: lime;} a[href=""""] {background: fuchsia;} Here we have a set that will call our attention to links missing title information, as well as links that have no valid target, whether through a missing URL or a JavaScript-driven page where there are no link fallbacks in the case of missing or disabled JavaScript (href=""#""). And What About IE? As I said at the beginning, much of what I covered here doesn’t work in Internet Explorer, most particularly :not() and outline. (Oh, so basically everything? -Ed.) I can’t do much about the latter. For the former, however, it’s possible to hack your way around the problem by doing some layered on-off stuff. For example, for images, you replace the previously-shown rules with the following: img {border: 5px solid red;} img[alt][title] {border-width: 0;} img[alt] {border-color: fuchsia;} img[alt], img[title] {border-style: double;} img[alt=""""][title], img[alt][title=""""] {border-width: 3px;} img[alt=""""][title=""""] {border-style: dotted;} It won’t have exactly the same set of effects, given the inability to use both borders and outlines, but will still highlight troublesome images. It’s also the case that IE6 and earlier lack support for even attribute selectors, whereas IE7 added pretty much all the attribute selector types there are, so the previous code block won’t have any effect previous to IE7. In a broader sense, though, these kinds of styles probably aren’t going to be used in the wild, as it were. Diagnostic styles are something only you see as you work on a site, so you can make sure to use a browser that supports outlines and :not() when you’re diagnosing. The fact that IE users won’t see these styles is irrelevant since users of any browser probably won’t be seeing these styles. Personally, I always develop in Firefox anyway, thanks to its ability to become a full-featured IDE through the addition of extensions like Firebug and the Web Developer Toolbar. Yeah, About That… It’s true that much of what I describe in this article is available in the WDT. I feel there are two advantages to writing your own set of diagnostic styles. When you write your own styles, you can define exactly what the visual results will be, and how they will interact. The WDT doesn’t let you make its outlines thicker or change their colors. You can combine a bunch of diagnostics into a single set of rules and add it to your site’s style sheet during the diagnostic portion, thus ensuring they persist as you surf around. This can be done in the WDT, but it isn’t as easy (and, at least for me, not as reliable). It’s also true that a markup validator will catch many of the errors I mentioned, such as missing alt and summary attributes. For some, that’s sufficient. But it won’t catch everything diagnostic styles can, like empty alt values or untargeted links, which are perfectly valid, syntactically speaking. Diagnosis Complete? I hope this has been a fun look at the concept of diagnostic styling as well as a quick introduction into possibly new concepts like :not() and outlines. This isn’t all there is to say, of course: there is plenty more that could be added to a diagnostic style sheet. And everyone’s diagnostics will be different, tuned to meet each person’s unique situation. Mostly, though, I hope this small exploration triggers some creative thinking about the use of CSS to do more than just lay out pages and colorize text. Given the familiarity we acquire with CSS, it only makes sense to use it wherever it might be useful, and setting up visible diagnostic flags is just one more place for it to help us.",2007,Eric Meyer,ericmeyer,2007-12-20T00:00:00+00:00,https://24ways.org/2007/diagnostic-styling/,process 241,Jank-Free Image Loads,"There are a few fundamental problems with embedding images in pages of hypertext; perhaps chief among them is this: text is very light and loads rather fast; images are much heavier and arrive much later. Consequently, millions (billions?) of times a day, a hapless Web surfer will start reading some text on a page, and then — Your browser doesn’t support HTML5 video. Here is a link to the video instead. — oops! — an image pops in above it, pushing said text down the page, and our poor reader loses their place. By default, partially-loaded pages have the user experience of a slippery fish, or spilled jar of jumping beans. For the rest of this article, I shall call that jarring, no-good jumpiness by its name: jank. And I’ll chart a path into a jank-free future – one in which it’s easy and natural to author elements that load like this: Your browser doesn’t support HTML5 video. Here is a link to the video instead. Jank is a very old problem, and there is a very old solution to it: the width and height attributes on . The idea is: if we stick an image’s dimensions right into the HTML, browsers can know those dimensions before the image loads, and reserve some space on the layout for it so that nothing gets bumped down the page when the image finally arrives. width Specifies the intended width of the image in pixels. When given together with the height, this allows user agents to reserve screen space for the image before the image data has arrived over the network. —The HTML 3.2 Specification, published on January 14 1997 Unfortunately for us, when width and height were first spec’d and implemented, layouts were largely fixed and images were usually only intended to render at their fixed, actual dimensions. When image sizing gets fluid, width and height get weird: See the Pen fluid width + fixed height = distortion by Eric Portis (@eeeps) on CodePen. width and height are too rigid for the responsive world. What we need, and have needed for a very long time, is a way to specify fixed aspect ratios, to pair with our fluid widths. I have good news, bad news, and great news. The good news is, there are ways to do this, now, that work in every browser. Responsible sites, and responsible developers, go through the effort to do them. The bad news is that these techniques are all terrible, cumbersome hacks. They’re difficult to remember, difficult to understand, and they can interact with other pieces of CSS in unexpected ways. So, the great news: there are two on-the-horizon web platform features that are trying to make no-jank, fixed-aspect-ratio, fluid-width images a natural part of the web platform. aspect-ratio in CSS The first proposed feature? An aspect-ratio property in CSS! This would allow us to write CSS like this: img { width: 100%; } .thumb { aspect-ratio: 1/1; } .hero { aspect-ratio: 16/9; } This’ll work wonders when we need to set aspect ratios for whole classes of images, which are all sized to fit within pre-defined layout slots, like the .thumb and .hero images, above. Alas, the harder problem, in my experience, is not images with known-ahead-of-time aspect ratios. It’s images – possibly user generated images – that can have any aspect ratio. The really tricky problem is unknown-when-you’re-writing-your-CSS aspect ratios that can vary per-image. Using aspect-ratio to reserve space for images like this requires inline styles: And inline styles give me the heebie-jeebies! As a web developer of a certain age, I have a tiny man in a blue beanie permanently embedded deep within my hindbrain, who cries out in agony whenever I author a style="""" attribute. And you know what? The old man has a point! By sticking super-high-specificity inline styles in my content, I’m cutting off my, (or anyone else’s) ability to change those aspect ratios, for whatever reason, later. How might we specify aspect ratios at a lower level? How might we give browsers information about an image’s dimensions, without giving them explicit instructions about how to style it? I’ll tell you: we could give browsers the intrinsic aspect ratio of the image in our HTML, rather than specifying an extrinsic aspect ratio! A brief note on intrinsic and extrinsic sizing What do I mean by “intrinsic” and “extrinsic?” The intrinsic size of an image is, put simply, how big it’d be if you plopped it onto a page and applied no CSS to it whatsoever. An 800×600 image has an intrinsic width of 800px. The extrinsic size of an image, then, is how large it ends up after CSS has been applied. Stick a width: 300px rule on that same 800×600 image, and its intrinsic size (accessible via the Image.naturalWidth property, in JavaScript) doesn’t change: its intrinsic size is still 800px. But this image now has an extrinsic size (accessible via Image.clientWidth) of 300px. It surprised me to learn this year that height and width are interpreted as presentational hints and that they end up setting extrinsic dimensions (albeit ones that, unlike inline styles, have absolutely no specificity). CSS aspect-ratio lets us avoid setting extrinsic heights and widths – and instead lets us give images (or anything else) an extrinsic aspect ratio, so that as soon as we set one dimension (possibly to a fluid width, like 100%!), the other dimension is set automatically in relation to it. The last tool I’m going to talk about gets us out of the extrinsic sizing game all together — which, I think, is only appropriate for a feature that we’re going to be using in HTML. intrinsicsize in HTML The proposed intrinsicsize attribute will let you do this: That tells the browser, “hey, this image.jpg that I’m using here – I know you haven’t loaded it yet but I’m just going to let you know right away that it’s going to have an intrinsic size of 800×600.” This gives the browser enough information to reserve space on the layout for the image, and ensures that any and all extrinsic sizing instructions, specified in our CSS, will layer cleanly on top of this, the image’s intrinsic size. You may ask (I did!): wait, what if my references multiple resources, which all have different intrinsic sizes? Well, if you’re using srcset, intrinsicsize is a bit of a misnomer – what the attribute will do then, is specify an intrinsic aspect ratio: In the future (and behind the “Experimental Web Platform Features” flag right now, in Chrome 71+), asking this image for its .naturalWidth would not return 3 – it will return whatever 75vw is, given the current viewport width. And Image.naturalHeight will return that width, divided by the intrinsic aspect ratio: 3/2. Can’t wait I seem to have gotten myself into the weeds a bit. Sizing on the web is complicated! Don’t let all of these details bury the big takeaway here: sometime soon (🤞 2019‽ 🤞), we’ll be able to toss our terrible aspect-ratio hacks into the dustbin of history, get in the habit of setting aspect-ratios in CSS and/or intrinsicsizes in HTML, and surf a less-frustrating, more-performant, less-janky web. I can’t wait!",2018,Eric Portis,ericportis,2018-12-21T00:00:00+00:00,https://24ways.org/2018/jank-free-image-loads/,code 87,Content Planning Demystified,"The first thing you learn as a junior editor is that you can’t do everything yourself. You must rely on someone else to do at least part of what must be done: the long-range planning, the initial drafting or shooting or recording, the editing, the production, the final polish. All of those pieces of work that belong to someone else take quite a lot of time — days, weeks, sometimes months. If you’re the sort of person who wrote college term papers the night before they were due, this can come as a bit of a shock. To my twenty-two-year-old self, it certainly did. It turns out that the only real way to avoid a trainwreck with editorial work is to get ahead of the trouble, line everything up carefully, and leave oodles of room for all the pieces to connect on time. The same is true of content strategy, content planning, and just about everything to do with content on the web, except for the writing itself — and that, too, usually takes far longer than anyone expects. If you’re not a professional editor and you suddenly find yourself dealing with content creation, you’re almost certainly going to underestimate the time and effort involved, or to skip something important in the planning process that pops up to bite you later. Without good content, it doesn’t matter how well designed or coded your web project is, because it won’t be doing the thing it’s meant to do. And even if content is far from your specialty, you may well end up being the only one willing to coordinate it far enough in advance to avoid a chaotic ending. Whether you’re hiring writers and editors for a big project, working with a small client, or coaxing some editorial help out of a co-worker, getting the planning work done correctly — and ahead of time — will allow you to orchestrate a glorious ballet of togetherness, instead of feverishly scraping together something to put on your site when the deadline looms. So get out the graph paper and the pocket protector, because we’re going to go Full Nerd on this problem. Know your poison Anyone who’s seen a project delayed for six months by content trouble, or derailed by content that’s bland and unhelpful, knows this stuff can make you feel like a dead sock. To get ahead of the problem, you’re going to have to learn to spot common problems and plan your way around them. On web projects without a dedicated editorial lead, you’re likely to encounter content that is: Useless – Content that doesn’t serve your readers’ needs in some way is pointless. And because it takes up your time and crowds out genuinely helpful things, it’s actually damaging. The logic is simple: you can make content that’s all about you, and that serves your stated messaging goals, but if no one is motivated to read it, it’s a waste of everyone’s time. Badly written – When you publish articles or instructions or other content that is too stiffly formal, overly wordy, hard to understand, offensive, unintentionally cheesy, or otherwise off in tone or style, you’re doing two things. First, you’re weakening the information you’re trying to convey by making it obscure or annoying. Second — and this one is even more damaging — you’re demonstrating bad taste. When you get the cultural elements of publishing wrong, you encourage your readers to believe that you either don’t understand them or don’t care about getting it wrong. Gooey – Content strategists have been talking about structured content (that’s chunks versus blobs) for years. If you’re publishing more than a few dozen pages without thinking through the structure of your content, you’re probably missing a chance to improve your long-term efficiency. If you’re publishing more than a couple of thousand pages without taking care of your content structure, you’re probably doing a lot more manual wrangling (or cumbersome CMS work) than you need to be, especially when it comes to cross-platform publishing. Unregulated – If you’re not tracking what works and what doesn’t — and especially if you don’t know what “works” means for your project or organization — you’re almost certainly getting worse results than you should be, for more work. Overabundant – As demonstrated by the cinnamon challenge, too much of a delicious thing can be a giant and publicly embarrassing disaster. For most projects and organizations, if you’re making more stuff than your readers can handle, or if you’re spreading your creative and editorial resources too thinly, that’s bad. Spammers, content farms, and barrel-bottom tabloids have their own special math, the side effects of which include insomnia, irritability, and crying in traffic while silently mouthing Wilson Phillips lyrics. Prevent all preventable damage Once you know what kind of trouble to look for, you can prevent a lot of it by doing some smart planning well before someone starts writing (or recording or shooting video). To prevent uselessness: Know your readers and decide what you’re trying to accomplish — with your website as a whole, and with each piece of content, always. Once you know what you’re trying to achieve, you can evaluate your work as you go to make sure that it’s actually doing the right thing. (I’ve written a lot more about this for A List Apart and in The Elements of Content Strategy.) To prevent bad writing: Establish a consistent and appropriate style using examples (and a style guide if you need one), designate an editor, hire good writers, and make time for quality control. Kate Kiefer’s style guide for MailChimp is a superb example of style-wrangling that everyone can use. To prevent repulsive goo: Give your content as much structure as possible, and know how structure relates to your entire publishing ecosystem, including all those mobile devices. Sara Wachter-Boettcher’s Content Everywhere and Karen McGrane’s Content Strategy for Mobile offer brilliant yet friendly introductions to the wide world of structured content. To prevent unregulated chaos: Measure everything that matters to your project, your client, your organization, and especially your readers — not generic measures of someone else’s success. Measure it all regularly. Be disciplined. Adjust at regular intervals. Rick Allen’s series on content strategy analytics is an excellent place to begin (part one; part two). To prevent overabundance: Stop trying to do everything and focus on giving your readers just a few things they want and genuinely need. Don’t establish a schedule your writers might not be able to keep, and focus on differentiating yourself with quality, not quantity. (And while you’re at it, scratch the auto-posting to social networks and the cross-posting between them. It’s about as engaging as an automated phone system.) At a slightly higher level, pick the right content person (or team) for the work. If you really only need a few pages of copy, find a smart writer who does good work for multi-platform readers. If you’re slinging tens of thousands of pages of content, get someone with field experience in high-level editorial planning and the ability to turn blobs into chunks and melted goo into Legos. If you’re starting a project that involves making a lot of content over time, bring in someone with journalism experience (or get your client to do so). “But wait!” you may say. “I’m not hiring anyone. I have to do this all myself.” That’s not uncommon at all. The bad news is, you have to learn a bunch of stuff. The good news is, you get to learn a bunch of awesome stuff. Figure out what the project needs, just as though you were going to hire someone, and then give yourself time to get up to speed. If it’s a really complicated project, you’re probably going to have trouble unless you eventually get professional help. But if it’s small and you can do it in steps, you can certainly do much better by giving yourself a plan and working on the things that matter most. Plan for the marathon, not the sprint Launching with awesome content is a tiny fraction of a victory, which is why it’s so important that your content not be gooey or unregulated. It also means that if you don’t plan for a realistic publication schedule, you are going to slam into reality in a really unpleasant way not too long after you’ve begun. If you’re asking people to make words (or videos or whatever) for you, they’re going to have to do less of something else, so plan for that beforehand. And while you’re at it, unless publishing is your core business, ditch the feed-the-beast plan that leads to fluffy blog posts and spiritless, unhelpful social media content. It’s antisocial for your reading community, offers short-term gains at best, and will burn you out or lower your standards until you don’t even know you’re doing lousy work. Good content is expensive, no matter how you do it, but spreading yourself too thin is a much worse investment than doing a smaller thing well and gradually building up a body of superb content that people want to share and keep and return to.",2012,Erin Kissane,erinkissane,2012-12-20T00:00:00+00:00,https://24ways.org/2012/content-planning-demystified/,content 54,Putting My Patterns through Their Paces,"Over the last few years, the conversation around responsive design has shifted subtly, focusing not on designing pages, but on patterns: understanding the small, reusable elements that comprise a larger design system. And given that many of those patterns are themselves responsive, learning to manage these small layout systems has become a big part of my work. The thing is, the more pattern-driven work I do, the more I realize my design process has changed in a number of subtle, important ways. I suppose you might even say that pattern-driven design has, in a few ways, redesigned me. Meet the Teaser Here’s a recent example. A few months ago, some friends and I redesigned The Toast. (It was a really, really fun project, and we learned a lot.) Each page of the site is, as you might guess, stitched together from a host of tiny, reusable patterns. Some of them, like the search form and footer, are fairly unique, and used once per page; others are used more liberally, and built for reuse. The most prevalent example of these more generic patterns is the teaser, which is classed as, uh, .teaser. (Look, I never said I was especially clever.) In its simplest form, a teaser contains a headline, which links to an article: Fairly straightforward, sure. But it’s just the foundation: from there, teasers can have a byline, a description, a thumbnail, and a comment count. In other words, we have a basic building block (.teaser) that contains a few discrete content types – some required, some not. In fact, very few of those pieces need to be present; to qualify as a teaser, all we really need is a link and a headline. But by adding more elements, we can build slight variations of our teaser, and make it much, much more versatile. Nearly every element visible on this page is built out of our generic “teaser” pattern. But the teaser variation I’d like to call out is the one that appears on The Toast’s homepage, on search results or on section fronts. In the main content area, each teaser in the list features larger images, as well as an interesting visual treatment: the byline and comment count were the most prominent elements within each teaser, appearing above the headline. The approved visual design of our teaser, as it appears on lists on the homepage and the section fronts. And this is, as it happens, the teaser variation that gave me pause. Back in the old days – you know, like six months ago – I probably would’ve marked this module up to match the design. In other words, I would’ve looked at the module’s visual hierarchy (metadata up top, headline and content below) and written the following HTML:

    By Author Name

    126 comments

    Article Title

    Lorem ipsum dolor sit amet, consectetur…

    But then I caught myself, and realized this wasn’t the best approach. Moving Beyond Layout Since I’ve started working responsively, there’s a question I work into every step of my design process. Whether I’m working in Sketch, CSSing a thing, or researching a project, I try to constantly ask myself: What if someone doesn’t browse the web like I do? …Okay, that doesn’t seem especially fancy. (And maybe you came here for fancy.) But as straightforward as that question might seem, it’s been invaluable to so many aspects of my practice. If I’m working on a widescreen layout, that question helps me remember the constraints of the small screen; if I’m working on an interface that has some enhancements for touch, it helps me consider other input modes as I work. It’s also helpful as a reminder that many might not see the screen the same way I do, and that accessibility (in all its forms) should be a throughline for our work on the web. And that last point, thankfully, was what caught me here. While having the byline and comment count at the top was a lovely visual treatment, it made for a terrible content hierarchy. For example, it’d be a little weird if the page was being read aloud in a speaking browser: the name of the author and the number of comments would be read aloud before the title of the article with which they’re associated. That’s why I find it’s helpful to begin designing a pattern’s hierarchy before its layout: to move past the visual presentation in front of me, and focus on the underlying content I’m trying to support. In other words, if someone’s encountering my design without the CSS I’ve written, what should their experience be? So I took a step back, and came up with a different approach:

    Article Title

    By Author Name

    Lorem ipsum dolor sit amet, consectetur… 126 comments

    Much, much better. This felt like a better match for the content I was designing: the headline – easily most important element – was at the top, followed by the author’s name and an excerpt. And while the comment count is visually the most prominent element in the teaser, I decided it was hierarchically the least critical: that’s why it’s at the very end of the excerpt, the last element within our teaser. And with some light styling, we’ve got a respectable-looking hierarchy in place: Yeah, you’re right – it’s not our final design. But from this basic-looking foundation, we can layer on a bit more complexity. First, we’ll bolster the markup with an extra element around our title and byline: With that in place, we can use flexbox to tweak our layout, like so: .teaser-hed { display: flex; flex-direction: column-reverse; } flex-direction: column-reverse acts a bit like a change in gravity within our teaser-hed element, vertically swapping its two children. Getting closer! But as great as flexbox is, it doesn’t do anything for elements outside our container, like our little comment count, which is, as you’ve probably noticed, still stranded at the very bottom of our teaser. Flexbox is, as you might already know, wonderful! And while it enjoys incredibly broad support, there are enough implementations of old versions of Flexbox (in addition to plenty of bugs) that I tend to use a feature test to check if the browser’s using a sufficiently modern version of flexbox. Here’s the one we used: var doc = document.body || document.documentElement; var style = doc.style; if ( style.webkitFlexWrap == '' || style.msFlexWrap == '' || style.flexWrap == '' ) { doc.className += "" supports-flex""; } Eagle-eyed readers will note we could have used @supports feature queries to ask browsers if they support certain CSS properties, removing the JavaScript dependency. But since we wanted to serve the layout to IE we opted to write a little question in JavaScript, asking the browser if it supports flex-wrap, a property used elsewhere in the design. If the browser passes the test, then a class of supports-flex gets applied to our html element. And with that class in place, we can safely quarantine our flexbox-enabled layout from less-capable browsers, and finish our teaser’s design: .supports-flex .teaser-hed { display: flex; flex-direction: column-reverse; } .supports-flex .teaser .comment-count { position: absolute; right: 0; top: 1.1em; } If the supports-flex class is present, we can apply our flexbox layout to the title area, sure – but we can also safely use absolute positioning to pull our comment count out of its default position, and anchor it to the top right of our teaser. In other words, the browsers that don’t meet our threshold for our advanced styles are left with an attractive design that matches our HTML’s content hierarchy; but the ones that pass our test receive the finished, final design. And with that, our teaser’s complete. Diving Into Device-Agnostic Design This is, admittedly, a pretty modest application of flexbox. (For some truly next-level work, I’d recommend Heydon Pickering’s “Flexbox Grid Finesse”, or anything Zoe Mickley Gillenwater publishes.) And for such a simple module, you might feel like this is, well, quite a bit of work. And you’d be right! In fact, it’s not one layout, but two: a lightly styled content hierarchy served to everyone, with the finished design served conditionally to the browsers that can successfully implement it. But I’ve found that thinking about my design as existing in broad experience tiers – in layers – is one of the best ways of designing for the modern web. And what’s more, it works not just for simple modules like our teaser, but for more complex or interactive patterns as well. Open video Even a simple search form can be conditionally enhanced, given a little layered thinking. This more layered approach to interface design isn’t a new one, mind you: it’s been championed by everyone from Filament Group to the BBC. And with all the challenges we keep uncovering, a more device-agnostic approach is one of the best ways I’ve found to practice responsive design. As Trent Walton once wrote, Like cars designed to perform in extreme heat or on icy roads, websites should be built to face the reality of the web’s inherent variability. We have a weird job, working on the web. We’re designing for the latest mobile devices, sure, but we’re increasingly aware that our definition of “smartphone” is much too narrow. Browsers have started appearing on our wrists and in our cars’ dashboards, but much of the world’s mobile data flows over sub-3G networks. After all, the web’s evolution has never been charted along a straight line: it’s simultaneously getting slower and faster, with devices new and old coming online every day. With all the challenges in front of us, including many we don’t yet know about, a more device-agnostic, more layered design process can better prepare our patterns – and ourselves – for the future. (It won’t help you get enough to eat at holiday parties, though.)",2015,Ethan Marcotte,ethanmarcotte,2015-12-10T00:00:00+00:00,https://24ways.org/2015/putting-my-patterns-through-their-paces/,code 162,Conditional Love,"“Browser.” The four-letter word of web design. I mean, let’s face it: on the good days, when things just work in your target browsers, it’s marvelous. The air smells sweeter, birds’ songs sound more melodious, and both your design and your code are looking sharp. But on the less-than-good days (which is, frankly, most of them), you’re compelled to tie up all your browsers in a sack, heave them into the nearest river, and start designing all-imagemap websites. We all play favorites, after all: some will swear by Firefox, Opera fans are allegedly legion, and others still will frown upon anything less than the latest WebKit nightly. Thankfully, we do have an out for those little inconsistencies that crop up when dealing with cross-browser testing: CSS patches. Spare the Rod, Hack the Browser Before committing browsercide over some rendering bug, a designer will typically reach for a snippet of CSS fix the faulty browser. Historically referred to as “hacks,” I prefer Dan Cederholm’s more client-friendly alternative, “patches”. But whatever you call them, CSS patches all work along the same principle: supply the proper property value to the good browsers, while giving higher maintenance other browsers an incorrect value that their frustrating idiosyncratic rendering engine can understand. Traditionally, this has been done either by exploiting incomplete CSS support: #content { height: 1%; // Let's force hasLayout for old versions of IE. line-height: 1.6; padding: 1em; } html>body #content { height: auto; // Modern browsers get a proper height value. } or by exploiting bugs in their rendering engine to deliver alternate style rules: #content p { font-size: .8em; /* Hide from Mac IE5 \*/ font-size: .9em; /* End hiding from Mac IE5 */ } We’ve even used these exploits to serve up whole stylesheets altogether: @import url(""core.css""); @media tty { i{content:""\"";/*"" ""*/}} @import 'windows-ie5.css'; /*"";} }/* */ The list goes on, and on, and on. For every browser, for every bug, there’s a patch available to fix some rendering bug. But after some time working with standards-based layouts, I’ve found that CSS patches, as we’ve traditionally used them, become increasingly difficult to maintain. As stylesheets are modified over the course of a site’s lifetime, inline fixes we’ve written may become obsolete, making them difficult to find, update, or prune out of our CSS. A good patch requires a constant gardener to ensure that it adds more than just bloat to a stylesheet, and inline patches can be very hard to weed out of a decently sized CSS file. Giving the Kids Separate Rooms Since I joined Airbag Industries earlier this year, every project we’ve worked on has this in the head of its templates: The first element is, simply enough, a link element that points to the project’s main CSS file. No patches, no hacks: just pure, modern browser-friendly style rules. Which, nine times out of ten, will net you a design that looks like spilled eggnog in various versions of Internet Explorer. But don’t reach for the mulled wine quite yet. Immediately after, we’ve got a brace of conditional comments wrapped around two other link elements. These odd-looking comments allow us to selectively serve up additional stylesheets just to the version of IE that needs them. We’ve got one for IE 6 and below: And another for IE7 and above: Microsoft’s conditional comments aren’t exactly new, but they can be a valuable alternative to cooking CSS patches directly into a master stylesheet. And though they’re not a W3C-approved markup structure, I think they’re just brilliant because they innovate within the spec: non-IE devices will assume that the comments are just that, and ignore the markup altogether. This does, of course, mean that there’s a little extra markup in the head of our documents. But this approach can seriously cut down on the unnecessary patches served up to the browsers that don’t need them. Namely, we no longer have to write rules like this in our main stylesheet: #content { height: 1%; // Let's force hasLayout for old versions of IE. line-height: 1.6; padding: 1em; } html>body #content { height: auto; // Modern browsers get a proper height value. } Rather, we can simply write an un-patched rule in our core stylesheet: #content { line-height: 1.6; padding: 1em; } And now, our patch for older versions of IE goes in—you guessed it—the stylesheet for older versions of IE: #content { height: 1%; } The hasLayout patch is applied, our design’s repaired, and—most importantly—the patch is only seen by the browser that needs it. The “good” browsers don’t have to incur any added stylesheet weight from our IE patches, and Internet Explorer gets the conditional love it deserves. Most importantly, this “compartmentalized” approach to CSS patching makes it much easier for me to patch and maintain the fixes applied to a particular browser. If I need to track down a bug for IE7, I don’t need to scroll through dozens or hundreds of rules in my core stylesheet: instead, I just open the considerably slimmer IE7-specific patch file, make my edits, and move right along. Even Good Children Misbehave While IE may occupy the bulk of our debugging time, there’s no denying that other popular, modern browsers will occasionally disagree on how certain bits of CSS should be rendered. But without something as, well, pimp as conditional comments at our disposal, how do we bring the so-called “good browsers” back in line with our design? Assuming you’re loving the “one patch file per browser” model as much as I do, there’s just one alternative: JavaScript. function isSaf() { var isSaf = (document.childNodes && !document.all && !navigator.taintEnabled && !navigator.accentColorName) ? true : false; return isSaf; } function isOp() { var isOp = (window.opera) ? true : false; return isOp; } Instead of relying on dotcom-era tactics of parsing the browser’s user-agent string, we’re testing here for support for various DOM objects, whose presence or absence we can use to reasonably infer the browser we’re looking at. So running the isOp() function, for example, will test for Opera’s proprietary window.opera object, and thereby accurately tell you if your user’s running Norway’s finest browser. With scripts such as isOp() and isSaf() in place, you can then reasonably test which browser’s viewing your content, and insert additional link elements as needed. function loadPatches(dir) { if (document.getElementsByTagName() && document.createElement()) { var head = document.getElementsByTagName(""head"")[0]; if (head) { var css = new Array(); if (isSaf()) { css.push(""saf.css""); } else if (isOp()) { css.push(""opera.css""); } if (css.length) { var link = document.createElement(""link""); link.setAttribute(""rel"", ""stylesheet""); link.setAttribute(""type"", ""text/css""); link.setAttribute(""media"", ""screen, projection""); for (var i = 0; i < css.length; i++) { var tag = link.cloneNode(true); tag.setAttribute(""href"", dir + css[0]); head.appendChild(tag); } } } } } Here, we’re testing the results of isSaf() and isOp(), one after the other. For each function that returns true, then the name of a new stylesheet is added to the oh-so-cleverly named css array. Then, for each entry in css, we create a new link element, point it at our patch file, and insert it into the head of our template. Fire it up using your favorite onload or DOMContentLoaded function, and you’re good to go. Scripteat Emptor At this point, some of the audience’s more conscientious ‘scripters may be preparing to lob figgy pudding at this author’s head. And that’s perfectly understandable; relying on JavaScript to patch CSS chafes a bit against the normally clean separation we have between our pages’ content, presentation, and behavior layers. And beyond the philosophical concerns, this approach comes with a few technical caveats attached: Browser detection? So un-133t. Browser detection is not something I’d typically recommend. Whenever possible, a proper DOM script should check for the support of a given object or method, rather than the device with which your users view your content. It’s JavaScript, so don’t count on it being available. According to one site, roughly four percent of Internet users don’t have JavaScript enabled. Your site’s stats might be higher or lower than this number, but still: don’t expect that every member of your audience will see these additional stylesheets, and ensure that your content’s still accessible with JS turned off. Be a constant gardener. The sample isSaf() and isOp() functions I’ve written will tell you if the user’s browser is Safari or Opera. As a result, stylesheets written to patch issues in an old browser may break when later releases repair the relevant CSS bugs. You can, of course, add logic to these simple little scripts to serve up version-specific stylesheets, but that way madness may lie. In any event, test your work vigorously, and keep testing it when new versions of the targeted browsers come out. Make sure that a patch written today doesn’t become a bug tomorrow. Patching Firefox, Opera, and Safari isn’t something I’ve had to do frequently: still, there have been occasions where the above script’s come in handy. Between conditional comments, careful CSS auditing, and some judicious JavaScript, browser-based bugs can be handled with near-surgical precision. So pass the ‘nog. It’s patchin’ time.",2007,Ethan Marcotte,ethanmarcotte,2007-12-15T00:00:00+00:00,https://24ways.org/2007/conditional-love/,code 238,Everything You Wanted To Know About Gradients (And a Few Things You Didn’t),"Hello. I am here to discuss CSS3 gradients. Because, let’s face it, what the web really needed was more gradients. Still, despite their widespread use (or is it overuse?), the smartly applied gradient can be a valuable contributor to a designer’s vocabulary. There’s always been a tension between the inherently two-dimensional nature of our medium, and our desire for more intensity, more depth in our designs. And a gradient can evoke so much: the splay of light across your desk, the slow decrease in volume toward the end of your favorite song, the sunset after a long day. When properly applied, graded colors bring a much needed softness to our work. Of course, that whole ‘proper application’ thing is the tricky bit. But given their place in our toolkit and their prominence online, it really is heartening to see we can create gradients directly with CSS. They’re part of the draft images module, and implemented in two of the major rendering engines. Still, I’ve always found CSS gradients to be one of the more confusing aspects of CSS3. So if you’ll indulge me, let’s take a quick look at how to create CSS gradients—hopefully we can make them seem a bit more accessible, and bring a bit more art into the browser. Gradient theory 101 (I hope that’s not really a thing) Right. So before we dive into the code, let’s cover a few basics. Every gradient, no matter how complex, shares a few common characteristics. Here’s a straightforward one: I spent seconds hours designing this gradient. I hope you like it. At either end of our image, we have a final color value, or color stop: on the left, our stop is white; on the right, black. And more color-rich gradients are no different: (Don’t ever really do this. Please. I beg you.) It’s visually more intricate, sure. But at the heart of it, we have just seven color stops (red, orange, yellow, and so on), making for a fantastic gradient all the way. Now, color stops alone do not a gradient make. Between each is a transition point, the fail-over point between the two stops. Now, the transition point doesn’t need to fall exactly between stops: it can be brought closer to one stop or the other, influencing the overall shape of the gradient. A tale of two syntaxes Armed with our new vocabulary, let’s look at a CSS gradient in the wild. Behold, the simple input button: There’s a simple linear gradient applied vertically across the button, moving from a bright sunflowerish hue (#FAA51A, for you hex nuts in the audience) to a much richer orange (#F47A20). And here’s the CSS that makes it happen: input[type=submit] { background-color: #F47A20; background-image: -moz-linear-gradient( #FAA51A, #F47A20 ); background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #FAA51A), color-stop(1, #F47A20) ); } I’ve borrowed David DeSandro’s most excellent formatting suggestions for gradients to make this snippet a bit more legible but, still, the code above might have turned your stomach a bit. And that’s perfectly understandable—heck, it sort of turned mine. But let’s step through the CSS slowly, and see if we can’t make it a little less terrifying. Verbose WebKit is verbose Here’s the syntax for our little gradient on WebKit: background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #FAA51A), color-stop(1, #F47A20) ); Woof. Quite a mouthful, no? Well, here’s what we’re looking at: WebKit has a single -webkit-gradient property, which can be used to create either linear or radial gradients. The next two values are the starting and ending positions for our gradient (0 0 and 0 100%, respectively). Linear gradients are simply drawn along the path between those two points, which allows us to change the direction of our gradient simply by altering its start and end points. Afterward, we specify our color stops with the oh-so-aptly named color-stop parameter, which takes the stop’s position on the gradient (0 being the beginning, and 100% or 1 being the end) and the color itself. For a simple two-color gradient like this, -webkit-gradient has a bit of shorthand notation to offer us: background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#FAA51A), to(#FAA51A) ); from(#FAA51A) is equivalent to writing color-stop(0, #FAA51A), and to(#FAA51A) is the same as color-stop(1, #FAA51A) or color-stop(100%, #FAA51A)—in both cases, we’re simply declaring the first and last color stops in our gradient. Terse Gecko is terse WebKit proposed its syntax back in 2008, heavily inspired by the way gradients are drawn in the canvas specification. However, a different, leaner syntax came to the fore, eventually appearing in a draft module specification in CSS3. Naturally, because nothing on the web was meant to be easy, this is the one that Mozilla has implemented. Here’s how we get gradient-y in Gecko: background-image: -moz-linear-gradient( #FAA51A, #F47A20 ); Wait, what? Done already? That’s right. By default, -moz-linear-gradient assumes you’re trying to create a vertical gradient, starting from the top of your element and moving to the bottom. And, if that’s the case, then you simply need to specify your color stops, delimited with a few commas. I know: that was almost… painless. But the W3C/Mozilla syntax also affords us a fair amount of flexibility and control, by introducing features as we need them. We can specify an origin point for our gradient: background-image: -moz-linear-gradient(50% 100%, #FAA51A, #F47A20 ); As well as an angle, to give it a direction: background-image: -moz-linear-gradient(50% 100%, 45deg, #FAA51A, #F47A20 ); And we can specify multiple stops, simply by adding to our comma-delimited list: background-image: -moz-linear-gradient(50% 100%, 45deg, #FAA51A, #FCC, #F47A20 ); By adding a percentage after a given color value, we can determine its position along the gradient path: background-image: -moz-linear-gradient(50% 100%, 45deg, #FAA51A, #FCC 20%, #F47A20 ); So that’s some of the flexibility implicit in the W3C/Mozilla-style syntax. Now, I should note that both syntaxes have their respective fans. I will say that the W3C/Mozilla-style syntax makes much more sense to me, and lines up with how I think about creating gradients. But I can totally understand why some might prefer WebKit’s more verbose approach to the, well, looseness behind the -moz syntax. À chacun son gradient syntax. Still, as the language gets refined by the W3C, I really hope some consensus is reached by the browser vendors. And with Opera signaling that it will support the W3C syntax, I suppose it falls on WebKit to do the same. Reusing color stops for fun and profit But CSS gradients aren’t all simple colors and shapes and whatnot: by getting inventive with individual color stops, you can create some really complex, compelling effects. Tim Van Damme, whose brain, I believe, should be posthumously donated to science, has a particularly clever application of gradients on The Box, a site dedicated to his occasional podcast series. Now, there are a fair number of gradients applied throughout the UI, but it’s the feature image that really catches the eye. You see, there’s nothing that says you can’t reuse color stops. And Tim’s exploited that perfectly. He’s created a linear gradient, angled at forty-five degrees from the top left corner of the photo, starting with a fully transparent white (rgba(255, 255, 255, 0)). At the halfway mark, he’s established another color stop at an only slightly more opaque white (rgba(255, 255, 255, 0.1)), making for that incredibly gradual brightening toward the middle of the photo. But then he has set another color stop immediately on top of it, bringing it back down to rgba(255, 255, 255, 0) again. This creates that fantastically hard edge that diagonally bisects the photo, giving the image that subtle gloss. And his final color stop ends at the same fully transparent white, completing the effect. Hot? I do believe so. Rocking the radials We’ve been looking at linear gradients pretty exclusively. But I’d be remiss if I didn’t at least mention radial gradients as a viable option, including a modest one as a link accent on a navigation bar: And here’s the relevant CSS: background: -moz-radial-gradient(50% 100%, farthest-side, rgb(204, 255, 255) 1%, rgb(85, 85, 85) 15%, rgba(85, 85, 85, 0) ); background: -webkit-gradient(radial, 50% 100%, 0, 50% 100%, 15, from(rgb(204, 255, 255)), to(rgba(85, 85, 85, 0)) ); Now, the syntax builds on what we’ve already learned about linear gradients, so much of it might be familiar to you, picking out color stops and transition points, as well as the two syntaxes’ reliance on either a separate property (-moz-radial-gradient) or parameter (-webkit-gradient(radial, …)) to shift into circular mode. Mozilla introduces another stand-alone property (-moz-radial-gradient), and accepts a starting point (50% 100%) from which the circle radiates. There’s also a size constant defined (farthest-side), which determines the reach and shape of our gradient. WebKit is again the more verbose of the two syntaxes, requiring both starting and ending points (50% 100% in both cases). Each also accepts a radius in pixels, allowing you to control the skew and breadth of the circle. Again, this is a fairly modest little radial gradient. Time and article length (and, let’s be honest, your author’s completely inadequate grasp of geometry) prevent me from covering radial gradients in much more detail, because they are incredibly powerful. For those interested in learning more, I can’t recommend the references at Mozilla and Apple strongly enough. Leave no browser behind But no matter the kind of gradients you’re working with, there is a large swathe of browsers that simply don’t support gradients. Thankfully, it’s fairly easy to declare a sensible fallback—it just depends on the kind of fallback you’d like. Essentially, gradient-blind browsers will disregard any properties containing references to either -moz-linear-gradient, -moz-radial-gradient, or -webkit-gradient, so you simply need to keep your fallback isolated from those properties. For example: if you’d like to fall back to a flat color, simply declare a separate background-color: .nav { background-color: #000; background-image: -moz-linear-gradient(rgba(0, 0, 0, 0), rgba(255, 255, 255, 0.45)); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(0, 0, 0, 0)), to(rgba(255, 255, 255, 0.45))); } Or perhaps just create three separate background properties. .nav { background: #000; background: #000 -moz-linear-gradient(rgba(0, 0, 0, 0), rgba(255, 255, 255, 0.45)); background: #000 -webkit-gradient(linear, 0 0, 0 100%, from(rgba(0, 0, 0, 0)), to(rgba(255, 255, 255, 0.45))); } We can even build on this to fall back to a non-gradient image: .nav { background: #000 url(""faux-gradient-lol.png"") repeat-x; background: #000 -moz-linear-gradient(rgba(0, 0, 0, 0), rgba(255, 255, 255, 0.45)); background: #000 -webkit-gradient(linear, 0 0, 0 100%, from(rgba(0, 0, 0, 0)), to(rgba(255, 255, 255, 0.45))); } No matter the approach you feel most appropriate to your design, it’s really just a matter of keeping your fallback design quarantined from its CSS3-ified siblings. (If you’re feeling especially masochistic, there’s even a way to get simple linear gradients working in IE via Microsoft’s proprietary filters. Of course, those come with considerable performance penalties that even Microsoft is quick to point out, so I’d recommend avoiding those. And don’t tell Andy Clarke I told you, or he’ll probably unload his Derringer at me. Or something.) Go forth and, um, gradientify! It’s entirely possible your head’s spinning. Heck, mine is, but that might be the effects of the ’nog. But maybe you’re wondering why you should care about CSS gradients. After all, images are here right now, and work just fine. Well, there are some quick benefits that spring to mind: fewer HTTP requests are needed; CSS3 gradients are easily made scalable, making them ideal for variable widths and heights; and finally, they’re easily modifiable by tweaking a few CSS properties. Because, let’s face it, less time spent yelling at Photoshop is a very, very good thing. Of course, CSS-generated gradients are not without their drawbacks. The syntax can be confusing, and it’s still under development at the W3C. As we’ve seen, browser support is still very much in flux. And it’s possible that gradients themselves have some real performance drawbacks—so test thoroughly, and gradient carefully. But still, as syntaxes converge, and support improves, I think generated gradients can make a compelling tool in our collective belts. The tasteful design is, of course, entirely up to you. So have fun, and get gradientin’.",2010,Ethan Marcotte,ethanmarcotte,2010-12-22T00:00:00+00:00,https://24ways.org/2010/everything-you-wanted-to-know-about-gradients/,code 313,Centered Tabs with CSS,"Doug Bowman’s Sliding Doors is pretty much the de facto way to build tabbed navigation with CSS, and rightfully so – it is, as they say, rockin’ like Dokken. But since it relies heavily on floats for the positioning of its tabs, we’re constrained to either left- or right-hand navigation. But what if we need a bit more flexibility? What if we need to place our navigation in the center? Styling the li as a floated block does give us a great deal of control over margin, padding, and other presentational styles. However, we should learn to love the inline box – with it, we can create a flexible, centered alternative to floated navigation lists. Humble Beginnings Do an extra shot of ‘nog, because you know what’s coming next. That’s right, a simple unordered list: If we were wedded to using floats to style our list, we could easily fix the width of our ul, and trick it out with some margin: 0 auto; love to center it accordingly. But this wouldn’t net us much flexibility: if we ever changed the number of navigation items, or if the user increased her browser’s font size, our design could easily break. Instead of worrying about floats, let’s take the most basic approach possible: let’s turn our list items into inline elements, and simply use text-align to center them within the ul: #navigation ul, #navigation ul li { list-style: none; margin: 0; padding: 0; } #navigation ul { text-align: center; } #navigation ul li { display: inline; margin-right: .75em; } #navigation ul li.last { margin-right: 0; } Our first step is sexy, no? Well, okay, not really – but it gives us a good starting point. We’ve tamed our list by removing its default styles, set the list items to display: inline, and centered the lot. Adding a background color to the links shows us exactly how the different elements are positioned. Now the fun stuff. Inline Elements, Padding, and You So how do we give our links some dimensions? Well, as the CSS specification tells us, the height property isn’t an option for inline elements such as our anchors. However, what if we add some padding to them? #navigation li a { padding: 5px 1em; } I just love leading questions. Things are looking good, but something’s amiss: as you can see, the padded anchors seem to be escaping their containing list. Thankfully, it’s easy to get things back in line. Our anchors have 5 pixels of padding on their top and bottom edges, right? Well, by applying the same vertical padding to the list, our list will finally “contain” its child elements once again. ’Tis the Season for Tabbing Now, we’re finally able to follow the “Sliding Doors” model, and tack on some graphics: #navigation ul li a { background: url(""tab-right.gif"") no-repeat 100% 0; color: #06C; padding: 5px 0; text-decoration: none; } #navigation ul li a span { background: url(""tab-left.gif"") no-repeat; padding: 5px 1em; } #navigation ul li a:hover span { color: #69C; text-decoration: underline; } Finally, our navigation’s looking appropriately sexy. By placing an equal amount of padding on the top and bottom of the ul, our tabs are properly “contained”, and we can subsequently style the links within them. But what if we want them to bleed over the bottom-most border? Easy: we can simply decrease the bottom padding on the list by one pixel, like so. A Special Note for Special Browsers The Mac IE5 users in the audience are likely hopping up and down by now: as they’ve discovered, our centered navigation behaves rather annoyingly in their browser. As Philippe Wittenbergh has reported, Mac IE5 is known to create “phantom links” in a block-level element when text-align is set to any value but the default value of left. Thankfully, Philippe has documented a workaround that gets that [censored] venerable browser to behave. Simply place the following code into your CSS, and the links will be restored to their appropriate width: /**//*/ #navigation ul li a { display: inline-block; white-space: nowrap; width: 1px; } /**/ IE for Windows, however, displays an extra kind of crazy. The padding I’ve placed on my anchors is offsetting the spans that contain the left curve of my tabs; thankfully, these shenanigans are easily straightened out: /**/ * html #navigation ul li a { padding: 0; } /**/ And with that, we’re finally finished. All set. And that’s it. With your centered navigation in hand, you can finally enjoy those holiday toddies and uncomfortable conversations with your skeevy Uncle Eustace.",2005,Ethan Marcotte,ethanmarcotte,2005-12-08T00:00:00+00:00,https://24ways.org/2005/centered-tabs-with-css/,code 226,Documentation-Driven Design for APIs,"Documentation is like gift wrapping. It seems like superfluous fluff, but your family tends to be rather disappointed when their presents arrive in supermarket carrier bags, so you have to feign some sort of attempt at making your gift look enticing. Documentation doesn’t have to be all hard work and sellotaping yourself to a table – you can make it useful and relevant. Documentation gets a pretty rough deal. It tends to get left until the end of a project, when some poor developer is assigned the ‘document project’ ticket and wades through each feature of Whizzy New API 3.0 and needs to recall exactly what each method is meant to do. That’s assuming any time is left for documentation at all. The more common outcome resembles last minute homework scribbled on a post-it note, where just the bare bones of what’s available are put out for your users, and you hope that you’ll spot the inconsistencies and mistakes before they do. Wouldn’t it be nicer for everyone if you could make documentation not only outstanding for your users, but also a valuable tool for your development team – so much so that you couldn’t imagine writing a line of code before you’d documented it? Documentation needs to have three main features: It should have total coverage and document all the features of your project. Private methods should be documented for your developers, and public features need to be available to your users. It should be consistent – a user should know what to expect from your documentation, and terminology should be accurate to your language. It should be current – and that means staying accurate as new versions of your code base are released. But you can also get these bonuses: Act as a suggested specification – a guide that will aid a developer in making something consistent and usable. It can test your API quality. It can enhance the communication skills within your development team. So how do we get our documentation to be rich and full of features, instead of a little worn out like Boxing Day leftovers? Write your documentation first When I say first, I mean first. Not after you’ve started writing the code. Not even after you’ve started writing your unit tests. First. You may or may not have been provided with a decent specification, but the first job should be to turn your requirements for a feature into documentation. It works best when it takes the form of in-code comments. It works even better when your in-code comments take a standard documentation format that you can later use to generate published documentation for your users. This has the benefit of immediately making your docs as version controlled as your code-base, and it saves having to rewrite, copy or otherwise harass your docs into something legible later on. Almost all languages have a self-documentation format these days. My choice of format for JavaScript is JSDocToolkit, and the sort of things I look for are the ability to specify private and public methods, full options object statements (opts as Opts only is a no-no), and the ability to include good examples. So, our example for today will be a new festive feature for a JavaScript API. We’ve been asked to specify a sled for Santa to get around the world to give out toys: Santa needs to be able to travel around the world in one night to deliver toys to children, and he’ll need some reindeer to pull his sled. As documentation, it would look like: /** @name Sled @extends Vehicle @constructor @description Create a new sled to send Santa around the world to deliver toys to good kids. @param {Object} [opts] Options @param {number} [opts.capacity='50'] Set the capacity of the sled @param {string} [opts.pilot='santa'] The pilot of the sled. @example // Create a sled and specify some reindeer. new Sled().reindeer(['Dasher', 'Dancer', 'Prancer', 'Vixen', 'Comet', 'Cupid']); */ By breaking it down as documentation, you can, for example, hand this over to another developer without the need to explain the feature in much depth, and they’ll develop something that has to match this piece of documentation. It specifies everything that is important to this feature – its default values and types, and where it inherits other features from. We know that we need to specify some way of setting reindeer to pull the sled and also some toys to give, and so we can quickly specify extra methods for the sled: /* @name vehicle.Sled#reindeer @function @description Set the reindeer that will pull Santa's sled. @param {string[]} reindeer A list of the reindeer. @example // specifying some reindeer Sled().reindeer(['Dasher', 'Dancer', 'Rudolph', 'Vixen']); */ /* @name vehicle.Sled#toys @function @description Add a list of toys and recipients to the Sled. @param {Object[]} toys A list of toys and who will receive them. @example // Adding toys to the sled Sled().toys([ {name:'Brian', toy:'Fire Engine'}, {name:'Drew', toy:'Roller-skates'}, {name:'Anna', toy:'Play-doh'}, ... ]); */ Job done! You’ve got a specification to share with your team and something useful for your users in the form of full examples, and you didn’t even have to open another text editor. Use your documentation to share knowledge Documentation isn’t just for users. It’s also used by internal developers to explain what they’ve written and how it works. This is especially valuable where the team is large or the code-base sprawling. So, returning to our example, the next step would be to share with the rest of the team (or at least a selection of the team if yours is large) what the documentation looks like. This is useful for two main reasons: They can see if they understand what the documentation says the feature will do. It’s best if they haven’t seen the requirement before. If your fellow developers can’t work out what ‘MagicMethodX’ is going to return from the docs, neither can your users. They can check that the feature accomplishes everything that they expect to, and that it’s consistent with the rest of the functionality. On previous projects, we’ve taken to referring to this stage of the development process as the ‘bun fight’. It’s a chance for everyone to have an honest say and throw a few pies without actually causing anyone to have to rewrite any code. If you can identify at this stage that a feature is over-complicated, lacking or just plain useless, you’ll all be much happier to throw out a few lines of documentation than you may have been to throw out a partial, or even complete, piece of functionality. Documentation has your back The final benefit to working in this way is that your documentation not only remains accurate, it’s always as accurate as your latest release. It can’t fall behind. You can increase the likelihood that your docs will remain up to date by unit testing your examples. Returning to the previous example, we can add a QUnit unit test to the expected output with ease during the build process – we know exactly how the code will look and, with the @example tag, we can identify easily where to find the bits that need testing. If it’s tested it’ll definitely work as you expect it to when a user copy and pastes it. You’re ensuring quality from idea to implementation. As an extra bauble, the best thing about a system like JSDocToolkit is that it’ll take your inline comments and turn them into beautiful sites, as good systems will allow for customised output templates. You’ll be producing full-featured sites for your projects and plugins with almost no extra effort, but all the benefits.",2010,Frances Berriman,francesberriman,2010-12-11T00:00:00+00:00,https://24ways.org/2010/documentation-driven-design-for-apis/,process 289,Front-End Developers Are Information Architects Too,"The theme of this year’s World IA Day was “Information Everywhere, Architects Everywhere”. This article isn’t about what you may consider an information architect to be: someone in the user-experience field, who maybe studied library science, and who talks about taxonomies. This is about a realisation I had a couple of years ago when I started to run an increasing amount of usability-testing sessions with people who have disabilities: that the structure, labelling, and connections that can be made in front-end code is information architecture. People’s ability to be successful online is unequivocally connected to the quality of the code that is written. Places made of information In information architecture we talk about creating places made of information. These places are made of ones and zeros, but we talk about them as physical structures. We talk about going onto a social media platform, posting in blogs, getting locked out of an environment, and building applications. In 2002, Andrew Hinton stated: People live and work in these structures, just as they live and work in their homes, offices, factories and malls. These places are not virtual: they are as real as our own minds. 25 Theses We’re creating structures which people rely on for significant parts of their lives, so it’s critical that we carry out our work responsibly. This means we must use our construction materials correctly. Luckily, our most important material, HTML, has a well-documented specification which tells us how to build robust and accessible places. What is most important, I believe, is to understand the semantics of HTML. Semantics The word “semantic” has its origin in Greek words meaning “significant”, “signify”, and “sign”. In the physical world, a structure can have semantic qualities that tell us something about it. For example, the stunning Westminster Abbey inspires awe and signifies much about the intent and purpose of the structure. The building’s size; the quality of the stone work; the massive, detailed stained glass: these are all signs that this is a building meant for something the creators deemed important. Alternatively consider a set of large, clean, well-positioned, well-lit doors on the ground floor of an office block: they don’t need an “entrance” sign to communicate their use and to stop people trying to use a nearby fire exit to get into the building. The design of the doors signify their usage. Sometimes a more literal and less awe-inspiring approach to communicating a building’s purpose happens, but the affect is similar: the building is signifying something about its purpose. HTML has over 115 elements, many of which have semantics to signify structure and affordance to people, browsers, and assistive technology. The HTML 5.1 specification mentions semantics, stating: Elements, attributes, and attribute values in HTML are defined … to have certain meanings (semantics). For example, the
      element represents an ordered list, and the lang attribute represents the language of the content. HTML 5.1 Semantics, structure, and APIs of HTML documents HTML’s baked-in semantics means that developers can architect their code to signify structure, create relationships between elements, and label content so people can understand what they’re interacting with. Structuring and labelling information to make it available, usable, and understandable to people is what an information architect does. It’s also what a front-end developer does, whether they realise it or not. A brief introduction to information architecture We’re going to start by looking at what an information architect is. There are many definitions, and I’m going to quote Richard Saul Wurman, who is widely regarded as the father of information architecture. In 1976 he said an information architect is: the individual who organizes the patterns inherent in data, making the complex clear; a person who creates the structure or map of information which allows others to find their personal paths to knowledge; the emerging 21st century professional occupation addressing the needs of the age focused upon clarity, human understanding, and the science of the organization of information. Of Patterns And Structures To me, this clearly defines any developer who creates code that a browser, or other user agent (for example, a screen reader), uses to create a structured, navigable place for people. Just as there are many definitions of what an information architect is, there are for information architecture itself. I’m going to use the definition from the fourth edition of Information Architecture For The World Wide Web, in which the authors define it as: The structural design of shared information environments. The synthesis of organization, labeling, search, and navigation systems within digital, physical, and cross-channel ecosystems. The art and science of shaping information products and experiences to support usability, findability, and understanding. Information Architecture For The World Wide Web, 4th Edition To me, this describes front-end development. Done properly, there is an art to creating robust, accessible, usable, and findable spaces that delight all our users. For example, at 2015’s State Of The Browser conference, Edd Sowden talked about the accessibility of s. He discovered that by simply not using the semantically-correct
      element to mark up headings, in some situations browsers will decide that a
      is being used for layout and essentially make it invisible to assistive technology. Another example of how coding practices can affect the usability and findability of content is shown by Léonie Watson in her How ARIA landmark roles help screen reader users video. By using ARIA landmark roles, people who use screen readers are quickly able to identify and jump to common parts of a web page. Our definitions of information architects and information architecture mention patterns, rules, organisation, labelling, structure, and relationships. There are numerous different models for how these elements get boiled down to their fundamentals. In his Understanding Context book, Andrew Hinton calls them Labels, Relationships, and Rules; Jorge Arango calls them Links, Nodes, And Order; and Dan Klyn uses Ontology, Taxonomy, and Choreography, which is the one we’re going to use. Dan defines these terms as: Ontology The definition and articulation of the rules and patterns that govern the meaning of what we intend to communicate. What we mean when we say what we say. Taxonomy The arrangements of the parts. Developing systems and structures for what everything’s called, where everything’s sorted, and the relationships between labels and categories Choreography Rules for interaction among the parts. The structures it creates foster specific types of movement and interaction; anticipating the way users and information want to flow and making affordance for change over time. We now have definitions of an information architect, information architecture, and a model of the elements of information architecture. But is writing HTML really creating information or is it just wrangling data and metadata? When does data turn into information? In his book Managing For The Future Peter Drucker states: … data is not information. Information is data endowed with relevance and purpose. Managing For The Future If we use the correct semantic element to mark up content then we’re developing with purpose and creating relevance. For example, if we follow the advice of the HTML 5.1 specification and mark up headings using heading rank instead of the outline algorithm, we’re creating a structure where the depth of one heading is relevant to the previous one. Architected correctly, an

      element should be relevant to its parent, which should be the

      . By following the HTML specification we can create a structured, searchable, labeled document that will hopefully be relevant to what our users need to be successful. If you’ve never used a screen reader, you might be wondering how the headings on a page are searchable. Screen readers give users the ability to interact with headings in a couple of ways: by creating a list of headings so users can quickly scan the page for information by using a keyboard command to cycle through one heading at a time If we had a document for Christmas Day TV we might structure it something like this:

      Christmas Day TV schedule

      BBC1

      Morning

      Evening

      BBC2

      Morning

      Evening

      ITV

      Morning

      Evening

      Channel 4

      Morning

      Evening

      If I use VoiceOver to generate a list of headings, I get this: Once I have that list I can use keyboard commands to filter the list based on the heading level. For example, I can press 2 to hear just the

      s: If we hadn’t used headings, of if we’d nested them incorrectly, our users would be frustrated. Putting this together Let’s put this together with an example of a button that, when pressed, toggles the appearance of a panel of links. There are numerous ways we could create a button on a web page, but the best way is to just use a There’s quite a bit going on here. We’re using the: aria-controls attribute to architect a connection between the Color picker This is our new color picker function. It targets the input element by its class and gets its value. function getColor() { return document.querySelector("".color"").value; } Up until now, the app used a default color (black) for the paint brush/digital pen. If we want to change the color we need to use the canvas property strokeStyle. We’ll update drawLine by adding strokeStyle to it and setting it to the input value by calling getColor. function drawLine() { //...code... context.strokeStyle = getColor(); context.lineWidth = 4; context.lineCap = ""round""; //...code... } Clear button This is our new Clear function. It responds to a button click and displays a dialog asking the user if she really wants to delete the drawing. function clearCanvas() { if (confirm(""Want to clear?"")) { context.clearRect(0, 0, w, h); } } The method clearRect takes four arguments. The first two (0,0) mark the origin, which is actually the top left corner of the canvas. The other two (w,h) mark the full width and height of the canvas. This means the entire canvas will be erased, from the top left corner to the bottom right corner. If we were to give clearRect a slightly different set of arguments, say (0,0,w/2,h), the result would be different. In this case, only the left side of the canvas would clear up. Let’s add this event handler to init: function init() { //...code... canvas.onpointermove = handleMouseMove; canvas.onpointerdown = handleMouseDown; canvas.onpointerup = stopDrawing; canvas.onpointerout = stopDrawing; document.querySelector("".clear"").onclick = clearCanvas; } See the Pen Mandala Maker Tutorial: Part 2 by Hagar Shilo (@hagarsh) on CodePen. Part 3: Draw with 2 lines It’s time to make a line appear where no pointer has gone before. A ghost line! For that we are going to need four new coordinates: a', b', c' and d' (marked in the code as a_, b_, c_ and d_). In order for us to be able to add the first reflection, first we must decide if it’s going to go over the y-axis or the x-axis. Since this is an arbitrary decision, it doesn’t matter which one we choose. Let’s go with the x-axis. Here is a sketch to help you grasp the mathematics of reflecting a point across the x-axis. The coordinate space in my sketch is different from my explanation earlier about the way the coordinate space works in computer graphics (more about that in a bit!). Now, look at A. It shows a point drawn where the pointer hits, and B shows the additional point we want to appear: a reflection of the point across the x-axis. This is our goal. A sketch illustrating the mathematics of reflecting a point. What happens to the x coordinates? The variables a/a' and c/c' correspond to prevX and currX respectively, so we can call them “the x coordinates”. We are reflecting across x, so their values remain the same, and therefore a' = a and c' = c. What happens to the y coordinates? What about b' and d'? Those are the ones that have to change, but in what way? Thanks to the slightly misleading sketch I showed you just now (of A and B), you probably think that the y coordinates b' and d' should get the negative values of b and d respectively, but nope. This is computer graphics, remember? The origin is at the top left corner and not at the canvas center, and therefore we get the following values: b = h - b, d' = h - d, where h is the canvas height. This is the new code for the app’s variables and the two lines: the one that fills the pointer’s path and the one mirroring it across the x-axis. function drawLine() { var a = prevX, a_ = a, b = prevY, b_ = h-b, c = currX, c_ = c, d = currY, d_ = h-d; //... code ... // Draw line #1, at the pointer's location context.moveTo(a, b); context.lineTo(c, d); // Draw line #2, mirroring the line #1 context.moveTo(a_, b_); context.lineTo(c_, d_); //... code ... } In case this was too abstract for you, let’s look at some actual numbers to see how this works. Let’s say we have a tiny canvas of w = h = 10. Now let a = 3, b = 2, c = 4 and d = 3. So b' = 10 - 2 = 8 and d' = 10 - 3 = 7. We use the top and the left as references. For the y coordinates this means we count from the top, and 8 from the top is also 2 from the bottom. Similarly, 7 from the top is 3 from the bottom of the canvas. That’s it, really. This is how the single point, and a line (not necessarily a straight one, by the way) is made up of many, many small segments that are similar to point in behavior. If you are still confused, I don’t blame you. Here is the result. Draw something and see what happens. See the Pen Mandala Maker Tutorial: Part 3 by Hagar Shilo (@hagarsh) on CodePen. Part 4: Draw with 8 lines I have made yet another confusing sketch, with points C and D, so you understand what we’re trying to do. Later on we’ll look at points E, F, G and H as well. The circled point is the one we’re adding at each particular step. The circled point at C has the coordinates (-3,2) and the circled point at D has the coordinates (-3,-2). Once again, keep in mind that the origin in the sketches is not the same as the origin of the canvas. A sketch illustrating points C and D. This is the part where the math gets a bit mathier, as our drawLine function evolves further. We’ll keep using the four new coordinates: a', b', c' and d', and reassign their values for each new location/line. Let’s add two more lines in two new locations on the canvas. Their locations relative to the first two lines are exactly what you see in the sketch above, though the calculation required is different (because of the origin points being different). function drawLine() { //... code ... // Reassign values a_ = w-a; b_ = b; c_ = w-c; d_ = d; // Draw the 3rd line context.moveTo(a_, b_); context.lineTo(c_, d_); // Reassign values a_ = w-a; b_ = h-b; c_ = w-c; d_ = h-d; // Draw the 4th line context.moveTo(a_, b_); context.lineTo(c_, d_); //... code ... What is happening? You might be wondering why we use w and h as separate variables, even though we know they have the same value. Why complicate the code this way for no apparent reason? That’s because we want the symmetry to hold for a rectangular canvas as well, and this way it will. Also, you may have noticed that the values of a' and c' are not reassigned when the fourth line is created. Why write their value assignments twice? It’s for readability, documentation and communication. Maintaining the quadruple structure in the code is meant to help you remember that all the while we are dealing with two y coordinates (current and previous) and two x coordinates (current and previous). What happens to the x coordinates? As you recall, our x coordinates are a (prevX) and c (currX). For the third line we are adding, a' = w - a and c' = w - c, which means… For the fourth line, the same thing happens to our x coordinates a and c. What happens to the y coordinates? As you recall, our y coordinates are b (prevY) and d (currY). For the third line we are adding, b' = b and d' = d, which means the y coordinates are the ones not changing this time, making this is a reflection across the y-axis. For the fourth line, b' = h - b and d' = h - d, which we’ve seen before: that’s a reflection across the x-axis. We have four more lines, or locations, to define. Note: the part of the code that’s responsible for drawing a micro-line between the newly calculated coordinates is always the same: context.moveTo(a_, b_); context.lineTo(c_, d_); We can leave it out of the next code snippets and just focus on the calculations, i.e, the reassignments. Once again, we need some concrete examples to see where we’re going, so here’s another sketch! The circled point E has the coordinates (2,3) and the circled point F has the coordinates (2,-3). The ability to draw at A but also make the drawing appear at E and F (in addition to B, C and D that we already dealt with) is the functionality we are about to add to out code. A sketch illustrating points E and F. This is the code for E and F: // Reassign for 5 a_ = w/2+h/2-b; b_ = w/2+h/2-a; c_ = w/2+h/2-d; d_ = w/2+h/2-c; // Reassign for 6 a_ = w/2+h/2-b; b_ = h/2-w/2+a; c_ = w/2+h/2-d; d_ = h/2-w/2+c; Their x coordinates are identical and their y coordinates are reversed to one another. This one will be out final sketch. The circled point G has the coordinates (-2,3) and the circled point H has the coordinates (-2,-3). A sketch illustrating points G and H. This is the code: // Reassign for 7 a_ = w/2-h/2+b; b_ = w/2+h/2-a; c_ = w/2-h/2+d; d_ = w/2+h/2-c; // Reassign for 8 a_ = w/2-h/2+b; b_ = h/2-w/2+a; c_ = w/2-h/2+d; d_ = h/2-w/2+c; //...code... } Once again, the x coordinates of these two points are the same, while the y coordinates are different. And once again I won’t go into the full details, since this has been a long enough journey as it is, and I think we’ve covered all the important principles. But feel free to play around with the code and change it. I really recommend commenting out the code for some of the points to see what your drawing looks like without them. I hope you had fun learning! This is our final app: See the Pen Mandala Maker Tutorial: Part 4 by Hagar Shilo (@hagarsh) on CodePen.",2018,Hagar Shilo,hagarshilo,2018-12-02T00:00:00+00:00,https://24ways.org/2018/the-art-of-mathematics/,code 236,Extreme Design,"Recently, I set out with twelve other designers and developers for a 19th century fortress on the Channel Island of Alderney. We were going to /dev/fort, a sort of band camp for geeks. Our cohort’s mission: to think up, build and finish something – without readily available internet access. Alderney runway, photo by Chris Govias Wait, no internet? Well, pretty much. As the creators of /dev/fort James Aylett and Mark Norman Francis put it: “Imagine a place with no distractions – no IM, no Twitter”. But also no way to quickly look up a design pattern, code sample or source material. Like packing for camping, /dev/fort means bringing everything you’ll need on your back or your hard drive: from long johns to your favourite icon set. We got to work the first night discussing ideas for what we wanted to build. By the time breakfast was cleared up the next morning, we’d settled on Russ’s idea to make the Apollo 13 (PDF) transcript accessible. Days two and three were spent collaboratively planning (KJ style) what features we wanted to build, and unravelling the larger UX challenges of the project. The next five days were spent building it. Within 36 hours of touchdown at Southampton Airport, we launched our creation: spacelog.org The weather was cold, the coal fire less than ideal, food and supplies a hike away, and the process lightning-fast. A week of designing under extreme circumstances called for an extreme process. Some of this was driven by James’s and Norm’s experience running these things, but a lot of it materialised while we were there – especially for our three-strong design team (myself, Gavin O’ Carroll and Chris Govias) who, though we knew each other, had never worked together as a group in this kind of scenario before. The outcome was a pretty spectacular process, with a some key takeaways useful for any small group trying to build something quickly. What it’s like inside the fort /dev/fort has the pressure and pace of a hack day without being a hack day – primarily, no workshops or interruptions‚ but also a different mentality. While hack days are typically developer-driven with a ‘hack first, design later (if at all)’ attitude, James was quick to tell the team to hold off from writing any code until we had a plan. This put a healthy pressure on the design and product folks to slash through the UX problems before we started building. While the fort had definitely more of a hack day feel, all of us were familiar with Agile methods, so we borrowed a few useful techniques such as morning stand-ups and an emphasis on teamwork. We cut some really good features to make our launch date, and chunked the work based on user goals, iterating as we went. What made this design process work? A golden ratio of teams My personal experience both professionally and in free-form situations like this, is a tendency to get/hire a designer. Leaders of businesses, founders of start-ups, organisers of events: one designer is not enough! Finding one ace-blooded designer who can ‘do everything’ will always result in bottleneck and burnout. Like the nuances between different development languages, design is a multifaceted discipline, and very few can claim to be equally strong in every aspect. Overlap in skill set will result in a stronger, more robust interface. More importantly, however, having lots of designers to go around meant that we all had the opportunity to pair with developers, polishing the details that don’t usually get polished. As soon as we launched, the public reception of the design and UX was overwhelmingly positive (proof!). But also, a lot of people asked us who the designer was, attributing it to one person. While it’s important to note that everyone in our team was multitalented (and could easily shift between roles, helping us all stay unblocked), the golden ratio James and Norm devised was two product/developer folks, three interaction designers and eight developers. photo by Ben Firshman Equality inside the fortress walls Something magical about the fort is how everyone leaves the outside world on the drawbridge. Job titles, professional status, Twitter followers, and so on. Like scout camp, a mutual respect and trust is expected of all the participants. Like extreme programming, extreme design requires us all to be equal partners in a collaborative team. I think this is especially worth noting for designers; our past is filled with the clear hierarchy of the traditional studio system which, however important for taste and style, seems less compatible with modern web/software development methods. Being equal doesn’t mean being the same, however. We established clear roles and teams for ourselves on the second day, deferring to that person when a decision needed to be made. As the interface coalesced, the designers and developers took ownership over certain parts to ensure the details got looked after, while staying open to ideas and revisions from the rest of the cohort. Create a space where everyone who enters is equal, but be sure to establish clear roles. Even if it’s just for a short while, the environment will be beneficial. photo by Ben Firshman Hang your heraldry from the rafters Forts and castles are full of lore: coats of arms; paintings of battles; suits of armour. It’s impossible not to be surrounded by these stories, words and ways of thinking. Like the whiteboards on the walls, putting organisational lore in your physical surroundings makes it impossible not to see. Ryan Alexander brought some of those static-cling whiteboard sheets which were quickly filled with use cases; IA; team roles; and, most importantly, a glossary. As soon as we started working on the project, we realised we needed to get clear on what certain words meant: what was a logline, a range, a phase, a key moment? Were the back-end people using these words in the same way design and product was? Quickly writing up a glossary of terms meant everyone was instantly speaking the same language. There was no “Ah, I misunderstood because in the data structure x means y” or, even worse, accidental seepage of technical language into the user interface copy. Put a glossary of your internal terminology somewhere big and fat on the wall. Stand around it and argue until you agree on what it says. Leave it up; don’t underestimate the power of ambient communication and physical reference. Plan more, download less While internet is forbidden inside the fort, we did go on downloading expeditions: NASA photography; code documentation; and so on. The project wouldn’t have been possible without a few trips to the web. We had two lists on the wall: groceries and supplies; internets – “loo roll; Tom Stafford photo“. This changed our usual design process, forcing us to plan carefully and think of what we needed ahead of time. Getting to the internet was a thirty-minute hike up a snow covered cliff to the town airport, so you really had to need it, too. The path to the internet For the visual design, especially, this resulted in more focus up front, and communication between the designers on what assets we required. It made us make decisions earlier and stick with them, creating less distraction and churn later in the process. Try it at home: unplug once you’ve got the things you need. As an artist, it’s easier to let your inner voice shine through if you’re not looking at other people’s work while creating. Social design Finally, our design team experimented with a collaborative approach to wireframing. Once we had collectively nailed down use cases, IA, user journeys and other critical artefacts, we tried a pairing approach. One person drew in Illustrator in real time as the other two articulated what to draw. (This would work equally well with two people, but with three it meant that one of us could jump up and consult the lore on the walls or clarify a technical detail.) The result: we ended up considering more alternatives and quickly rallying around one solution, and resolved difficult problems more quickly. At a certain stage we discovered it was more efficient for one person to take over – this happened around the time when the basic wireframes existed in Illustrator and we’d collectively run through the use cases, making sure that everything was accounted for in a broad sense. At this point, take a break, go have a beer, and give yourself a pat on the back. Put the files somewhere accessible so everyone can use them as their base, and divide up the more detailed UI problems, screens or journeys. At this level of detail it’s better to have your personal headspace. Gavin called this ‘social design’. Chatting and drawing in real time turned what was normally a rather solitary act into a very social process, with some really promising results. I’d tried something like this before with product or developer folks, and it can work – but there’s something really beautiful about switching places and everyone involved being equally quick at drawing. That’s not something you get with non-designers, and frequent swapping of the ‘driver’ and ‘observer’ roles is a key aspect to pairing. Tackle the forest collectively and the trees individually – it will make your framework more robust and your details more polished. Win/win. The return home Grateful to see a 3G signal on our phones again, our flight off the island was delayed, allowing for a flurry of domain name look-ups, Twitter catch-up, and e-mails to loved ones. A week in an isolated fort really made me appreciate continuous connectivity, but also just how unique some of these processes might be. You just never know what crazy place you might be designing from next.",2010,Hannah Donovan,hannahdonovan,2010-12-09T00:00:00+00:00,https://24ways.org/2010/extreme-design/,process 21,Keeping Parts of Your Codebase Private on GitHub,"Open source is brilliant, there’s no denying that, and GitHub has been instrumental in open source’s recent success. I’m a keen open-sourcerer myself, and I have a number of projects on GitHub. However, as great as sharing code is, we often want to keep some projects to ourselves. To this end, GitHub created private repositories which act like any other Git repository, only, well, private! A slightly less common issue, and one I’ve come up against myself, is the desire to only keep certain parts of a codebase private. A great example would be my site, CSS Wizardry; I want the code to be open source so that people can poke through and learn from it, but I want to keep any draft blog posts private until they are ready to go live. Thankfully, there is a very simple solution to this particular problem: using multiple remotes. Before we begin, it’s worth noting that you can actually build a GitHub Pages site from a private repo. You can keep the entire source private, but still have GitHub build and display a full Pages/Jekyll site. I do this with csswizardry.net. This post will deal with the more specific problem of keeping only certain parts of the codebase (branches) private, and expose parts of it as either an open source project, or a built GitHub Pages site. N.B. This post requires some basic Git knowledge. Adding your public remote Let’s assume you’re starting from scratch and you currently have no repos set up for your project. (If you do already have your public repo set up, skip to the “Adding your private remote” section.) So, we have a clean slate: nothing has been set up yet, we’re doing all of that now. On GitHub, create two repositories. For the sake of this article we shall call them site.com and private.site.com. Make the site.com repo public, and the private.site.com repo private (you will need a paid GitHub account). On your machine, create the site.com directory, in which your project will live. Do your initial work in there, commit some stuff — whatever you need to do. Now we need to link this local Git repo on your machine with the public repo (remote) on GitHub. We should all be used to this: $ git remote add origin git@github.com:[user]/site.com.git Here we are simply telling Git to add a remote called origin which lives at git@github.com:[user]/site.com.git. Simple stuff. Now we need to push our current branch (which will be master, unless you’ve explicitly changed it) to that remote: $ git push -u origin master Here we are telling Git to push our master branch to a corresponding master branch on the remote called origin, which we just added. The -u sets upstream tracking, which basically tells Git to always shuttle code on this branch between the local master branch and the master branch on the origin remote. Without upstream tracking, you would have to tell Git where to push code to (and pull it from) every time you ran the push or pull commands. This sets up a permanent bond, if you like. This is really simple stuff, stuff that you will probably have done a hundred times before as a Git user. Now to set up our private remote. Adding your private remote We’ve set up our public, open source repository on GitHub, and linked that to the repository on our machine. All of this code will be publicly viewable on GitHub.com. (Remember, GitHub is just a host of regular Git repositories, which also puts a nice GUI around it all.) We want to add the ability to keep certain parts of the codebase private. What we do now is add another remote repository to the same local repository. We have two repos on GitHub (site.com and private.site.com), but only one repository (and, therefore, one directory) on our machine. Two GitHub repos, and one local one. In your local repo, check out a new branch. For the sake of this article we shall call the branch dev. This branch might contain work in progress, or draft blog posts, or anything you don’t want to be made publicly viewable on GitHub.com. The contents of this branch will, in a moment, live in our private repository. $ git checkout -b dev We have now made a new branch called dev off the branch we were on last (master, unless you renamed it). Now we need to add our private remote (private.site.com) so that, in a second, we can send this branch to that remote: $ git remote add private git@github.com:[user]/private.site.com.git Like before, we are just telling Git to add a new remote to this repo, only this time we’ve called it private and it lives at git@github.com:[user]/private.site.com.git. We now have one local repo on our machine which has two remote repositories associated with it. Now we need to tell our dev branch to push to our private remote: $ git push -u private dev Here, as before, we are pushing some code to a repo. We are saying that we want to push the dev branch to the private remote, and, once again, we’ve set up upstream tracking. This means that, by default, the dev branch will only push and pull to and from the private remote (unless you ever explicitly state otherwise). Now you have two branches (master and dev respectively) that push to two remotes (origin and private respectively) which are public and private respectively. Any work we do on the master branch will push and pull to and from our publicly viewable remote, and any code on the dev branch will push and pull from our private, hidden remote. Adding more branches So far we’ve only looked at two branches pushing to two remotes, but this workflow can grow as much or as little as you’d like. Of course, you’d never do all your work in only two branches, so you might want to push any number of them to either your public or private remotes. Let’s imagine we want to create a branch to try something out real quickly: $ git checkout -b test Now, when we come to push this branch, we can choose which remote we send it to: $ git push -u private test This pushes the new test branch to our private remote (again, setting the persistent tracking with -u). You can have as many or as few remotes or branches as you like. Combining the two Let’s say you’ve been working on a new feature in private for a few days, and you’ve kept that on the private remote. You’ve now finalised the addition and want to move it into your public repo. This is just a simple merge. Check out your master branch: $ git checkout master Then merge in the branch that contained the feature: $ git merge dev Now master contains the commits that were made on dev and, once you’ve pushed master to its remote, those commits will be viewable publicly on GitHub: $ git push Note that we can just run $ git push on the master branch as we’d previously set up our upstream tracking (-u). Multiple machines So far this has covered working on just one machine; we had two GitHub remotes and one local repository. Let’s say you’ve got yourself a new Mac (yay!) and you want to clone an existing project: $ git clone git@github.com:[user]/site.com.git This will not clone any information about the remotes you had set up on the previous machine. Here you have a fresh clone of the public project and you will need to add the private remote to it again, as above. Done! If you’d like to see me blitz through all that in one go, check the showterm recording. The beauty of this is that we can still share our code, but we don’t have to develop quite so openly all of the time. Building a framework with a killer new feature? Keep it in a private branch until it’s ready for merge. Have a blog post in a Jekyll site that you’re not ready to make live? Keep it in a private drafts branch. Working on a new feature for your personal site? Tuck it away until it’s finished. Need a staging area for a Pages-powered site? Make a staging remote with its own custom domain. All this boils down to, really, is the fact that you can bring multiple remotes together into one local codebase on your machine. What you do with them is entirely up to you!",2013,Harry Roberts,harryroberts,2013-12-09T00:00:00+00:00,https://24ways.org/2013/keeping-parts-of-your-codebase-private-on-github/,code 303,We Need to Talk About Technical Debt,"In my work with clients, a lot of time is spent assessing old, legacy, sprawling systems and identifying good code, bad code, and technical debt. One thing that constantly strikes me is the frequency with which bad code and technical debt are conflated, so let me start by saying this: Not all technical debt is bad code, and not all bad code is technical debt. Sometimes your bad code is just that: bad code. Calling it technical debt often feels like a more forgiving and friendly way of referring to what may have just been a poor implementation or a substandard piece of work. It is an oft-misunderstood phrase, and when mistaken for meaning ‘anything legacy or old hacky or nasty or bad’, technical debt is swept under the carpet along with all of the other parts of the codebase we’d rather not talk about, and therein lies the problem. We need to talk about technical debt. What We Talk About When We Talk About Technical Debt The thing that separates technical debt from the rest of the hacky code in our project is the fact that technical debt, by definition, is something that we knowingly and strategically entered into. Debt doesn’t happen by accident: debt happens when we choose to gain something otherwise-unattainable immediately in return for paying it back (with interest) later on. An Example You’re a front-end developer working on a SaaS product, and your sales team is courting a large customer – a customer so large that you can’t really afford to lose them. The customer tells you that as long as you can allow them to theme your SaaS application according to their branding, they are willing to sign on the dotted line… the problem being that your CSS architecture was never designed to incorporate theming at all, and there isn’t currently a nice, clean way to incorporate a theme into the codebase. You and the business make the decision that you will hack a theme into the product in two days. It’s going to be messy, it’s going to be ugly, but you can’t afford to lose a huge customer just because your CSS isn’t quite right, right now. This is technical debt. You deliver the theme, the customer signs up, and everyone is happy. Except you (and the business, because you are one and the same) have a decision to make: Do we go back and build theming into the CSS architecture as a first-class citizen, porting the hacked theme back into a codified and formal framework? Do we carry on as we are? Things are working okay, and the customer paid up, so is there any reason to invest time and effort into things after we (and the customer) got what we wanted? Option 1 is choosing to pay off your debts; Option 2 is ignoring your repayments. With Option 1, you’re acknowledging that you did what you could given the constraints, but, free of constraints, you’d have done something different. Now, you are choosing to implement that something different. With Option 2, however, you are avoiding your responsibility to repay your debt, and you are letting interest accrue. The problem here is that… your SaaS product now offers theming to one of your customers; another potential customer might also demand the ability to theme their instance of your product; you can’t refuse them that request, nor can you quickly fulfil it; you hack in another theme, thus adding to the balance of your existing debt; and so on (plus interest) for every subsequent theme you need to implement. Here you have increased entropy whilst making little to no attempt to address what you already knew to be problems. Your second, third, fourth, fifth request for theming will be hacked on top of your hack, further accumulating debt whilst offering nothing by way of a repayment. After a long enough period, the code involved will get so unwieldy, so hard to work with, that you are forced to tear it all down and start again, and the most painful part of this is that you’re actually paying off even more than your debt repayments would have been in the first place. Two days of hacking plus, say, five days of subsequent refactoring, would still have been substantially less than the weeks you will now have to spend rewriting your CSS to fix and incorporate the themes properly. You’ve made a loss; your strategic debt ultimately became a loss-making exercise. The important thing to note here is that you didn’t necessarily write bad code. You knew there were two options: the quick way and the correct way. The decision to take the quick route was a definite choice, because you knew there was a better way. Implementing the better way is your repayment. Good Debt and Bad Debt Technical debt is acceptable as long as you have intentions to settle; it can be a valuable solution to a business problem, provided the right approach is taken afterwards. That doesn’t, however, mean that all debt is born equal. Just as in real life, there is good debt and there is bad debt. Good debt might be… a mortgage; a student loan, or; a business loan. These are types of debt that will secure you the means of repaying them. These are well considered debts whose very reason for being will allow you to make the money to pay them off—they have real, tangible benefit. A business loan to secure some equipment and premises will allow you to start an enterprise whose revenue will allow you to pay that debt back; a student loan will allow you to secure the kind of job that has the ability to pay a student loan back. These kinds of debt involve a considered and well-balanced decision to acquire something in the short term in the knowledge that you will have the means, in the long term, to pay it back. Conversely, bad debt might be… borrowing $1,000 from a loan shark so you can go to Vegas, or; taking out a payday loan in order to buy a new television. Both of these kinds of debt will leave you paying for things that didn’t provide you a way of earning your own capital. That is to say, the loans taken did not secure anything that would help pay off said loans. These are bad debts that will usually provide a net loss. You really are only gaining the short term in exchange for a long term financial responsibility: i.e., was it worth it? A good litmus test for debt is to compare the gains of its immediate benefit with the cost of its long term commitment. The earlier example of theming a site is a good debt, provided we are keeping up our repayments (all debt is bad debt if you don’t). A calculated decision to do something ‘wrong’ in the short term with the promise of better payoffs later on. Bad Technical Debt The majority of my work is with front-end development teams—CSS is what I do. To that end, the most succinct example of technical debt for that audience is simply: !important All front-end developers know the horrors and dangers associated with using !important, yet we continue to use it. Why? It’s not necessarily because we’re bad developers, but because we see a shortcut. !important is usually implemented as a quick way out of a sticky specificity situation. We could spend the rest of the day refactoring our CSS to fix the issue at its source, or we can spend mere seconds typing the word !important and patch over the symptoms. This is us making an explicit decision to do something less than ideal now in exchange for immediate benefit. After all, refactoring our CSS will take a lot more time, and will still only leave us with the same outcome that the vastly quicker !important solution will, so it seems to make better business sense. However, this is a bad debt. !important takes seconds to implement but weeks to refactor. The cost of refactoring this back out later will be an order of magnitude higher than it would be to have done things properly the first time. The first !important usually sets a precedent, and subsequent developers are likely to have to use it themselves in order to get around the one that you left. So many CSS projects deteriorate because of this one simple word, and rewrites become more and more imminent. That makes it possibly the most costly 10 bytes a CSS developer could ever write. Bad Code Now we’ve got a good idea of what constitutes technical debt, let’s take a look at what constitutes bad code. Something I hear time and time again in my client work goes a little like this: We’ve amassed a lot of technical debt and we’d like to get a strategy in place to begin dealing with it. Whilst I genuinely admire their willingness to identify and desire to fix problems in their code, sometimes they’re not looking at technical debt at all—sometimes they’re just looking at bad code, plain and simple. Where technical debt is knowing that there’s a better way, but the quicker way makes more sense right now, bad code is not caring if there’s a better way at all. Again, looking at a CSS-specific world, a lot of bad code is contributed by non-front-end developers with little training, appreciation, or even respect for the front-end landscape. Writing code with reckless abandon should not be described as technical debt, because to do so would imply that… the developers knew they were implementing a sub-par solution, but… the developers also knew that a better solution was out there, which… implies that it can be tidied up relatively simply. Developers writing bad code is a larger and more cultural problem that requires a lot more effort to fix. Hopefully—and usually—bad code is in the minority, but it helps to be objective in identifying and solving it. Bad code usually doesn’t happen for a good enough reason, and is therefore much harder to justify. Technical debt often represents ability in judgement, whereas bad code often represents a gap in skills. Takeaway Take time to familiarise yourself with the true concepts underlying technical debt and why it exists. Understand that technical debt can be good or bad. Admit that sometimes code is just of poor quality. Understanding these points will allow you to make better calls around what you might need to refactor and when, and what skills gaps you might have in your team. Sometimes it’s okay to cut corners if there is a tangible gain to be had in the immediate term. Technical debt is okay provided it is a sensible debt and you have intentions to pay it off. Technical debt is not necessarily synonymous with bad code, and bad code isn’t necessarily technical debt. Technical debt is code that was implemented given limited knowledge or resource, with the understanding that you would need to repay something in future. Technical debt is not inherently bad—failure to make repayments is. Periodically, it is justifiable—encouraged, even—to enter a debt in order to fulfil a more pressing matter. However, it is imperative that we begin making repayments as soon as we are capable, be that based on newly available time or knowledge. Bad code is worse than technical debt as it represents a lack of knowledge or quality control within a team. It needs a much more fundamental fix.",2016,Harry Roberts,harryroberts,2016-12-05T00:00:00+00:00,https://24ways.org/2016/we-need-to-talk-about-technical-debt/,code 60,What’s Ahead for Your Data in 2016?,"Who owns your data? Who decides what can you do with it? Where can you store it? What guarantee do you have over your data’s privacy? Where can you publish your work? Can you adapt software to accommodate your disability? Is your tiny agency subject to corporate regulation? Does another country have rights over your intellectual property? If you aren’t the kind of person who is interested in international politics, I hate to break it to you: in 2016 the legal foundations which underpin our work on the web are being revisited in not one but three major international political agreements, and every single one of those questions is up for grabs. These agreements – the draft EU Data Protection Regulation (EUDPR), the Trans-Pacific Partnership (TPP), and the draft Transatlantic Trade and Investment Partnership (TTIP) – stand poised to have a major impact on your data, your workflows, and your digital rights. While some proposed changes could protect the open web for the future, other provisions would set the internet back several decades. In this article we will review the issues you need to be aware of as a digital professional. While each of these agreements covers dozens of topics ranging from climate change to food safety, we will focus solely on the aspects which pertain to the work we do on the web. The Trans-Pacific Partnership The Trans-Pacific Partnership (TPP) is a free trade agreement between the US, Japan, Malaysia, Vietnam, Singapore, Brunei, Australia, New Zealand, Canada, Mexico, Chile and Peru – a bloc comprising 40% of the world’s economy. The agreement is expected to be signed by all parties, and thereby to come into effect, in 2016. This agreement is ostensibly about the bloc and its members working together for their common interests. However, the latest draft text of the TPP, which was formulated entirely in secret, has only been made publicly available on a Medium blog published by the U.S. Trade Representative which features a patriotic banner at the top proclaiming “TPP: Made in America.” The message sent about who holds the balance of power in this agreement, and whose interests it will benefit, is clear. By far the most controversial area of the TPP has centred around the provisions on intellectual property. These include copyright terms of up to 120 years, mandatory takedowns of allegedly infringing content in response to just one complaint regardless of that complaint’s validity, heavy and disproportionate penalties for alleged violations, and – most frightening of all – government seizures of equipment allegedly used for copyright violations. All of these provisions have been raised without regard for the fact that a trade agreement is not the appropriate venue to negotiate intellectual property law. Other draft TPP provisions would restrict the digital rights of people with disabilities by banning the workarounds they use every day. These include no exemptions for the adaptations of copywritten works for use in accessible technology (such as text-to-speech in ebook readers), a ban on circumventing DRM or digital locks in order to convert a file to an accessible format, and requiring the takedown of adapted works, such as a video with added subtitles, even if that adaptation would normally have fallen under the definition of fair use. The e-commerce provisions would prohibit data localisation, the practice of requiring data to be physically stored on servers within a country’s borders. Data localisation is growing in popularity following the Snowden revelations, and some of your own personal data may have been recently “localised” in response to the Safe Harbor verdict. Prohibiting data localisation through the TPP would address the symptom but not the cause. The Electronic Frontier Foundation has published an excellent summary of the digital rights issues raised by the agreement along with suggested actions American readers can take to speak out. Transatlantic Trade and Investment Partnership TTIP stands for the Transatlantic Trade and Investment Partnership, a draft free trade agreement between the United States and the EU. The plan has been hugely controversial and divisive, and the internet and digital provisions of the draft form just a small part of that contention. The most striking digital provision of TTIP is an attempt to circumvent and override European data protection law. As EDRI, a European digital rights organisation, noted: “the US proposal would authorise the transfer of EU citizens’ personal data to any country, trumping the EU data protection framework, which ensures that this data can only be transferred in clearly defined circumstances. For years, the US has been trying to bypass the default requirement for storage of personal data in the EU. It is therefore not surprising to see such a proposal being {introduced} in the context of the trade negotiations.” This draft provision was written before the Safe Harbor data protection agreement between the EU and US was invalidated by the Court of Justice of the European Union. In other words, there is no longer any protective agreement in place, and our data is as vulnerable as this political situation. However, data protection is a matter of its own law, the acting Data Protection Directive and the draft EU Data Protection Reform. A trade agreement, be it the TTIP or the TPP, is not the appropriate place to revamp a law on data protection. Other digital law issues raised by TTIP include the possibility of renegotiating standards on encryption (which in practice means lowering them) and renegotiating intellectual property rights such as copyright. The spectre of net neutrality has even put in an appearance, with an attempt to introduce rules on access to the internet itself being introduced as provisions. TTIP is still under discussion, and this month the EU trade representative said that “we agreed to further intensify our work during 2016 to help negotiations move forward rapidly.” This has been cleverly worded: this means the agreement has little chance of being passed or coming into effect in 2016, which buys civil society more precious time to speak out. The EU Data Protection Regulation On 15 December 2015 the European Commission announced their agreement on the text of the draft General Data Protection Regulation. This law will replace its predecessor, the EU Data Protection Regulation of 1995, which has done a remarkable job of protecting data privacy across the continent throughout two decades of constant internet evolution. The goal of the reform process has been to return power over data, and its uses, to citizens. Users will have more control over what data is captured about them, how it is used, how it is retained, and how it can be deleted. Businesses and digital professionals, in turn, will have to restructure their relationships with client and customer data. Compliance obligations will increase, and difficult choices will have to be made. However, this time should be seen as an opportunity to rethink our relationship with data. After Snowden, Schrems, and Safe Harbor, it is clear that we cannot go back to the way things were before. In an era of where every one of our heartbeats is recorded on a wearable device and uploaded to a surveilled data centre in another country, the need for reform has never been more acute. While texts of the draft GDPR are available, there is not enough mulled wine in the world that will help you get through them. Instead, the law firm Fieldfisher Waterhouse has produced this helpful infographic which will give you a good idea of the changes we can expect to see (view full size): The most surprising outcome announced on 15 December was the new regulation’s teeth. Under the new law, companies that fail to heed the updated data protection rules will face fines of up to 4% of their global turnover. Additionally, the law expands the liability for data protection to both the controller (the company hosting the data) and the data processor (the company using the data). The new law will also introduce a one-stop shop for resolving concerns over data misuse. Companies will no longer be able to headquarter their European operations in countries which are perceived to have relatively light-touch data protection enforcement (that means you, Ireland) as a means of automatically rejecting any complaints filed by citizens outside that country. For digital professionals, the most immediate concern is analytics. In fact, I am going to make a prediction: in 2016 we will begin to see the same misguided war on analytics that we saw on cookies. By increasing the legal liabilities for both data processors and controllers – in other words, the company providing the analytics as well as the site administrator studying them – the new regulation risks creating disproportionate burdens as well as the same “guilt by association” risks we saw in 2012. There have already been statements made by some within the privacy community that analytics are tracking, and tracking is surveillance, therefore analytics are evil. Yet “just don’t use analytics,” as was suggested by one advocate, is simply not an option. European regulators should consult with the web community to gain a clear understanding of why analytics are vital to everyday site administrators, and must find a happy medium that protects users’ data without criminalising every website by default. No one wants a repeat of the crisis of consent, as well as the scaremongering, caused by the cookie law. Assuming the text is adopted in 2016, the new EU Data Protection Regulation would not come into effect until 2018. We have a considerable challenge ahead, but we also have plenty of time to get it right.",2015,Heather Burns,heatherburns,2015-12-21T00:00:00+00:00,https://24ways.org/2015/whats-ahead-for-your-data-in-2016/,business 114,How To Create Rockband'ism,"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’t just want a shopping experience – we want an engagement with a company we can relate to. Let me get back to “feeling cool” – if we want to feel cool, we might get the companies we buy from to support that. That’s why I am on a mission to make companies into rockbands. Now when I say rockbands – I don’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 “rockband’ism”. This word is the definition of a childhood dream version of being in a rockband – the feeling of being more respected and loved and cool, than a cockroach or a suit on the floor of a company. Rockband’ism Rockband’ism is what we aspire to, to feel cool and happy. 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. I have listed a couple of things you could do today to become a rockband, as a person or as a company. 1 – Give your support to companies that make a difference to their surroundings – 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). 2 – 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 – this can also be implemented for business. 3 – WWRD? – “what would a rockband do”? or if you are into Kenny Rogers – 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. 4 – Start leading instead of managing – 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. 5 – Respect and confide in, that people are the best at what they do. If they aren’t, they won’t be around for long. If they are and you keep on buggin’ them, they won’t be around for long either. 6 – Don’t be arrogant – Because audiences can’t stand it – talk to people as a person not as a company. 7 – Focus on your return on involvement – know that you get a return on, what you involve yourself in. No matter if it’s bingo, communities, talks, ornithology or un-conferences. 8 – Find out where you can make a difference and do it. Don’t leave it up to everybody else to save the world. 9 – 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. 10 – Last but not least – if you’re not happy – do something else, become another type of rockband, maybe a soloist of a sort, or an orchestra. No more business as usual This really isn’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. 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 eBook that you can get on Toothless Tiger Press for free. 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.",2008,Henriette Weber,henrietteweber,2008-12-07T00:00:00+00:00,https://24ways.org/2008/how-to-create-rockbandism/,business 299,What the Heck Is Inclusive Design?,"Naming things is hard. And I don’t just mean CSS class names and JSON properties. Finding the right term for what we do with the time we spend awake and out of bed turns out to be really hard too. I’ve variously gone by “front-end developer”, “user experience designer”, and “accessibility engineer”, all clumsy and incomplete terms for labeling what I do as an… erm… see, there’s the problem again. It’s tempting to give up entirely on trying to find the right words for things, but this risks summarily dispensing with thousands of years spent trying to qualify the world around us. So here we are again. Recently, I’ve been using the term “inclusive design” and calling myself an “inclusive designer” a lot. I’m not sure where I first heard it or who came up with it, but the terminology feels like a good fit for the kind of stuff I care to do when I’m not at a pub or asleep. This article is about what I think “inclusive design” means and why I think you might like it as an idea. Isn’t ‘inclusive design’ just ‘accessibility’ by another name? No, I don’t think so. But that’s not to say the two concepts aren’t related. Note the ‘design’ part in ‘inclusive design’ — that’s not just there by accident. Inclusive design describes a design activity; a way of designing things. This sets it apart from accessibility — or at least our expectations of what ‘accessibility’ entails. Despite every single accessibility expert I know (and I know a lot) recommending that accessibility should be integrated into design process, it is rarely ever done. Instead, it is relegated to an afterthought, limiting its effect. The term ‘accessibility’ therefore lacks the power to connote design process. It’s not that we haven’t tried to salvage the term, but it’s beginning to look like a lost cause. So maybe let’s use a new term, because new things take new names. People get that. The ‘access’ part of accessibility is also problematic. Before we get ahead of ourselves, I don’t mean access is a problem — access is good, and the more accessible something is the better. I mean it’s not enough by itself. Imagine a website filled with poorly written and lackadaisically organized information, including a bunch of convoluted and confusing functionality. To make this site accessible is to ensure no barriers prevent people from accessing the content. But that doesn’t make the content any better. It just means more people get to suffer it. Whoopdidoo. Access is certainly a prerequisite of inclusion, but accessibility compliance doesn’t get you all the way there. It’s possible to check all the boxes but still be left with an unusable interface. And unusable interfaces are necessarily inaccessible ones. Sure, you can take an unusable interface and make it accessibility compliant, but that only placates stakeholders’ lawyers, not users. Users get little value from it. So where have we got to? Access is important, but inclusion is bigger than access. Inclusive design means making something valuable, not just accessible, to as many people as we can. So inclusive design is kind of accessibility + UX? Closer, but there are some problems with this definition. UX is, you will have already noted, a broad term encompassing activities ranging from conducting research studies to optimizing the perceived affordance of interface elements. But overall, what I take from UX is that it’s the pursuit of making interfaces understandable. As it happens, WCAG 2.0 already contains an ‘Understandable’ principle covering provisions such as readability, predictability and feedback. So you might say accessibility — at least as described by WCAG — already covers UX. Unfortunately, the criteria are limited, plus some really important stuff (like readability) is relegated to the AAA level; essentially “bonus points if you get the time (you won’t).” So better to let UX folks take care of this kind of thing. It’s what they do. Except, therein lies a danger. UX professionals don’t tend to be well versed in accessibility, so their ‘solutions’ don’t tend to work for that many people. My friend Billy Gregory coined the term SUX, or “Some UX”: if it doesn’t work for different users, it’s only doing part of the job it should be. SUX won’t do, but it’s not just a disability issue. All sorts of user circumstances go unchecked when you’re shooting straight for what people like, and bypassing what people need: device type, device settings, network quality, location, native language, and available time to name just a few. In short, inclusive design means designing things for people who aren’t you, in your situation. In my experience, mainstream UX isn’t very good at that. By bolting accessibility onto mainstream UX we labor under the misapprehension that most people have a ‘normal’ experience, a few people are exceptions, and that all of the exceptions pertain to disability directly. So inclusive design isn’t really about disability? It is about disability, but not in the same way as accessibility. Accessibility (as it is typically understood, anyway) aims to make sure things work for people with clinically recognized disabilities. Inclusive design aims to make sure things work for people, not forgetting those with clinically recognized disabilities. A subtle, but not so subtle, difference. Let’s go back to discussing readability, because that’s a good example. Now: everyone benefits from readable text; text with concise sentences and widely-understood words. It certainly helps people with cognitive impairments, but it doesn’t hinder folks who have less trouble with comprehension. In fact, they’ll more than likely be thankful for the time saved and the clarity. Readable text covers the whole gamut. It’s — you’ve got it — inclusive. Legibility is another one. A clear, well-balanced typeface makes the reading experience less uncomfortable and frustrating for all concerned, including those who have various forms of visual dyslexia. Again, everyone’s happy — so why even contemplate a squiggly, sketchy typeface? Leave well alone. Contrast too. No one benefits from low contrast; everyone benefits from high contrast. Simple. There’s no more work involved, it just entails better decision making. And that’s what design is really: decision making. How about zoom support? If you let your users pinch zoom on their phones they can compensate for poor eyesight, but they can also increase the touch area of controls, inspect detail in images, and compose better screen shots. Unobtrusively supporting options like zoom makes interfaces much more inclusive at very little cost. And when it comes to the underlying HTML code, you’re in luck: it has already been designed, from the outset, to be inclusive. HTML is a toolkit for inclusion. Using the right elements for the job doesn’t just mean the few who use screen readers benefit, but keyboard accessibility comes out-of-the-box, you can defer to browser behavior rather than writing additional scripts, the code is easier to read and maintain, and editors can create content that is effortlessly presentable. Wait… are you talking about universal design? Hmmm. Yes, I guess some folks might think of “universal design” and “inclusive design” as synonymous. I just really don’t like the term universal in this context. The thing is, it gives the impression that you should be designing for absolutely everyone in the universe. Though few would adopt a literal interpretation of “universal” in this context, there are enough developers who would deliberately misconstrue the term and decry universal design as an impossible task. I’ve actually had people push back by saying, “what, so I’ve got to make it work for people who are allergic to computers? What about people in comas?” For everyone’s sake, I think the term ‘inclusive’ is less misleading. Of course you can’t make things that everybody can use — it’s okay, that’s not the aim. But with everything that’s possible with web technologies, there’s really no need to exclude people in the vast numbers that we usually are. Accessibility can never be perfect, but by thinking inclusively from planning, through prototyping to production, you can cast a much wider net. That means more and happier users at very little if any more effort. If you like, inclusive design is the means and accessibility is the end — it’s just that you get a lot more than just accessibility along the way. Conclusion That’s inclusive design. Or at least, that’s a definition for a thing I think is a good idea which I identify as inclusive design. I’ll leave you with a few tips. Involve code early Web interfaces are made of code. If you’re not working with code, you’re not working on the interface. That’s not to say there’s anything wrong with sketching or paper prototyping — in fact, I recommend paper prototyping in my book on inclusive design. Just work with code as soon as you can, and think about code even before that. Maintain a pattern library of coded solutions and omit any solutions that don’t adhere to basic accessibility guidelines. Respect conventions Your content should be fresh, inventive, radical. Your interface shouldn’t. Adopt accepted conventions in the appearance, placement and coding of interface elements. Users aren’t there to experience interface design; they’re there to use an interface. In other words: stop showing off (unless, of course, the brief is to experiment with new paradigms in interface design, for an audience of interface design researchers). Don’t be exact “Perfection is the enemy of good”. But the pursuit of perfection isn’t just to be avoided because nothing ever gets finished. Exacting design also makes things inflexible and brittle. If your design depends on elements retaining precise coordinates, they’ll break easily when your users start adjusting font settings or zooming. Choose not to position elements exactly or give them fixed, “magic number” dimensions. Make less decisions in the interface so your users can make more decisions for it. Enforce simplicity The virtue of simplicity is difficult to overestimate. The simpler an interface is, the easier it is to use for all kinds of users. Simpler interfaces require less code to make too, so there’s an obvious performance advantage. There are many design decisions that require user research, but keeping things simple is always the right thing to do. Not simplified or simple-seeming or simplistic, but simple. Do a little and do it well, for as many people as you can.",2016,Heydon Pickering,heydonpickering,2016-12-07T00:00:00+00:00,https://24ways.org/2016/what-the-heck-is-inclusive-design/,process 136,Making XML Beautiful Again: Introducing Client-Side XSL,"Remember that first time you saw XML and got it? When you really understood what was possible and the deep meaning each element could carry? Now when you see XML, it looks ugly, especially when you navigate to a page of XML in a browser. Well, with every modern browser now supporting XSL 1.0, I’m going to show you how you can turn something as simple as an ATOM feed into a customised page using a browser, Notepad and some XSL. What on earth is this XSL? XSL is a family of recommendations for defining XML document transformation and presentation. It consists of three parts: XSLT 1.0 – Extensible Stylesheet Language Transformation, a language for transforming XML XPath 1.0 – XML Path Language, an expression language used by XSLT to access or refer to parts of an XML document. (XPath is also used by the XML Linking specification) XSL-FO 1.0 – Extensible Stylesheet Language Formatting Objects, an XML vocabulary for specifying formatting semantics XSL transformations are usually a one-to-one transformation, but with newer versions (XSL 1.1 and XSL 2.0) its possible to create many-to-many transformations too. So now you have an overview of XSL, on with the show… So what do I need? So to get going you need a browser an supports client-side XSL transformations such as Firefox, Safari, Opera or Internet Explorer. Second, you need a source XML file – for this we’re going to use an ATOM feed from Flickr.com. And lastly, you need an editor of some kind. I find Notepad++ quick for short XSLs, while I tend to use XMLSpy or Oxygen for complex XSL work. Because we’re doing a client-side transformation, we need to modify the XML file to tell it where to find our yet-to-be-written XSL file. Take a look at the source XML file, which originates from my Flickr photos tagged sky, in ATOM format. The top of the ATOM file now has an additional instruction, as can been seen on Line 2 below. This instructs the browser to use the XSL file to transform the document. Your first transformation Your first XSL will look something like this: This is pretty much the starting point for most XSL files. You will notice the standard XML processing instruction at the top of the file (line 1). We then switch into XSL mode using the XSL namespace on all XSL elements (line 2). In this case, we have added namespaces for ATOM (line 4) and Dublin Core (line 5). This means the XSL can now read and understand those elements from the source XML. After we define all the namespaces, we then move onto the xsl:output element (line 6). This enables you to define the final method of output. Here we’re specifying html, but you could equally use XML or Text, for example. The encoding attributes on each element do what they say on the tin. As with all XML, of course, we close every element including the root. The next stage is to add a template, in this case an as can be seen below: Making XML beautiful again : Transforming ATOM The beautiful thing about XSL is its English syntax, if you say it out loud it tends to make sense. The / value for the match attribute on line 8 is our first example of XPath syntax. The expression / matches any element – so this will match against any element in the document. As the first element in any XML document is the root element, this will be the one matched and processed first. Once we get past our standard start of a HTML document, the only instruction remaining in this is to look for and match all elements using the in line 14, above.

      This new template (line 12, above) matches and starts to write the new HTML elements out to the output stream. The does exactly what you’d expect – it finds the value of the item specifed in its select attribute. With XPath you can select any element or attribute from the source XML. The last part is a repeat of the now familiar from before, but this time we’re using it inside of a called template. Yep, XSL is full of recursion…
    1. ()

    2. The which matches atom:entry (line 1) occurs every time there is a element in the source XML file. So in total that is 20 times, this is naturally why XSLT is full of recursion. This has been matched and therefore called higher up in the document, so we can start writing list elements directly to the output stream. The first part is simply a

      with a link wrapped within it (lines 3-7). We can select attributes using XPath using @. The second part of this template selects the date, but performs a XPath string function on it. This means that we only get the date and not the time from the string (line 9). This is achieved by getting only the part of the string that exists before the T. Regular Expressions are not part of the XPath 1.0 string functions, although XPath 2.0 does include them. Because of this, in XSL we tend to rely heavily on the available XML output. The third part of the template (line 12) is a again, but this time we use an attribute of called disable output escaping to turn escaped characters back into XML. The very last section is another call, taking us three templates deep. Do not worry, it is not uncommon to write XSL which go 20 or more templates deep! tag In our final , we see a combination of what we have done before with a couple of twists. Once we match atom:category we then count how many elements there are at that same level (line 2). The XPath . means ‘self’, so we count how many category elements are within the element. Following that, we start to output a link with a rel attribute of the predefined text, tag (lines 4-6). In XSL you can just type text, but results can end up with strange whitespace if you do (although there are ways to simply remove all whitespace). The only new XPath function in this example is concat(), which simply combines what XPaths or text there might be in the brackets. We end the output for this tag with an actual tag name (line 10) and we add a space afterwards (line 12) so it won’t touch the next tag. (There are better ways to do this in XSL using the last() XPath function). After that, we go back to the element again if there is another category element, otherwise we end the loop and end this . A touch of style Because we’re using recursion through our templates, you will find this is the end of the templates and the rest of the XML will be ignored by the parser. Finally, we can add our CSS to finish up. (I have created one for Flickr and another for News feeds) So we end up with a nice simple to understand but also quick to write XSL which can be used on ATOM Flickr feeds and ATOM News feeds. With a little playing around with XSL, you can make XML beautiful again. All the files can be found in the zip file (14k)",2006,Ian Forrester,ianforrester,2006-12-07T00:00:00+00:00,https://24ways.org/2006/beautiful-xml-with-xsl/,code 142,Revealing Relationships Can Be Good Form,"A few days ago, a colleague of mine – someone I have known for several years, who has been doing web design for several years and harks back from the early days of ZDNet – was running through a prototype I had put together for some user testing. As with a lot of prototypes, there was an element of ‘smoke and mirrors’ to make things look like they were working. One part of the form included a yes/no radio button, and selecting the Yes option would, in the real and final version of the form, reveal some extra content. Rather than put too much JavaScript in the prototype, I took a preverbial shortcut and created a link which I wrapped around the text next to the radio button – clicking on that link would cause the form to mimic a change event on the radio button. But it wasn’t working for him. Why was that? Because whereas I created the form using a

      ... Check out the example. Fun with Backgrounds Pop in a tiled background to give your table some character! Internet Explorer’s PNG hack unfortunately only works well when applied to a cell. To figure out which background will appear over another, just remember the hierarchy: (bottom) Table → Column → Row Group → Row → Cell (top) The Future is Bright Once browser-makers start implementing CSS3, we’ll have more power at our disposal. Just with :first-child and :last-child, you can pull off a scalable version of our previous table with rounded corners and all — unfortunately, only Firefox manages to pull this one off successfully. And the selector the masses are clamouring for, nth-child, will make zebra tables easy as eggnog.",2005,Jonathan Snook,jonathansnook,2005-12-19T00:00:00+00:00,https://24ways.org/2005/tables-with-style/,code 112,User Styling,"During the recent US elections, Twitter decided to add an ‘election bar’ as part of their site design. You could close it if it annoyed you, but the action wasn’t persistent and the bar would always come back like a bad penny. The solution to common browsing problems like this is CSS. ‘User styling’ (or the creepy ‘skinning’) is the creation of CSS 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: Improving personal readability by changing text size and colour Personalising the look of a web app like GMail to look less insipid Revealing microformats Sport! My dreams of site skinning tennis are not yet fully realised, but it’ll be all the rage by next Christmas, believe me. Hopefully you’re now asking “But how? HOW?!”. The process of creating a site skin is roughly as follows: See something you want to change Find out what it’s called, and if any rules already apply to it Write CSS rule(s) to override and/or enhance it. Apply the rules So let’s get stuck in… See something Let’s start small with Multimap.com. Look at that big header – it takes up an awful lot of screen space doesn’t it? No matter, we can fix it. Tools Now we need to find out where that big assed header is in the DOM, and make overriding CSS rules. The best tool I’ve found yet is the Mac OS X app, CSS Edit. It utilises a slick ‘override stylesheets’ function and DOM Inspector. Rather than give you all the usual DOM inspection tools, CSS Edit’s is solely concerned with style. Go into ‘X-Ray’ 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 CSS. It really is a user styling dream app. Having said all that, you can achieve all this with free, cross platform tools – namely Firefox with the Firebug and Stylish extensions. We’ll be using them for these examples, so make sure you have them installed if you want to follow along. 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 header. Change Something When you installed Stylish, it added a page and brush icon to your status bar. Click on that, and choose Write Style > for Multimap.com. The other options allow you to only create a style for a particular part of a website or URL, but we want this to apply to the whole of Multimap: The ‘Add Style’ window then pops up, with the @-moz-document query at the top: @namespace url(http://www.w3.org/1999/xhtml); @-moz-document domain(""multimap.com"") { } All you need to do is add the CSS to hide the header, in between the curly brackets. @namespace url(http://www.w3.org/1999/xhtml); @-moz-document domain(""multimap.com"") { #header {display: none;} } A click of the preview button shows us that it’s worked! Now the map appears further up the page. The ethics of hiding adverts is a discussion for another time, but let’s face it, when did you last whoop at the sight of a banner? Make Something Better If we’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 userstyles.org is the place to do it. It’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 “Find Styles for this Page”. Selecting this with “BBC News” shows that there are plenty of options, ranging from small layout tweaks to redesigns: What’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’ll cover ways of applying site styles to other browsers later. Specific Techniques Important! In the Multimap example there wasn’t a display specified on that element, but it isn’t always going to be that easy. You may have spent most of your CSS life being a good designer and not resorting to adding !important to give your rule priority. There’s no way to avoid this in user styling – if you’re overriding an existing rule it’s a necessity! Be prepared to be typing !important a lot. Star Selector The Universal Selector is a particularly useful way to start a style. For example, if we want to make Flickr use Helvetica before Arial (as they should’ve done!), we can cover all occurrences with just one rule: * {font-family: ""Helvetica Neue"", Helvetica, sans-serif !important;} You can also use it to select ‘everything within an element’, by placing it after the element name: #content * {font-family: ""Helvetica Neue"", Helvetica, sans-serif !important;} Swapping Images If you’re changing something a little more complex, such as Google Reader, then at some point you’ll probably want to change an . The technique for replacing an image involves: making your replacement image the background of the tag adding padding top and left to the size of you image to push the ‘top’ image away making the height and width zero. 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: img[src=""/reader/ui/3544433079-tree-view-folder-open.gif""] { padding: 16px 0 0 16px; width: 0 !important; height: 0 !important; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYA AAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAA Bx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdE VYdENyZWF0aW9uIFRpbWUAMjkvNi8wOJJ/BVgAAAG3SURBVDiNpZIhb5RBEIaf 2W+vpIagIITSBIHBgsGjEYQaFLYShcITDL+ABIPnh4BFN0GQNFA4Cnf3fbszL2L3 jiuEVLDJbCazu8+8Mzsmif9ZBvDy7bvXlni0HRe8eXL/zuPzABng62J5kFKaAQS QgJAOgHMB9vDZq+d71689Hcyw9LfAZAYdioE10VSJo6OPL/KNvSuHD+7dhU 0vHEsDUUWJChIlYJIjFx5BuMB2mJY/DnMoOJl/R147oBUR0QAm8LAGCOEh3IO ULiAl8jSOy/nPetGsbGRKjktEiBCEHMlQj4loCuu4zCXCi4lUHTNDtGqEiACTqAFSI OgAUAKv4bkWVy2g6tAbJtGy0TNugM3HADmlurKH27dVZSecxjboXggiAsMItR h99wTILdewYRpXVJWtY85k7fPW8e1GpJFJacgesXs6VYYomz9G2yDhwPB7NEB BDAMK7WYJlisYVBCpfaJBeB+eocFyVyAgCaoMCTJSTOOCWSyILrAnaXpSexRsx GGAZ0AR+XT+5fjzyfwSpnUB/1w64xizVI/t6q3b+58+vJ96mWtLf9haxNoc8M v7N3d+AT4XPcFIxghoAAAAAElFTkSuQmCC) no-repeat !important; } Woah boy! What was all that gubbins in the background-image? It was a Data URI, and you can create these easily with Hixie’s online tool. It’s simply the image translated into text so that it can be embedded in the CSS, cutting down on the number of http requests. It’s also a necessity with Mozilla browsers, as they don’t allow user CSS to reference images stored locally. Converting images to URI’s avoids this, as well as making a style easily portable – no images folder to pass around. Don’t forget all your other CSS techniques at your disposal: inserting your own content with :before and :after pseudo classes, make elements semi-transparent with opacity and round box corners without hacking . You can have fun, and for once, enjoy the freedom of not worrying about IE! User styling without Stylish 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? Opera & Omniweb: Both allow you to specify a custom CSS file as part of the site’s preferences. Opera also allows custom javascript, using the same syntax as Greasemonkey scripts (more on that below) Safari There are a few options here: the PithHelmet and SafariStand haxies both allow custom stylesheets, or alternatively, a Greasemonkey style user script can employed via GreaseKit. The latter is my favoured solution on my Helvetireader 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. What now? Hopefully I’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 ‘Holy Grail’, then off with you to GMail – I get more requests to theme that than anything else! If you’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: 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 CSS file (chosen via Preferences > Advanced > Stylesheet) without affecting other sites. One final revelation on user styling – it’s not just for web sites. You can tweak the UI of Firefox itself with the userChrome.css. You’ll need to use the in-built DOM 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.",2008,Jon Hicks,jonhicks,2008-12-03T00:00:00+00:00,https://24ways.org/2008/user-styling/,process 288,Displaying Icons with Fonts and Data- Attributes,"Traditionally, bitmap formats such as PNG have been the standard way of delivering iconography on websites. They’re quick and easy, and it also ensures they’re as pixel crisp as possible. Bitmaps have two drawbacks, however: multiple HTTP requests, affecting the page’s loading performance; and a lack of scalability, noticeable when the page is zoomed or viewed on a screen with a high pixel density, such as the iPhone 4 and 4S. The requests problem is normally solved by using CSS sprites, combining the icon set into one (physically) large image file and showing the relevant portion via background-position. While this works well, it can get a bit fiddly to specify all the positions. In particular, scalability is still an issue. A vector-based format such as SVG sounds ideal to solve this, but browser support is still patchy. The rise and adoption of web fonts have given us another alternative. By their very nature, they’re not only scalable, but resolution-independent too. No need to specify higher resolution graphics for high resolution screens! That’s not all though: Browser support: Unlike a lot of new shiny techniques, they have been supported by Internet Explorer since version 4, and, of course, by all modern browsers. We do need several different formats, however! Design on the fly: The font contains the basic graphic, which can then be coloured easily with CSS – changing colours for themes or :hover and :focus styles is done with one line of CSS, rather than requiring a new graphic. You can also use CSS3 properties such as text-shadow to add further effects. Using -webkit-background-clip: text;, it’s possible to use gradient and inset shadow effects, although this creates a bitmap mask which spoils the scalability. Small file size: specially designed icon fonts, such as Drew Wilson’s Pictos font, can be as little as 12Kb for the .woff font. This is because they contain fewer characters than a fully fledged font. You can see Pictos being used in the wild on sites like Garrett Murray’s Maniacal Rage. As with all formats though, it’s not without its disadvantages: Icons can only be rendered in monochrome or with a gradient fill in browsers that are capable of rendering CSS3 gradients. Specific parts of the icon can’t be a different colour. It’s only appropriate when there is an accompanying text to provide meaning. This can be alleviated by wrapping the text label in a tag (I like to use rather than , due to the fact that it’s smaller and isn’ t being used elsewhere) and then hiding it from view with text-indent:-999em. Creating an icon font can be a complex and time-consuming process. While font editors can carry out hinting automatically, the best results are achieved manually. Unless you’re adept at creating your own fonts, you’re restricted to what is available in the font. However, fonts like Pictos will cover the most common needs, and icons are most effective when they’re using familiar conventions. The main complaint about using fonts for icons is that it can mean adding a meaningless character to our markup. The good news is that we can overcome this by using one of two methods – CSS generated content or the data-icon attribute – in combination with the :before and :after pseudo-selectors, to keep our markup minimal and meaningful. Our simple markup looks like this: View Basket Note the multiple class attributes. Next, we’ll import the Pictos font using the @font-face web fonts property in CSS: @font-face { font-family: 'Pictos'; src: url('pictos-web.eot'); src: local('☺'), url('pictos-web.woff') format('woff'), url('pictos-web.ttf') format('truetype'), url('pictos-web.svg#webfontIyfZbseF') format('svg'); } This rather complicated looking set of rules is (at the time of writing) the most bulletproof way of ensuring as many browsers as possible load the font we want. We’ll now use the content property applied to the :before pseudo-class selector to generate our icon. Once again, we’ll use those multiple class attribute values to set common icon styles, then specific styles for .basket. This helps us avoid repeating styles: .icon { font-family: 'Pictos'; font-size: 22px: } .basket:before { content: ""$""; } What does the :before pseudo-class do? It generates the dollar character in a browser, even when it’s not present in the markup. Using the generated content approach means our markup stays simple, but we’ll need a new line of CSS, defining what letter to apply to each class attribute for every icon we add. data-icon is a new alternative approach that uses the HTML5 data- attribute in combination with CSS attribute selectors. This new attribute lets us add our own metadata to elements, as long as its prefixed by data- and doesn’t contain any uppercase letters. In this case, we want to use it to provide the letter value for the icon. Look closely at this markup and you’ll see the data-icon attribute. View Basket We could add others, in fact as many as we like. Favourites History Location Then, we need just one CSS attribute selector to style all our icons in one go: .icon:before { content: attr(data-icon); /* Insert your fancy colours here */ } By placing our custom attribute data-icon in the selector in this way, we can enable CSS to read the value of that attribute and display it before the element (in this case, the anchor tag). It saves writing a lot of CSS rules. I can imagine that some may not like the extra attribute, but it does keep it out of the actual content – generated or not. This could be used for all manner of tasks, including a media player and large simple illustrations. See the demo for live examples. Go ahead and zoom the page, and the icons will be crisp, with the exception of the examples that use -webkit-background-clip: text as mentioned earlier. Finally, it’s worth pointing out that with both generated content and the data-icon method, the letter will be announced to people using screen readers. For example, with the shopping basket icon above, the reader will say “dollar sign view basket”. As accessibility issues go, it’s not exactly the worst, but could be confusing. You would need to decide whether this method is appropriate for the audience. Despite the disadvantages, icon fonts have huge potential.",2011,Jon Hicks,jonhicks,2011-12-12T00:00:00+00:00,https://24ways.org/2011/displaying-icons-with-fonts-and-data-attributes/,code 324,Debugging CSS with the DOM Inspector,"An Inspector Calls The larger your site and your CSS becomes, the more likely that you will run into bizarre, inexplicable problems. Why does that heading have all that extra padding? Why is my text the wrong colour? Why does my navigation have a large moose dressed as Noel Coward on top of all the links? Perhaps you work in a collaborative environment, where developers and other designers are adding code? In which case, the likelihood of CSS strangeness is higher. You need to debug. You need Firefox’s wise-guy know-it-all, the DOM Inspector. The DOM Inspector knows where everything is in your layout, and more importantly, what causes it to look the way it does. So without further ado, load up any css based site in your copy of Firefox (or Flock for that matter), and launch the DOM Inspector from the Tools menu. The inspector uses two main panels – the left to show the DOM tree of the page, and the right to show you detail: The Inspector will look at whatever site is in the front-most window or tab, but you can also use it without another window. Type in a URL at the top (A), press ‘Inspect’ (B) and a third panel appears at the bottom, with the browser view. I find this layout handier than looking at a window behind the DOM Inspector. Step 1 – find your node! Each element on your page – be it a HTML tag or a piece of text, is called a ‘node’ of the DOM tree. These nodes are all listed in the left hand panel, with any ID or CLASS attribute values next to them. When you first look at a page, you won’t see all those yet. Nested HTML elements (such as a link inside a paragraph) have a reveal triangle next to their name, clicking this takes you one level further down. This can be fine for finding the node you want to look at, but there are easier ways. Say you have a complex rounded box technique that involves 6 nested DIVs? You’d soon get tired of clicking all those triangles to find the element you want to inspect. Click the top left icon © – “Find a node to inspect by clicking on it” and then select the area you want to inspect. Boom! All that drilling down the DOM tree has been done for you! Huzzah! If you’re looking for an element that you know has an ID (such as