{"rowid": 101, "title": "Easing The Path from Design to Development", "contents": "As a web developer, I have the pleasure of working with a lot of different designers. There has been a lot of industry discussion of late about designers and developers, focusing on how different we sometimes are and how the interface between our respective phases of a project (that is to say moving from a design phase into production) can sometimes become a battleground.\n\nI don\u2019t believe it has to be a battleground. It\u2019s actually more like being a dance partner \u2013 our steps are different, but as long as we know our own part and have a little knowledge of our partner\u2019s steps, it all goes together to form a cohesive dance. Albeit with less spandex and fewer sequins (although that may depend on the project in question).\n\nAs the process usually flows from design towards development, it\u2019s most important that designers have a little knowledge of how the site is going to be built. At the specialist web development agency I\u2019m part of, we find that designs that have been well considered from a technical perspective help to keep the project on track and on budget.\n\nBased on that experience, I\u2019ve put together my checklist of things that designers should consider before handing their work over to a developer to build.\n\nLayout\n\nOne rookie mistake made by traditionally trained designers transferring to the web is to forget a web browser is not a fixed medium. Unlike designing a magazine layout or a piece of packaging, there are lots of available options to consider. Should the layout be fluid and resize with the window, or should it be set to a fixed width? If it\u2019s fluid, which parts expand and which not? If it\u2019s fixed, should it sit in the middle of the window or to one side?\n\nIf any part of the layout is going to be flexible (get wider and narrower as required), consider how any graphics are affected. Images don\u2019t usually look good if displayed at anything other that their original size, so should they behave? If a column is going to get wider than it\u2019s shown in the Photoshop comp, it may be necessary to provide separate wider versions of any background images.\n\nText size and content volume\n\nA related issue is considering how the layout behaves with both different sizes of text and different volumes of content. Whilst text zooming rather than text resizing is becoming more commonplace as the default behaviour in browsers, it\u2019s still a fundamentally important principal of web design that we are suggesting and not dictating how something should look. Designs must allow for a little give and take in the text size, and how this affects the design needs to be taken into consideration.\n\nKeep in mind that the same font can display differently in different places and platforms. Something as simple as Times will display wider on a Mac than on Windows. However, the main impact of text resizing is the change in how much vertical space copy takes up. This is particularly important where space is limited by the design (making text bigger causes many more problems than making text smaller). Each element from headings to box-outs to navigation items and buttons needs to be able to expand at least vertically, if not horizontally as well. This may require some thought about how elements on the page may wrap onto new lines, as well as again making sure to provide extended versions of any graphical elements.\n\nSimilarly, it\u2019s rare theses days to know exactly what content you\u2019re working with when a site is designed. Many, if not most sites are designed as a series of templates for some kind of content management system, and so designs cannot be tweaked around any specific item of content. Designs must be able to cope with both much greater and much lesser volumes of content that might be thrown in at the lorem ipsum phase.\n\nParticular things to watch out for are things like headings (how do they wrap onto multiple lines) and any user-generated items like usernames. It can be very easy to forget that whilst you might expect something like a username to be 8-12 characters, if the systems powering your site allow for 255 characters they\u2019ll always be someone who\u2019ll go there. Expect them to do so.\n\nAgain, if your site is content managed or not, consider the possibility that the structure might be expanded in the future. Consider how additional items might be added to each level of navigation. Whilst it\u2019s rarely desirable to make significant changes without revisiting the site\u2019s information architecture more thoroughly, it\u2019s an inevitable fact of life that the structure needs a little bit of flexibility to change over time.\n\nInteractions with and without JavaScript\n\nA great number of sites now make good use of JavaScript to streamline the user interface and make everything just that touch more usable. Remember, though, that any developer worth their salt will start by building the interface without JavaScript, get it all working, and then layer that JavaScript on top. This is to allow for users viewing the site without JavaScript available or enabled in their browser.\n\nDesigners need to consider both states of any feature they\u2019re designing \u2013 how it looks and functions with and without JavaScript. If the feature does something fancy with Ajax, consider how the same can be achieved with basic HTML forms, links and intermediary pages. These all need to be designed, because this is how some of your users will interact with the site.\n\nLogged in and logged out states\n\nWhen designing any type of web application or site that has a membership system \u2013 that is to say users can create an account and log into the site \u2013 the design will need to consider how any element is presented in both logged in and logged out states. For some items there\u2019ll be no difference, whereas for others there may be considerable differences.\n\nShould an item be hidden completely not logged out users? Should it look different in some way? Perhaps it should look the same, but prompt the user to log in when they interact with it. If so, what form should that prompt take on and how does the user progress through the authentication process to arrive back at the task they were originally trying to complete?\n\nCouple logged in and logged out states with the possible absence of JavaScript, and every feature needs to be designed in four different states:\n\n\n\tLogged out with JavaScript available\n\tLogged in with JavaScript available\n\tLogged out without JavaScript available\n\tLogged in without JavaScript available\n\n\nFonts\n\nThere are three main causes of war in this world; religions, politics and fonts. I\u2019ve said publicly before that I believe the responsibility for this falls squarely at the feet of Adobe Photoshop. Photoshop, like a mistress at a brothel, parades a vast array of ropey, yet strangely enticing typefaces past the eyes of weak, lily-livered designers, who can\u2019t help but crumble to their curvy charms.\n\nYet, on the web, we have to be a little more restrained in our choice of typefaces. The purest solution is always to make the best use of the available fonts, but this isn\u2019t always the most desirable solution from a design point of view. There are several technical solutions such as techniques that utilise Flash (like sIFR), dynamically generated images and even canvas in newer browsers. Discuss the best approach with your developer, as every different technique has different trade-offs, and this may impact the design in other ways.\n\nMessaging\n\nAny site that has interactive elements, from a simple contact form through to fully featured online software application, involves some kind of user messaging. By this I mean the error messages when something goes wrong and the success and thank-you messages when something goes right. These typically appear as the result of an interaction, so are easy to forget and miss off a Photoshop comp.\n\nFor every form, consider what gets displayed to the user if they make a mistake or miss something out, and also what gets displayed back when the interaction is successful. What do they see and where do the go next?\n\nWith Ajax interactions, the user doesn\u2019t get any visual feedback of the site waiting for a response from the server unless you design it that way. Consider using a \u2018waiting\u2019 or \u2018in progress\u2019 spinner to give the user some visual feedback of any background processes. How should these look? How do they animate?\n\nSimilarly, also consider the big error pages like a 404. With luck, these won\u2019t often be seen, but it\u2019s at the point that they are when careful design matters the most.\n\nForm fields\n\nDepending on the visual style of your site, the look of a browser\u2019s default form fields and buttons can sometimes jar. It\u2019s understandable that many a designer wants to change the way they look. Depending on the browser in question, various things can be done to style form fields and their buttons (although it\u2019s not as flexible as most would like).\n\nA common request is to replace the default buttons with a graphical button. This is usually achievable in most cases, although it\u2019s not easy to get a consistent result across all browsers \u2013 particularly when it comes to vertical positioning and the space surrounding the button. If the layout is very precise, or if space is at a premium, it\u2019s always best to try and live with the browser\u2019s default form controls.\n\nWhichever way you go, it\u2019s important to remember that in general, each form field should have a label, and each form should have a submit button. If you find that your form breaks either of those rules, you should double check.\n\nPractical tips for handing files over\n\nThere are a couple of basic steps that a design can carry out to make sure that the developer has the best chance of implementing the design exactly as envisioned.\n\nIf working with Photoshop of Fireworks or similar comping tool, it helps to group and label layers to make it easy for a developer to see which need to be turned on and off to get to isolate parts of the page and different states of the design. Also, if you don\u2019t work in the same office as your developer (and so they can\u2019t quickly check with you), provide a PDF of each page and state so that your developer can see how each page should look aside from any confusion with quick layers are switched on or off. These also act as a handy quick reference that can be used without firing up Photoshop (which can kill both productivity and your machine).\n\nFinally, provide a colour reference showing the RGB values of all the key colours used throughout the design. Without this, the developer will end up colour-picking from the comps, and could potentially end up with different colours to those you intended. Remember, for a lot of developers, working in a tool like Photoshop is like presenting a designer with an SSH terminal into a web server. It\u2019s unfamiliar ground and easy to get things wrong. Be the expert of your own domain and help your colleagues out when they\u2019re out of their comfort zone. That goes both ways.\n\nIn conclusion\n\nWhen asked the question of how to smooth hand-over between design and development, almost everyone who has experienced this situation could come up with their own list. This one is mine, based on some of the more common experiences we have at edgeofmyseat.com. So in bullet point form, here\u2019s my checklist for handing a design over.\n\n\n\tIs the layout fixed, or fluid?\n\tDoes each element cope with expanding for larger text and more content?\n\tAre all the graphics large enough to cope with an area expanding?\n\tDoes each interactive element have a state for with and without JavaScript?\n\tDoes each element have a state for logged in and logged out users?\n\tHow are any custom fonts being displayed? (and does the developer have the font to use?)\n\tDoes each interactive element have error and success messages designed?\n\tDo all form fields have a label and each form a submit button?\n\tIs your Photoshop comp document well organised?\n\tHave you provided flat PDFs of each state?\n\tHave you provided a colour reference?\n\tAre we having fun yet?", "year": "2008", "author": "Drew McLellan", "author_slug": "drewmclellan", "published": "2008-12-01T00:00:00+00:00", "url": "https://24ways.org/2008/easing-the-path-from-design-to-development/", "topic": "process"} {"rowid": 111, "title": "Geometric Background Patterns", "contents": "When the design is finished and you\u2019re about to start the coding process, you have to prepare your graphics. If you\u2019re working with a pattern background you need to export only the repeating fragment. It can be a bit tricky to isolate a fragment to achieve a seamless pattern background. For geometric patterns there is a method I always follow and that I want to share with you. Take for example a perfect 45\u00b0 diagonal line pattern. \n\n\n\nHow do you define this pattern fragment so it will be rendered seamlessly?\n\n\n\nHere is the method I usually follow to avoid a mismatch. First, zoom in so you see enough detail and you can distinguish the pixels. Select the Rectangular Marquee Selection tool and start your selection at the intersection of 2 different colors of a diagonal line. Hold down the Shift key while dragging so you drag a perfect square.\n\n\n\nRelease the mouse when you reach the exact same intesection (as your starting) point at the top right. \n\n\n\nCopy this fragment (using Copy Merged: Cmd/Ctrl + Shift + C) and paste the fragment in a new layer. Give this layer the name \u2018pattern\u2019. Now hold down the Command Key (Control Key on Windows) and click on the \u2018pattern\u2019 layer in the Layers Palette to select the fragment. Now go to Edit > Define Pattern, enter a name for your pattern and click OK. Test your pattern in a new document. Create a new document of 600 px by 400px, hit Cmd/Ctrl + A and go to Edit > Fill\u2026 and choose your pattern. If the result is OK, you have created a perfect pattern fragment.\n\n\n\nBelow you see this pattern enlarged. The guides show the boundaries of the pattern fragment and the red pixels are the reference points. The red pixels at the top right, bottom right and bottom left should match the red pixel at the top left.\n\n\n\nThis technique should work for every geometric pattern. Some patterns are easier than others, but this, and the Photoshop pattern fill test, has always been my guideline.\n\nOther geometric pattern examples\n\nExample 1\n\nNot all geometric pattern fragments are squares. Some patterns look easy at first sight, because they look very repetitive, but they can be a bit tricky.\n\n\n\nZoomed in pattern fragment with point of reference shown:\n\n\n\nExample 2\n\nSome patterns have a clear repeating point that can guide you, such as the blue small circle of this pattern as you can see from this zoomed in screenshot:\n\n\n\nZoomed in pattern fragment with point of reference shown:\n\n\n\nExample 3\n\nThe different diagonal colors makes a bit more tricky to extract the correct pattern fragment. \n\n\n\nThe orange dot, which is the starting point of the selection is captured a few times inside the fragment selection:", "year": "2008", "author": "Veerle Pieters", "author_slug": "veerlepieters", "published": "2008-12-02T00:00:00+00:00", "url": "https://24ways.org/2008/geometric-background-patterns/", "topic": "design"} {"rowid": 112, "title": "User Styling", "contents": "During the recent US elections, Twitter decided to add an \u2018election bar\u2019 as part of their site design. You could close it if it annoyed you, but the action wasn\u2019t persistent and the bar would always come back like a bad penny. \n\nThe solution to common browsing problems like this is CSS. \u2018User styling\u2019 (or the creepy \u2018skinning\u2019) 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:\n\n\n\tImproving personal readability by changing text size and colour\n\tPersonalising the look of a web app like GMail to look less insipid\n\tRevealing microformats\n\tSport! My dreams of site skinning tennis are not yet fully realised, but it\u2019ll be all the rage by next Christmas, believe me.\n\n\nHopefully you\u2019re now asking \u201cBut how? HOW?!\u201d. The process of creating a site skin is roughly as follows:\n\n\n\tSee something you want to change\n\tFind out what it\u2019s called, and if any rules already apply to it\n\tWrite CSS rule(s) to override and/or enhance it.\n\tApply the rules\n\n\nSo let\u2019s get stuck in\u2026\n\nSee something\n\nLet\u2019s start small with Multimap.com. Look at that big header \u2013 it takes up an awful lot of screen space doesn\u2019t it? \n\n\n\nNo matter, we can fix it.\n\nTools\n\nNow we need to find out where that big assed header is in the DOM, and make overriding CSS rules. The best tool I\u2019ve found yet is the Mac OS X app, CSS Edit. It utilises a slick \u2018override stylesheets\u2019 function and DOM Inspector. Rather than give you all the usual DOM inspection tools, CSS Edit\u2019s is solely concerned with style. Go into \u2018X-Ray\u2019 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.\n\n\n\nHaving said all that, you can achieve all this with free, cross platform tools \u2013 namely Firefox with the Firebug and Stylish extensions. We\u2019ll be using them for these examples, so make sure you have them installed if you want to follow along.\n\n\n\nUsing 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. \n\nChange Something\n\nWhen 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:\n\n\n\nThe \u2018Add Style\u2019 window then pops up, with the @-moz-document query at the top:\n\n@namespace url(http://www.w3.org/1999/xhtml);\n@-moz-document domain(\"multimap.com\") {\n}\n\nAll you need to do is add the CSS to hide the header, in between the curly brackets.\n\n@namespace url(http://www.w3.org/1999/xhtml);\n@-moz-document domain(\"multimap.com\") {\n #header {display: none;} \n}\n\n\n\nA click of the preview button shows us that it\u2019s worked! Now the map appears further up the page. The ethics of hiding adverts is a discussion for another time, but let\u2019s face it, when did you last whoop at the sight of a banner?\n\nMake Something Better\n\nIf we\u2019re 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\u2019s 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 \u201cFind Styles for this Page\u201d. Selecting this with \u201cBBC News\u201d shows that there are plenty of options, ranging from small layout tweaks to redesigns:\n\n\n\nWhat\u2019s 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\u2019ll cover ways of applying site styles to other browsers later.\n\nSpecific Techniques\n\nImportant!\n\nIn the Multimap example there wasn\u2019t a display specified on that element, but it isn\u2019t 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\u2019s no way to avoid this in user styling \u2013 if you\u2019re overriding an existing rule it\u2019s a necessity! Be prepared to be typing !important a lot.\n\nStar Selector\n\nThe 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\u2019ve done!), we can cover all occurrences with just one rule:\n\n* {font-family: \"Helvetica Neue\", Helvetica, sans-serif !important;}\n\nYou can also use it to select \u2018everything within an element\u2019, by placing it after the element name:\n\n#content * {font-family: \"Helvetica Neue\", Helvetica, sans-serif !important;}\n\nSwapping Images\n\nIf you\u2019re changing something a little more complex, such as Google Reader, then at some point you\u2019ll probably want to change an . The technique for replacing an image involves:\n\n\n\tmaking your replacement image the background of the tag\n\tadding padding top and left to the size of you image to push the \u2018top\u2019 image away\n\tmaking the height and width zero.\n\n\n\n\nThe 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:\n\nimg[src=\"/reader/ui/3544433079-tree-view-folder-open.gif\"] {\n\tpadding: 16px 0 0 16px;\n\twidth: 0 !important;\n\theight: 0 !important;\n\tbackground-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYA\nAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAA\nBx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdE\nVYdENyZWF0aW9uIFRpbWUAMjkvNi8wOJJ/BVgAAAG3SURBVDiNpZIhb5RBEIaf\n2W+vpIagIITSBIHBgsGjEYQaFLYShcITDL+ABIPnh4BFN0GQNFA4Cnf3fbszL2L3\njiuEVLDJbCazu8+8Mzsmif9ZBvDy7bvXlni0HRe8eXL/zuPzABng62J5kFKaAQS\nQgJAOgHMB9vDZq+d71689Hcyw9LfAZAYdioE10VSJo6OPL/KNvSuHD+7dhU\n0vHEsDUUWJChIlYJIjFx5BuMB2mJY/DnMoOJl/R147oBUR0QAm8LAGCOEh3IO\nULiAl8jSOy/nPetGsbGRKjktEiBCEHMlQj4loCuu4zCXCi4lUHTNDtGqEiACTqAFSI\nOgAUAKv4bkWVy2g6tAbJtGy0TNugM3HADmlurKH27dVZSecxjboXggiAsMItR\nh99wTILdewYRpXVJWtY85k7fPW8e1GpJFJacgesXs6VYYomz9G2yDhwPB7NEB\nBDAMK7WYJlisYVBCpfaJBeB+eocFyVyAgCaoMCTJSTOOCWSyILrAnaXpSexRsx\nGGAZ0AR+XT+5fjzyfwSpnUB/1w64xizVI/t6q3b+58+vJ96mWtLf9haxNoc8M\nv7N3d+AT4XPcFIxghoAAAAAElFTkSuQmCC) no-repeat !important;\n}\n\nWoah boy! What was all that gubbins in the background-image? It was a Data URI, and you can create these easily with Hixie\u2019s online tool. It\u2019s simply the image translated into text so that it can be embedded in the CSS, cutting down on the number of http requests. It\u2019s also a necessity with Mozilla browsers, as they don\u2019t allow user CSS to reference images stored locally. Converting images to URI\u2019s avoids this, as well as making a style easily portable \u2013 no images folder to pass around. \n\nDon\u2019t 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!\n\nUser styling without Stylish\n\nInstead 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?\n\nOpera & Omniweb: \n\nBoth allow you to specify a custom CSS file as part of the site\u2019s preferences. Opera also allows custom javascript, using the same syntax as Greasemonkey scripts (more on that below)\n\nSafari\n\nThere 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.\n\nWhat now?\n\nHopefully I\u2019ve given you enough information for you to be able start making your own styles. If you want to go straight in and tackle the \u2018Holy Grail\u2019, then off with you to GMail \u2013 I get more requests to theme that than anything else!\n\nIf you\u2019re 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:\n\n\n\nThis 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. \n\nOne final revelation on user styling \u2013 it\u2019s not just for web sites. You can tweak the UI of Firefox itself with the userChrome.css. You\u2019ll 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.", "year": "2008", "author": "Jon Hicks", "author_slug": "jonhicks", "published": "2008-12-03T00:00:00+00:00", "url": "https://24ways.org/2008/user-styling/", "topic": "process"} {"rowid": 104, "title": "Sitewide Search On A Shoe String", "contents": "One of the questions I got a lot when I was building web sites for smaller businesses was if I could create a search engine for their site. Visitors should be able to search only this site and find things without the maintainer having to put \u201crelated articles\u201d or \u201cfeatured content\u201d links on every page by hand. \n\nBack when this was all fields this wasn\u2019t easy as you either had to write your own scraping tool, use ht://dig or a paid service from providers like Yahoo, Altavista or later on Google. In the former case you had to swallow the bitter pill of computing and indexing all your content and storing it in a database for quick access and in the latter it hurt your wallet.\n\nTimes have moved on and nowadays you can have the same functionality for free using Yahoo\u2019s \u201cBuild your own search service\u201d \u2013 BOSS. The cool thing about BOSS is that it allows for a massive amount of hits a day and you can mash up the returned data in any format you want. Another good feature of it is that it comes with JSON-P as an output format which makes it possible to use it without any server-side component!\n\nStarting with a working HTML form\n\nIn order to add a search to your site, you start with a simple HTML form which you can use without JavaScript. Most search engines will allow you to filter results by domain. In this case we will search \u201cbbc.co.uk\u201d. If you use Yahoo as your standard search, this could be: \n\n
\n\t
\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n
\n\nThe Google equivalent is:\n\n
\n\t
\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n
\n\nIn any case make sure to use the ID term for the search term and site for the site, as this is what we are going to use for the script. To make things easier, also have an ID called customsearch on the form.\n\nTo use BOSS, you should get your own developer API for BOSS and replace the one in the demo code. There is click tracking on the search results to see how successful your app is, so you should make it your own.\n\nAdding the BOSS magic\n\nBOSS is a REST API, meaning you can use it in any HTTP request or in a browser by simply adding the right parameters to a URL. Say for example you want to search \u201cbbc.co.uk\u201d for \u201cchristmas\u201d all you need to do is open the following URL:\n\nhttp://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&format=xml&appid=YOUR-APPLICATION-ID\n\nTry it out and click it to see the results in XML. We don\u2019t want XML though, which is why we get rid of the format=xml parameter which gives us the same information in JSON:\n\nhttp://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&appid=YOUR-APPLICATION-ID\n\nJSON makes most sense when you can send the output to a function and immediately use it. For this to happen all you need is to add a callback parameter and the JSON will be wrapped in a function call. Say for example we want to call SITESEARCH.found() when the data was retrieved we can do it this way:\n\nhttp://boss.yahooapis.com/ysearch/web/v1/christmas?sites=bbc.co.uk&callback=SITESEARCH.found&appid=YOUR-APPLICATION-ID\n\nYou can use this immediately in a script node if you want to. The following code would display the total amount of search results for the term christmas on bbc.co.uk as an alert:\n\n\n\n\nHowever, for our example, we need to be a bit more clever with this.\n\nEnhancing the search form\n\n\n\n\nHere\u2019s the script that enhances a search form to show results below it.\n\nSITESEARCH = function(){\n\tvar config = {\n\t\tIDs:{\n\t\t\tsearchForm:'customsearch',\n\t\t\tterm:'term',\n\t\t\tsite:'site'\n\t\t},\n\t\tloading:'Loading results...',\n\t\tnoresults:'No results found.',\n\t\tappID:'YOUR-APP-ID',\n\t\tresults:20\n\t};\n\tvar form;\n\tvar out;\n\tfunction init(){\n\t\tif(config.appID === 'YOUR-APP-ID'){\n\t\t\talert('Please get a real application ID!');\n\t\t} else {\n\t\t\tform = document.getElementById(config.IDs.searchForm);\n\t\t\tif(form){\n\t\t\t\tform.onsubmit = function(){\n\t\t\t\t\tvar site = document.getElementById(config.IDs.site).value;\n\t\t\t\t\tvar term = document.getElementById(config.IDs.term).value;\n\t\t\t\t\tif(typeof site === 'string' && typeof term === 'string'){\n\t\t\t\t\t\tif(typeof out !== 'undefined'){\n\t\t\t\t\t\t\tout.parentNode.removeChild(out);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tout = document.createElement('p');\n\t\t\t\t\t\tout.appendChild(document.createTextNode(config.loading));\n\t\t\t\t\t\tform.appendChild(out);\n\t\t\t\t\t\tvar APIurl = 'http://boss.yahooapis.com/ysearch/web/v1/' + \n\t\t\t\t\t\t\t\t\t\t\t\t\tterm + '?callback=SITESEARCH.found&sites=' + \n\t\t\t\t\t\t\t\t\t\t\t\t\tsite + '&count=' + config.results + \n\t\t\t\t\t\t\t\t\t\t\t\t\t'&appid=' + config.appID;\n\t\t\t\t\t\tvar s = document.createElement('script');\n\t\t\t\t\t\ts.setAttribute('src',APIurl);\n\t\t\t\t\t\ts.setAttribute('type','text/javascript');\n\t\t\t\t\t\tdocument.getElementsByTagName('head')[0].appendChild(s);\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t};\n\tfunction found(o){\n\t\tvar list = document.createElement('ul');\n\t\tvar results = o.ysearchresponse.resultset_web;\n\t\tif(results){\n\t\t\tvar item,link,description;\n\t\t\tfor(var i=0,j=results.length;i\n\t
\n\t\t\n\t\t\n\t\t\n\t\t\n\t
\n\n\n\n\nWhere to go from here\n\nThis is just a very simple example of what you can do with BOSS. You can define languages and regions, retrieve and display images and news and mix the results with other data sources before displaying them. One very cool feature is that by adding a view=keyterms parameter to the URL you can get the keywords of each of the results to drill deeper into the search. An example for this written in PHP is available on the YDN blog. For JavaScript solutions there is a handy wrapper called yboss available to help you go nuts.", "year": "2008", "author": "Christian Heilmann", "author_slug": "chrisheilmann", "published": "2008-12-04T00:00:00+00:00", "url": "https://24ways.org/2008/sitewide-search-on-a-shoestring/", "topic": "code"} {"rowid": 102, "title": "Art Directing with Looking Room", "contents": "Using photographic composition techniques to start to art direct on the template-driven web.\n\nThink back to last night. There you are, settled down in front of the TV, watching your favourite soap opera, with nice hot cup of tea in hand. Did you notice \u2013 whilst engrossed in the latest love-triangle \u2013 that the cameraman has worked very hard to support your eye\u2019s natural movement on-screen? He\u2019s carefully framed individual shots to create balance.\n\nThink back to last week. There you were, sat with your mates watching the big match. Did you notice that the cameraman frames the shot to go with the direction of play? A player moving right will always be framed so that he is on the far left, with plenty of \u2018room\u2019 to run into.\n\nBoth of these cameramen use a technique called Looking Room, sometimes called Lead Room. Looking Room is the space between the subject (be it a football, or a face), and the edge of the screen. Specifically, Looking Room is the negative space on the side the subject is looking or moving. The great thing is, it\u2019s not just limited to photography, film or television; we can use it in web design too.\n\nBasic Framing\n\nBefore we get into Looking Room, and how it applies to web, we need to have a look at some basics of photographic composition.\n\nMany web sites use imagery, or photographs, to enhance the content. But even with professionally shot photographs, without a basic understanding of framing or composition, you can damage how the image is perceived. \n\nA simple, easy way to make photographs more interesting is to fill the frame. \n\nTake this rather mundane photograph of a horse:\n\n\n\nA typical point and click affair. But, we can work with this.\n\nBy closely cropping, and filling the frame, we can instantly change the mood of the shot.\n\n\n\nI\u2019ve also added Looking Room on the right of the horse. This is space that the horse would be walking into. It gives the photograph movement.\n\nSubject, Space, and Movement\n\nGenerally speaking, a portrait photograph will have a subject and space around them. Visual interest in portrait photography can come from movement; how the eye moves around the shot. To get the eye moving, the photographer modifies the space around the subject.\n\nLook at this portrait:\n\n\n\nThe photography has framed the subject on the right, allowing for whitespace, or Looking Room, in the direction the subject is looking. The framing of the subject (1), with the space to the left (2) \u2013 the Looking Room \u2013 creates movement, shown by the arrow (3).\n\n\n\nNote the subject is not framed centrally (shown by the lighter dotted line).\n\nIf the photographer had framed the subject with equal space either side, the resulting composition is static, like our horse.\n\n\n\nIf the photographer framed the subject way over on the left, as she is looking that way, the resulting whitespace on the right leads a very uncomfortable composition.\n\n\n\nThe root of this discomfort is what the framing is telling our eye to do. The subject, looking to the left, suggests to us that we should do the same. However, the Looking Room on the right is telling our eye to occupy this space. The result is a confusing back and forth.\n\nHow Looking Room applies to the web\n\nWe can apply the same theory to laying out a web page or application. Taking the three same elements \u2013 Subject, Space, and resulting Movement \u2013 we can guide a user\u2019s eye to the elements we need to. As designers, or content editors, framing photographs correctly can have a subtle but important effect on how a page is visually scanned. Take this example:\n\n\n\nThe BBC homepage uses great photography as a way of promoting content. Here, they have cropped the main photograph to guide the user\u2019s eye into the content. \n\nBy applying the same theory, the designer or content editor has applied considerable Looking Room (2) to the photograph to create balance with the overall page design, but also to create movement of the user\u2019s eye toward the content (1)\n\n\n\nIf the image was flipped horizontally. The Looking Room is now on the right. The subject of the photograph is looking off the page, drawing the user\u2019s eye away from the content. Once again, this results in a confusing back and forth as your eye fights its way over to the left of the page.\n\n\n\nA little bit of Art Direction\n\nArt Direction can be described as the act or process of managing the visual presentation of content. Art Direction is difficult to do on the web, because content and presentation are, more often than not, separated. But where there are images, and when we know the templates that those images will populate, we can go a little way to bridging the gap between content and presentation.\n\nBy understanding the value of framing and Looking Room, and the fact that it extends beyond just a good looking photograph, we can start to see photography playing more of an integral role in the communication of content. \n\nWe won\u2019t just be populating templates. We\u2019ll be art directing.\n\nPhoto credits: \n\n\n\tPortrait by Carsten Tolkmit\n\tHorse by Mike Pedroncelli", "year": "2008", "author": "Mark Boulton", "author_slug": "markboulton", "published": "2008-12-05T00:00:00+00:00", "url": "https://24ways.org/2008/art-directing-with-looking-room/", "topic": "design"} {"rowid": 107, "title": "Using Google App Engine as Your Own Content Delivery Network", "contents": "Do you remember, years ago, when hosting was expensive, domain names were the province of the rich, and you hosted your web pages on Geocities? It seems odd to me now that there was a time when each and every geek didn\u2019t have his own top-level domain and super hosting setup. But as the parts became more and more affordable a man could become an outcast if he didn\u2019t have his own slightly surreal-sounding TLD.\n\nAnd so it will be in the future when people realise with surprise there was a time before affordable content delivery networks.\n\nA content delivery network, or CDN, is a system of servers spread around the world, serving files from the nearest physical location. Instead of waiting for a file to find its way from a server farm in Silicon Valley 8,000 kilometres away, I can receive it from London, Dublin, or Paris, cutting down the time I wait. The big names \u2014 Google, Yahoo, Amazon, et al \u2014 use CDNs for their sites, but they\u2019ve always been far too expensive for us mere mortals. Until now.\n\nThere\u2019s a service out there ready for you to use as your very own CDN. You have the company\u2019s blessing, you won\u2019t need to write a line of code, and \u2014 best of all \u2014 it\u2019s free. The name? Google App Engine.\n\nIn this article you\u2019ll find out how to set up a CDN on Google App Engine. You\u2019ll get the development software running on your own computer, tell App Engine what files to serve, upload them to a web site, and give everyone round the world access to them.\n\nCreating your first Google App Engine project\n\nBefore we do anything else, you\u2019ll need to download the Google App Engine software development kit (SDK). You\u2019ll need Python 2.5 too \u2014 you won\u2019t be writing any Python code but the App Engine SDK will need it to run on your computer. If you don\u2019t have Python, App Engine will install it for you (if you use Mac OS X 10.5 or a Linux-based OS you\u2019ll have Python; if you use Windows you won\u2019t).\n\nDone that? Excellent, because that\u2019s the hardest step. The rest is plain sailing.\n\nYou\u2019ll need to choose a unique \u2018application id\u2019 \u2014 nothing more than a name \u2014 for your project. Make sure it consists only of lowercase letters and numbers. For this article I\u2019ll use 24ways2008, but you can choose anything you like.\n\nOn your computer, create a folder named after your application id. This folder can be anywhere you want: your desktop, your documents folder, or wherever you usually keep your web files. Within your new folder, create a folder called assets, and within that folder create three folders called images, css, and javascript. These three folders are the ones you\u2019ll fill with files and serve from your content delivery network. You can have other folders too, if you like.\n\nThat will leave you with a folder structure like this:\n\n24ways2008/\n\t\tassets/\n\t\t\tcss/\n\t\t\timages/\n\t\t\tjavascript/\n\nNow you need to put a few files in these folders, so we can later see our CDN in action. You can put anything you want in these folders, but for this example we\u2019ll include an HTML file, a style sheet, an image, and a Javascript library.\n\nIn the top-level folder (the one I\u2019ve called 24ways2008), create a file called index.html. Fill this with any content you want. In the assets/css folder, create a file named core.css and throw in a couple of CSS rules for good measure. In the assets/images directory save any image that takes your fancy \u2014 I\u2019ve used the silver badge from the App Engine download page. Finally, to fill the JavaScript folder, add in this jQuery library file. If you\u2019ve got the time and the inclination, you can build a page that uses all these elements.\n\nSo now we should have a set of files and folders that look something like this:\n\n24ways2008/\n\t\tassets/\n\t\t\t\tindex.html\n\t\t\t\tcss/\n\t\t\t\t\t\tcore.css\n\t\t\t\timages/\n\t\t\t\t\t\tappengine-silver-120x30.gif\n\t\t\t\tjavascript/\n\t\t\t\t\t\tjquery-1.2.6.min.js\n\nWhich leaves us with one last file to create. This is the important one: it tells App Engine what to do with your files. It\u2019s named app.yaml, it sits at the top-level (inside the folder I\u2019ve named 24ways2008), and it needs to include these lines:\n\napplication: 24ways2008\nversion: 1\nruntime: python\napi_version: 1\n\nhandlers:\n- url: /\n\tstatic_files: assets/index.html\n\tupload: assets/index.html\n\n- url: /\n\tstatic_dir: assets\n\nYou need to make sure you change 24ways2008 on the first line to whatever you chose as your application id, but otherwise the content of your app.yaml file should be identical. And with that, you\u2019ve created your first App Engine project. If you want it, you can download a zip file containing my project.\n\nTesting your project\n\nAs it stands, your project is ready to be uploaded to App Engine. But we couldn\u2019t call ourselves professionals if we didn\u2019t test it, could we? So, let\u2019s put that downloaded SDK to good use and run the project from your own computer.\n\nOne of the files you\u2019ll find App Engine installed is named dev_appserver.py, a Python script used to simulate App Engine on your computer. You\u2019ll find lots of information on how to do this in the documentation on the development web server, but it boils down to running the script like so (the space and the dot at the end are important):\n\ndev_appserver.py .\n\nYou\u2019ll need to run this from the command-line: Mac users can run the Terminal application, Linux users can run their favourite shell, and Windows users will need to run it via the Command Prompt (open the Start menu, choose \u2018Run\u2026\u2019, type \u2018cmd\u2018, and click \u2018OK\u2019). Before you run the script you\u2019ll need to make sure you\u2019re in the project folder \u2014 in my case, as I saved it to my desktop I can go there by typing \n\ncd ~/Desktop/24ways2008\n\nin my Mac\u2019s Terminal app; if you\u2019re using Windows you can type \n\ncd \"C:\\Documents and Settings\\username\\Desktop\\24ways2008\"\n\nIf that\u2019s successful, you\u2019ll see a few lines of output, the last looking something like this:\n\nINFO 2008-11-22 14:35:00,830 dev_appserver_main.py] Running application 24ways2008 on port 8080: http://localhost:8080\n\nNow you can power up your favourite browser, point it to http://localhost:8080/, and you\u2019ll see the page you saved as index.html. You\u2019ll also find your CSS file at http://localhost:8080/css/core.css. In fact, anything you put inside the assets folder in the project will be accessible from this domain. You\u2019re running our own App Engine web server!\n\nNote that no-one else will be able to see your files: localhost is a special domain that you can only see from your computer \u2014 and once you stop the development server (by pressing Control\u2013C) you\u2019ll not be able to see the files in your browser until you start it again.\n\nYou might notice a new file has turned up in your project: index.yaml. App Engine creates this file when you run the development server, and it\u2019s for internal App Engine use only. If you delete it there are no ill effects, but it will reappear when you next run the development server. If you\u2019re using version control (e.g. Subversion) there\u2019s no need to keep a copy in your repository.\n\nSo you\u2019ve tested your project and you\u2019ve seen it working on your own machine; now all you need to do is upload your project and the world will be able to see your files too.\n\nUploading your project\n\nIf you don\u2019t have a Google account, create one and then sign in to App Engine. Tell Google about your new project by clicking on the \u2018Create an Application\u2019 button. Enter your application id, give the application a name, and agree to the terms and conditions. That\u2019s it. All we need do now is upload the files.\n\nOpen your Mac OS X Terminal, Windows Command Prompt, or Linux shell window again, move to the project folder, and type (again, the space and the dot at the end are important):\n\nappcfg.py update .\n\nEnter your email address and password when prompted, and let App Engine do it\u2019s thing. It\u2019ll take no more than a few seconds, but in that time App Engine will have done the equivalent of logging in to an FTP server and copying files across. It\u2019s fairly understated, but you now have your own project up and running. You can see mine at http://24ways2008.appspot.com/, and everyone can see yours at http://your-application-id.appspot.com/. Your files are being served up over Google\u2019s content delivery network, at no cost to you!\n\nBenefits of using Google App Engine\n\nThe benefits of App Engine as a CDN are obvious: your own server doesn\u2019t suck up the bandwidth, while your visitors will appreciate a faster site. But there are also less obvious benefits.\n\nFirst, once you\u2019ve set up your site, updating it is an absolute breeze. Each time you update a file (or a batch of files) you need only run appcfg.py to see the changes appear on your site. To paraphrase Joel Spolsky, a good web site must be able to be updated in a single step. Many designers and developers can\u2019t make that claim, but with App Engine, you can.\n\nApp Engine also allows multiple people to work on one application. If you want a friend to be able to upload files to your site you can let him do so without giving him usernames and passwords \u2014 all he needs is his own Google account. App Engine also gives you a log of all actions taken by collaborators, so you can see who\u2019s made updates, and when.\n\nAnother bonus is the simple version control App Engine offers. Do you remember the file named app.yaml you created a while back? The second line looked like this:\n\nversion: 1\n\nIf you change the version number to 2 (or 3, or 4, etc), App Engine will keep a copy of the last version you uploaded. If anything goes wrong with your latest version, you can tell App Engine to revert back to that last saved version. It\u2019s no proper version control system, but it could get you out of a sticky situation.\n\nOne last thing to note: if you\u2019re not happy using your-application-id.appspot.com as your domain, App Engine will quite happily use any domain you own.\n\nThe weak points of Google App Engine\n\nIn the right circumstances, App Engine can be a real boon. I run my own site using the method I\u2019ve discussed above, and I\u2019m very happy with it. But App Engine does have its disadvantages, most notably those discussed by Aral Balkan in his post \u2018Why Google App Engine is broken and what Google must do to fix it\u2018.\n\nAral found the biggest problems while using App Engine as a web application platform; I wouldn\u2019t recommend using it as such either (at least for now) but for our purposes as a CDN for static files, it\u2019s much more worthy. Still, App Engine has two shortcomings you should be aware of.\n\nThe first is that you can\u2019t host a file larger than one megabyte. If you want to use App Engine to host that 4.3MB download for your latest-and-greatest desktop software, you\u2019re out of luck. The only solution is to stick to smaller files.\n\nThe second problem is the quota system. Google\u2019s own documentation says you\u2019re allowed 650,000 requests a day and 10,000 megabytes of bandwidth in and out (20,000 megabytes in total), which should be plenty for most sites. But people have seen sites shut down temporarily for breaching quotas \u2014 in some cases after inexplicable jumps in Google\u2019s server CPU usage. Aral, who\u2019s seen it happen to his own sites, seemed genuinely frustrated by this, and if you measure your hits in the hundreds of thousands and don\u2019t want to worry about uptime, App Engine isn\u2019t for you.\n\nThat said, for most of us, App Engine offers a fantastic resource: the ability to host files on Google\u2019s own content delivery network, at no charge.\n\nConclusion\n\nIf you\u2019ve come this far, you\u2019ve seen how to create a Google App Engine project and host your own files on Google\u2019s CDN. You\u2019ve seen the great advantages App Engine offers \u2014 an excellent content delivery network, the ability to update your site with a single command, multiple authors, simple version control, and the use of your own domain \u2014 and you\u2019ve come across some of its weaknesses \u2014 most importantly the limit on file sizes and the quota system. All that\u2019s left to do is upload those applications \u2014 but not before you\u2019ve finished your Christmas shopping.", "year": "2008", "author": "Matt Riggott", "author_slug": "mattriggott", "published": "2008-12-06T00:00:00+00:00", "url": "https://24ways.org/2008/using-google-app-engine-as-your-own-cdn/", "topic": "process"} {"rowid": 114, "title": "How To Create Rockband'ism", "contents": "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\u2019t just want a shopping experience \u2013 we want an engagement with a company we can relate to.\n\nLet me get back to \u201cfeeling cool\u201d \u2013 if we want to feel cool, we might get the companies we buy from to support that. That\u2019s why I am on a mission to make companies into rockbands.\n\nNow when I say rockbands \u2013 I don\u2019t 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 \u201crockband\u2019ism\u201d. This word is the definition of a childhood dream version of being in a rockband \u2013 the feeling of being more respected and loved and cool, than a cockroach or a suit on the floor of a company.\n\nRockband\u2019ism\n\nRockband\u2019ism is what we aspire to, to feel cool and happy.\n\nSo 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.\n\nI have listed a couple of things you could do today to become a rockband, as a person or as a company.\n\n1 \u2013 Give your support to companies that make a difference to their surroundings \u2013 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).\n\n2 \u2013 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 \u2013 this can also be implemented for business.\n\n3 \u2013 WWRD? \u2013 \u201cwhat would a rockband do\u201d? or if you are into Kenny Rogers \u2013 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.\n\n4 \u2013 Start leading instead of managing \u2013 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.\n\n5 \u2013 Respect and confide in, that people are the best at what they do. If they aren\u2019t, they won\u2019t be around for long. If they are and you keep on buggin\u2019 them, they won\u2019t be around for long either.\n\n6 \u2013 Don\u2019t be arrogant \u2013 Because audiences can\u2019t stand it \u2013 talk to people as a person not as a company.\n\n7 \u2013 Focus on your return on involvement \u2013 know that you get a return on, what you involve yourself in. No matter if it\u2019s bingo, communities, talks, ornithology or un-conferences.\n\n8 \u2013 Find out where you can make a difference and do it. Don\u2019t leave it up to everybody else to save the world.\n\n9 \u2013 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.\n\n10 \u2013 Last but not least \u2013 if you\u2019re not happy \u2013 do something else, become another type of rockband, maybe a soloist of a sort, or an orchestra.\n\nNo more business as usual\n\nThis really isn\u2019t 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.\n\nThis 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.\n\nMay 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.", "year": "2008", "author": "Henriette Weber", "author_slug": "henrietteweber", "published": "2008-12-07T00:00:00+00:00", "url": "https://24ways.org/2008/how-to-create-rockbandism/", "topic": "business"} {"rowid": 116, "title": "The IE6 Equation", "contents": "It is the destiny of one browser to serve as the nemesis of web developers everywhere. At the birth of the Web Standards movement, that role was played by Netscape Navigator 4; an outdated browser that refused to die. Its tenacious existence hampered the adoption of modern standards. Today that role is played by Internet Explorer 6.\n\nThere\u2019s a sensation that I\u2019m sure you\u2019re familiar with. It\u2019s a horrible mixture of dread and nervousness. It\u2019s the feeling you get when\u2014after working on a design for a while in a standards-compliant browser like Firefox, Safari or Opera\u2014you decide that you can no longer put off the inevitable moment when you must check the site in IE6. Fingers are crossed, prayers are muttered, but alas, to no avail. The nemesis browser invariably screws something up.\n\nWhat do you do next? If the differences in IE6 are minor, you could just leave it be. After all, websites don\u2019t need to look exactly the same in all browsers. But if there are major layout issues and a significant portion of your audience is still using IE6, you\u2019ll probably need to roll up your sleeves and start fixing the problems.\n\nA common approach is to quarantine IE6-specific CSS in a separate stylesheet. This stylesheet can then be referenced from the HTML document using conditional comments like this:\n\n\n\nThat stylesheet will only be served up to Internet Explorer where the version number is less than 7.\n\nYou can put anything inside a conditional comment. You could put a script element in there. So as well as serving up browser-specific CSS, it\u2019s possible to serve up browser-specific JavaScript.\n\nA few years back, before Microsoft released Internet Explorer 7, JavaScript genius Dean Edwards wrote a script called IE7. This amazing piece of code uses JavaScript to make Internet Explorer 5 and 6 behave like a standards-compliant browser. Dean used JavaScript to bootstrap IE\u2019s CSS support.\n\nBecause the script is specifically targeted at Internet Explorer, there\u2019s no point in serving it up to other browsers. Conditional comments to the rescue:\n\n\n\nStandards-compliant browsers won\u2019t fetch the script. Users of IE6, on the hand, will pay a kind of bad browser tax by having to download the JavaScript file.\n\nSo when should you develop an IE6-specific stylesheet and when should you just use Dean\u2019s JavaScript code? This is the question that myself and my co-worker Natalie Downe set out to answer one morning at Clearleft. We realised that in order to answer that question you need to first answer two other questions, how much time does it take to develop for IE6? and how much of your audience is using IE6?\n\nLet\u2019s say that t represents the total development time. Let t6 represent the portion of that time you spend developing for IE6. If your total audience is a, then a6 is the portion of your audience using IE6. With some algebraic help from our mathematically minded co-worker Cennydd Bowles, Natalie and I came up with the following equation to calculate the percentage likelihood that you should be using Dean\u2019s IE7 script:\n\n\n\np = 50 [ log ( at6 / ta6 ) + 1 ]\n\nTry plugging in your own numbers. If you spend a lot of time developing for IE6 and only a small portion of your audience is using that browser, you\u2019ll get a very high number out of the equation; you should probably use the IE7 script. But if you only spend a little time developing for IE6 and a significant portion of you audience are still using that browser, you\u2019ll get a very small value for p; you might as well write an IE6-specific stylesheet.\n\nOf course this equation is somewhat disingenuous. While it\u2019s entirely possible to research the percentage of your audience still using IE6, it\u2019s not so easy to figure out how much of your development time will be spent developing for that one browser. You can\u2019t really know until you\u2019ve already done the development, by which time the equation is irrelevant.\n\nInstead of using the equation, you could try imposing a limit on how long you will spend developing for IE6. Get your site working in standards-compliant browsers first, then give yourself a time limit to get it working in IE6. If you can\u2019t solve all the issues in that time limit, switch over to using Dean\u2019s script. You could even make the time limit directly proportional to the percentage of your audience using IE6. If 20% of your audience is still using IE6 and you\u2019ve just spent five days getting the site working in standards-compliant browsers, give yourself one day to get it working in IE6. But if 50% of your audience is still using IE6, be prepared to spend 2.5 days wrestling with your nemesis.\n\nAll of these different methods for dealing with IE6 demonstrate that there\u2019s no one single answer that works for everyone. They also highlight a problem with the current debate around dealing with IE6. There\u2019s no shortage of blog posts, articles and even entire websites discussing when to drop support for IE6. But very few of them take the time to define what they mean by \u201csupport.\u201d This isn\u2019t a binary issue. There is no Boolean answer. Instead, there\u2019s a sliding scale of support:\n\n\n\tBlock IE6 users from your site.\n\tDevelop with web standards and don\u2019t spend any development time testing in IE6.\n\tUse the Dean Edwards IE7 script to bootstrap CSS support in IE6.\n\tWrite an IE6 stylesheet to address layout issues.\n\tMake your site look exactly the same in IE6 as in any other browser.\n\n\nEach end of that scale is extreme. I don\u2019t think that anybody should be actively blocking any browser but neither do I think that users of an outdated browser should get exactly the same experience as users of a more modern browser. The real meanings of \u201csupporting\u201d or \u201cnot supporting\u201d IE6 lie somewhere in-between those extremes.\n\nJust as I think that semantics are important in markup, they are equally important in our discussion of web development. So let\u2019s try to come up with some better terms than using the catch-all verb \u201csupport.\u201d If you say in your client contract that you \u201csupport\u201d IE6, define exactly what that means. If you find yourself in a discussion about \u201cdropping support\u201d for IE6, take the time to explain what you think that entails.\n\nThe web developers at Yahoo! are on the right track with their concept of graded browser support. I\u2019m interested in hearing more ideas of how to frame this discussion. If we can all agree to use clear and precise language, we stand a better chance of defeating our nemesis.", "year": "2008", "author": "Jeremy Keith", "author_slug": "jeremykeith", "published": "2008-12-08T00:00:00+00:00", "url": "https://24ways.org/2008/the-ie6-equation/", "topic": "code"} {"rowid": 115, "title": "Charm Clients, Win Pitches", "contents": "Over the years I have picked up a number of sales techniques that have lead to us doing pretty well in the pitches we go for. Of course, up until now, these top secret practices have remained firmly locked in the company vault but now I am going to share them with you. They are cunningly hidden within the following paragraphs so I\u2019m afraid you\u2019re going to have to read the whole thing.\n\nOk, so where to start? I guess a good place would be getting invited to pitch for work in the first place.\n\nShameless self promotion\n\nWhat not to do\n\nYou\u2019re as keen as mustard to \u2018sell\u2019 what you do, but you have no idea as to the right approach. From personal experience (sometimes bitter!), the following methods are as useful as the proverbial chocolate teapot:\n\n\n\tCold calling\n\tAdvertising\n\tBidding websites\n\tSales people\n\tNetworking events\n\n\nOk, I\u2019m exaggerating; sometimes these things work. For example, cold calling can work if you have a story \u2013 a reason to call and introduce yourself other than \u201cwe do web design and you have a website\u201d. \u201cWe do web design and we\u2019ve just moved in next door to you\u201d would be fine. \n\nAdvertising can work if your offering is highly specialist. However, paying oodles of dollars a day to Google Ads to appear under the search term \u2018web design\u2019 is probably not the best use of your budget. \n\nSpecialising is, in fact, probably a good way to go. Though it can feel counter intuitive in that you are not spreading yourself as widely as you might, you will eventually become an expert and therefore gain a reputation in your field. Specialism doesn\u2019t necessarily have to be in a particular skillset or technology, it could just as easily be in a particular supply chain or across a market.\n\nTarget audience\n\n\u2018Who to target?\u2019 is the next question. If you\u2019re starting out then do tap-up your family and friends. Anything that comes your way from them will almost certainly come with a strong recommendation. Also, there\u2019s nothing wrong with calling clients you had dealings with in previous employment (though beware of any contractual terms that may prevent this). You are informing your previous clients that your situation has changed; leave it up to them to make any move towards working with you. After all, you\u2019re simply asking to be included on the list of agencies invited to tender for any new work.\n\nLook to target clients similar to those you have worked with previously. Again, you have a story \u2013 hopefully a good one!\n\nSo how do you reach these people?\n\n\n\tMailing lists\n\tForums\n\tWriting articles\n\tConferences / Meetups\n\tSpeaking opportunities\n\tSharing Expertise\n\n\nIn essence: blog, chat, talk, enthuse, show off (a little)\u2026 share.\n\nThere are many ways you can do this. There\u2019s the traditional portfolio, almost obligatory blog (regularly updated of course), podcast, \u2018giveaways\u2019 like Wordpress templates, CSS galleries and testimonials. Testimonials are your greatest friend. Always ask clients for quotes (write them and ask for their permission to use) and even better, film them talking about how great you are.\n\nFinally, social networking sites can offer a way to reach your target audiences. You do have to be careful here though. You are looking to build a reputation by contributing value. Do not self promote or spam!\n\nWriting proposals\n\nIs it worth it?\n\nOk, so you have been invited to respond to a tender or brief in the form of a proposal. Good proposals take time to put together so you need to be sure that you are not wasting your time. There are two fundamental questions that you need to ask prior to getting started on your proposal:\n\n\n\tCan I deliver within the client\u2019s timescales?\n\tDoes the client\u2019s budget match my price?\n\n\nThe timescales that clients set are often plucked from the air and a little explanation about how long projects usually take can be enough to change expectations with regard to delivery. However, if a deadline is set in stone ask yourself if you can realistically meet it. Agreeing to a deadline that you know you cannot meet just to win a project is a recipe for an unhappy client, no chance of repeat business and no chance of any recommendations to other potential clients.\n\nPrice is another thing altogether. So why do we need to know?\n\nThe first reason, and most honest reason, is that we don\u2019t want to do a lot of unpaid pitch work when there is no chance that our price will be accepted. Who would? But this goes both ways \u2013 the client\u2019s time is also being wasted. It may only be the time to read the proposal and reject it, but what if all the bids are too expensive? Then the client needs to go through the whole process again.\n\nThe second reason why we need to know budgets relates to what we would like to include in a proposal over what we need to include. For example, take usability testing. We always highly recommend that a client pays for at least one round of usability testing because it will definitely improve their new site \u2013 no question. But, not doing it doesn\u2019t mean they\u2019ll end up with an unusable turkey. It\u2019s just more likely that any usability issues will crop up after launch.\n\nI have found that the best way to discover a budget is to simply provide a ballpark total, usually accompanied by a list of \u2018likely tasks for this type of project\u2019, in an initial email or telephone response. Expect a lot of people to dismiss you out of hand. This is good. Don\u2019t be tempted to \u2018just go for it\u2019 anyway because you like the client or work is short \u2013 you will regret it.\n\nOthers will say that the ballpark is ok. This is not as good as getting into a proper discussion about what priorities they might have but it does mean that you are not wasting your time and you do have a chance of winning the work. The only real risk with this approach is that you misinterpret the requirements and produce an inaccurate ballpark.\n\nFinally, there is a less confrontational approach that I sometimes use that involves modular pricing. We break down our pricing into quite detailed tasks for all proposals but when I really do not have a clue about a client\u2019s budget, I will often separate pricing into \u2018core\u2019 items and \u2018optional\u2019 items. This has proved to be a very effective method of presenting price.\n\nWhat to include\n\nSo, what should go into a proposal? It does depend on the size of the piece of work. If it\u2019s a quick update for an existing client then they don\u2019t want to read through all your blurb about why they should choose to work with you \u2013 a simple email will suffice.\n\nBut, for a potential new client I would look to include the following:\n\n\n\tYour suitability\n\tSummary of tasks\n\tTimescales\n\tProject management methodology\n\tPricing\n\tTesting methodology\n\tHosting options\n\tTechnologies\n\tImagery\n\tReferences\n\tFinancial information\n\tBiographies\n\n\nHowever, probably the most important aspect of any proposal is that you respond fully to the brief. In other words, don\u2019t ignore the bits that either don\u2019t make sense to you or you think irrelevant. If something is questionable, cover it and explain why you don\u2019t think it is something that warrants inclusion in the project.\n\nShould you provide speculative designs? If the brief doesn\u2019t ask for any, then certainly not. If it does, then speak to the client about why you don\u2019t like to do speculative designs. Explain that any designs included as part of a proposal are created to impress the client and not the website\u2019s target audience. Producing good web design is a partnership between client and agency. This can often impress and promote you as a professional. However, if they insist then you need to make a decision because not delivering any mock-ups will mean that all your other work will be a waste of time.\n\nWalking away\n\nAs I have already mentioned, all of this takes a lot of work. So, when should you be prepared to walk away from a potential job? I have already covered unrealistic deadlines and insufficient budget but there are a couple of other reasons. Firstly, would this new client damage your reputation, particularly within current sectors you are working in? Secondly, can you work with this client? A difficult client will almost certainly lead to a loss-making project.\n\nPerfect pitch\n\nRequirements\n\nIf the original brief didn\u2019t spell out what is expected of you at a presentation then make sure you ask beforehand. The critical element is how much time you have. It seems that panels are providing less and less time these days.\n\nThe usual formula is that you get an hour; half of which should be a presentation of your ideas followed by 30 minutes of questions. This isn\u2019t that much time, particularly for a big project that covers all aspect of web design and production. Don\u2019t be afraid to ask for more time, though it is very rare that you will be granted any.\n\nAsk if there any areas that a) they particularly want you to cover and b) if there are any areas of your proposal that were weak.\n\nAsk who will be attending. The main reason for this is to see if the decision maker(s) will be present but it\u2019s also good to know if you\u2019re presenting to 3 or 30 people.\n\nWho should be there\n\nGenerally speaking, I think two is the ideal number. Though I have done many presentations on my own, I always feel having two people to bounce ideas around with and have a bit of banter with, works well. You are not only trying to sell your ideas and expertise but also yourselves. One of the main things in the panels minds will be \u2013 \u201ccan I work with these people?\u201d\n\nHaving more than two people at a presentation often looks like you\u2019re wheeling people out just to demonstrate that they exist.\n\nWhat makes a client want to hire you?\n\nIn a nutshell: Confidence, Personality, Enthusiasm.\n\nYou can impart confidence by being well prepared and professional, providing examples and demonstrations and talking about your processes. You may find project management boring but pretty much every potential client will want to feel reassured that you manage your projects effectively.\n\nAs well as demonstrating that you know what you\u2019re talking about, it is important to encourage, and be part of, discussion about the project. Be prepared to suggest and challenge and be willing to say \u201cI don\u2019t know\u201d.\n\nAlso, no-one likes a show-off so don\u2019t over promote yourself; encourage them to contact your existing clients.\n\nWhat makes a client like you?\n\nEngaging with a potential client is tricky and it\u2019s probably the area where you need to be most on your toes and try to gauge the reaction of the client. We recommend the following:\n\n\n\tEncourage questions throughout\n\tAsk if you make sense \u2013 which encourages questions if you\u2019re not getting any\n\tHumour \u2013 though don\u2019t keep trying to be funny if you\u2019re not getting any laughs!\n\tBe willing to go off track\n\tRead your audience\n\tEmpathise with the process \u2013 chances are, most of the people in front of you would rather be doing something else\n\tThink about what you wear \u2013 this sounds daft but do you want to be seen as either the \u2018stiff in the suit\u2019 or the \u2018scruffy art student\u2019? Chances are neither character would get hired.\n\n\nDifferentiation\n\nSometimes, especially if you think you are an outsider, it\u2019s worth taking a few risks. I remember my colleague Paul starting off a presentation once with the line (backed up on screen) \u2013 \u201cHeadscape is not a usability consultancy\u201d. This was in response to the clients request to engage a usability consultancy. The thrust of Paul\u2019s argument was that we are a lot more than that.\n\nThis really worked. We were the outside choice but they ended up hiring us. Basically, this differentiated us from the crowd. It showed that we are prepared to take risks and think, dare I say it, outside of the box.\n\nDealing with difficult characters \n\nHow you react to tricky questioning is likely to be what determines whether you have a good or bad presentation. Here are a few of those characters that so often turn up in panels:\n\nThe techie \u2013 this is likely to be the situation where you need to say \u201cI don\u2019t know\u201d. Don\u2019t bluff as you are likely to dig yourself a great big embarrassment-filled hole. Promise to follow up with more information and make sure that you do so as quickly as possible after the pitch. \n\nThe \u2018hard man\u2019 MD \u2013 this the guy who thinks it is his duty to throw \u2018curve ball\u2019 questions to see how you react. Focus on your track record (big name clients will impress this guy) and emphasise your processes.\n\nThe \u2018no clue\u2019 client \u2013 you need to take control and be the expert though you do need to explain the reasoning behind any suggestions you make. This person will be judging you on how much you are prepared to help them deliver the project.\n\nThe price negotiator \u2013 be prepared to discuss price but do not reduce your rate or the effort associated with your proposal. Fall back on modular pricing and try to reduce scope to come within budget. You may wish to offer a one-off discount to win a new piece of work but don\u2019t get into detail at the pitch.\n\nDon\u2019t panic\u2026\n\nIf you go into a presentation thinking \u2018we must win this\u2019 then, chances are, you won\u2019t. Relax and be yourself. If you\u2019re not hitting it off with the panel then so be it. You have to remember that quite often you will be making up the numbers in a tendering process. This is massively frustrating but, unfortunately, part of it. If it\u2019s not going well, concentrate on what you are offering and try to demonstrate your professionalism rather than your personality. Finally, be on your toes, watch people\u2019s reactions and pay attention to what they say and try to react accordingly.\n\nSo where are the secret techniques I hear you ask? Well, using the words \u2018secret\u2019 and \u2018technique\u2019 was probably a bit naughty. Most of this stuff is about being keen, using your brain and believing in yourself and what you are selling rather than following a strict set of rules.", "year": "2008", "author": "Marcus Lillington", "author_slug": "marcuslillington", "published": "2008-12-09T00:00:00+00:00", "url": "https://24ways.org/2008/charm-clients-win-pitches/", "topic": "business"} {"rowid": 99, "title": "A Christmas hCard From Me To You", "contents": "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\u2019s details are up date and that you\u2019ve deleted all those nasty clients who never paid on time?\n\nIt\u2019s 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\u2026 vCard! (See what I did there?)\n\nJust in case you\u2019ve been working in a magical toy factory in the upper reaches of Scandinavia for the last few years, I\u2019m going to tell you that now would also be the perfect time to get into microformats. Using the hCard format, we\u2019ll build a very simple web page and markup our contact details in such a way that they\u2019ll be understood by microformats plugins, like Operator or Tails for Firefox, or the cross-browser Microformats Bookmarklet.\n\nOh, and because Christmas is all about dressing up and being silly, we\u2019ll make the whole thing look nice and have a bit of fun with some CSS3 progressive enhancement. \n\nIf you can\u2019t wait to see what we end up with, you can preview it here.\n\n\n\nStep 1: Contact Details\n\nFirst, let\u2019s decide what details we want to put on the page. I\u2019d put my full name, my email address, my phone number, and my postal address, but I\u2019d rather not get surprise visits from strangers when I\u2019m fannying about with my baubles, so I\u2019m going to use Father Christmas instead (that\u2019s Santa to you Yanks).\n\nFather Christmas\nfatherchristmas@elliotjaystocks.com\n25 Laughingallthe Way\nSnow Falls\nLapland\nFinland\n010 60 58 000\n\nStep 2: hCard Creator\n\nNow I\u2019m 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\u2019ll give you some nice microformatted HTML in turn.\n\n\n\n
\n\tFather Christmas\n\t fatherchristmas@elliotjaystocks.com\n\t
\n\t
25 Laughingallthe Way
\n\tSnow Falls\n\t, \n\tLapland\n\t, \n\tFI-00101\n\tFinland\n
\n
010 60 58 000
\n\t

This hCard created with the hCard creator.

\n
\n\nStep 3: Editing The Code\n\nOne 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\u2019t mean you can\u2019t change it to a . Actually, no, don\u2019t do that. That\u2019s not even excusable at Christmas.\n\nI 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\u2019ll be fine.\n\n
    \n\t

    Father Christmas

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

    Send your Christmas lists my way...

    \n
    \n\t
    \n\t\t

    Father Christmas

    \n\t\tfatherchristmas@elliotjaystocks.com\n\t\t
      \n\t\t\t
    • 25 Laughingallthe Way
    • \n\t\t\t
    • Snow Falls
    • \n\t\t\t
    • Lapland
    • \n\t\t\t
    • FI-00101
    • \n\t\t\t
    • Finland
    • \n\t\t
    \n\t\t010 60 58 000\n\t
    \n\t
    \n\t
    \n
    \n
    \n\t

    A tutorial by Elliot Jay Stocks for 24 Ways

    \n\t

    Background: stock.xchng | Father Christmas: iStockPhoto

    \n
    \n\nStep 6: Some Christmas Sparkle\n\nSo far, our hCard-housing web page is slightly less than inspiring, isn\u2019t it? It\u2019s time to add a bit of CSS. There\u2019s nothing particularly radical going on here; just a simple layout, some basic typographic treatment, and the placement of the Father Christmas photo. I\u2019d usually use a more thorough CSS reset like the one found in the YUI or Eric Meyer\u2019s, but for this basic page, the simple * solution will do.\n\nCheck out the step 6 demo to see our basic styles in place.\n\nFrom this\u2026\n\n\n\n\u2026 to this:\n\n\n\nStep 7: Fun With imagery\n\nNow it\u2019s time to introduce a repeating background image to the element. This will seamlessly repeat for as wide as the browser window becomes.\n\nBut that\u2019s fairly straightforward. How about having some fun with the Father Christmas image? If you look at the image file itself, you\u2019ll see that it\u2019s twice as wide as the area we can see and contains a \u2018hidden\u2019 photo of our rather camp St. Nick.\n\n\n\nAs a light-hearted visual\u2026 er\u2026 \u2018treat\u2019 for users who move their mouse over the image, we move the position of the background image on the \u201cphoto\u201d div. Check out the step 7 demo to see it working.\n\nStep 8: Progressive Enhancement\n\nFinally, 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\u2019t forget: no Christmas pressies for clients who want you to support IE6!)\n\nHere are the rules we\u2019re using to give some browsers a superior viewing experience:\n\n\n\t@font-face allows us to use Jos Buivenga\u2019s free font \u2018Fertigo Pro\u2019 on all text;\n\ttext-shadow adds a little emphasis on the opening paragraph;\n\tbody > p:first-child causes only the first paragraph to receive this treatment;\n\tborder-radius created rounded corners on our main div and the links within it;\n\tand webkit-transition allows us to gently fade in between the default and hover states of those links.\n\n\nAnd with that, we\u2019re done! You can see the results here. It\u2019s time to customise the page to your liking, upload it to your site, and send out the URL. And do it quickly, because I\u2019m sure you\u2019ve got some last-minute Christmas shopping to finish off!", "year": "2008", "author": "Elliot Jay Stocks", "author_slug": "elliotjaystocks", "published": "2008-12-10T00:00:00+00:00", "url": "https://24ways.org/2008/a-christmas-hcard-from-me-to-you/", "topic": "code"} {"rowid": 120, "title": "Easier Page States for Wireframes", "contents": "When designing wireframes for web sites and web apps, it is often overlooked that the same \u2018page\u2019 can look wildly different depending on its context. A logged-in page will look different from a logged-out page; an administrator\u2019s view may have different buttons than a regular user\u2019s view; a power user\u2019s profile will be more extensive than a new user\u2019s.\n\nThese different page states need designing at some point, especially if the wireframes are to form a useful communication medium between designer and developer. Documenting the different permutations can be a time consuming exercise involving either multiple pages in one\u2019s preferred box-and-arrow software, or a fully fledged drawing containing all the possible combinations annotated accordingly.\n\nEnter interactive wireframes and Polypage\n\nInteractive wireframes built in HTML are a great design and communication tool. They provide a clickable prototype, running in the browser as would the final site. As such they give a great feel for how the site will be to use. Once you add in the possibilities of JavaScript and a library such as jQuery, they become even more flexible and powerful.\n\nPolypage is a jQuery plugin which makes it really easy to design multiple page states in HTML wireframes. There\u2019s no JavaScript knowledge required (other than cutting and pasting in a few lines). The page views are created by simply writing all the alternatives into your HTML page and adding special class names to apply state and conditional view logic to the various options. \n\nWhen the page is loaded Polypage automatically detects the page states defined by the class names and creates a control bar enabling the user to toggle page states with the click of a mouse or the clack of a keyboard.\n\n\n\nUsing cookies by way of the jQuery cookie plugin, Polypage retains the view state throughout your prototype. This means you could navigate through your wireframes as if you were logged out; as if you were logged in as an administrator; with notes on or off; or with any other view or state you might require. The possibilities are entirely up to you.\n\nHow does it work?\n\nFirstly you need to link to jQuery, the jQuery cookie plugin and to Polypage. Something like this:\n\n\n\n\n\nThen you need to initialise Polypage on page load using something along these lines:\n\n\n\nNext you need to define the areas of your wireframe which are particular to a given state or view. Do this by applying classes beginning with pp_. Polypage will ignore all other classes in the document.\n\nThe pp_ prefix should be followed by a state name. This can be any text string you like, bearing in mind it will appear in the control bar. Typical page states might include \u2018logged_in\u2019, \u2018administrator\u2019 or \u2018group_owner\u2019. A complete class name would therefore look something like pp_logged_in.\n\nExamples\n\nIf a user is logged in, you might want to specify an option for him or her to sign out. Using Polypage, this could be put in the wireframe as follows:\n\n Sign out \n\nPolypage will identify the pp_logged_in class on the link and hide it (as the \u2018Sign out\u2019 link should only be shown when the page is in the \u2018logged in\u2019 view). Polypage will then automatically write a \u2018logged in\u2019 toggle to the control bar, enabling you to show or hide the \u2018Sign out\u2019 link by toggling the \u2018logged in\u2019 view. The same will apply to all content marked with a pp_logged_in class.\n\nStates can also be negated by adding a not keyword to the class name. For example you might want to provide a log in link for users who are not signed in. Using Polypage, you would insert the not keyword after the pp prefix as follows:\n\n Login \n\nAgain Polypage identifies the pp prefix but this time sees that the \u2018Login\u2019 link should not be shown when the \u2018logged in\u2019 state is selected.\n\nStates can also be joined together to add some basic logic to pages. The syntax follows natural language and uses the or and and keywords in addition to the afore-mentioned not. Some examples would be pp_logged_in_and_admin, pp_admin_or_group_owner and pp_logged_in_and_not_admin.\n\nFinally, you can set default states for a page by passing an array to the polypage.init() function like this:\n\n$.polypage.init(['logged_in', 'admin']);\n\nYou can see a fully fledged example in this fictional social network group page. The example page defaults to a logged in state. You can see the logged out state by toggling \u2018logged in\u2019 off in the Polypage control bar. There are also views specified for a group member, a group admin, a new group and notes. \n\nWhere can I get hold of it?\n\nYou can download the current version from GitHub.\n\nPolypage was originally developed by Clearleft and New Bamboo, with particular contributions from Andy Kent and Natalie Downe. It has been used in numerous real projects, but it is still an early release so there is bound to be room for improvement. We\u2019re pleased to say that Polypage is now an open source project so any feedback, particularly by way of actual improvements, is extremely welcome.", "year": "2008", "author": "Richard Rutter", "author_slug": "richardrutter", "published": "2008-12-11T00:00:00+00:00", "url": "https://24ways.org/2008/easier-page-states-for-wireframes/", "topic": "process"} {"rowid": 106, "title": "Checking Out: Progress Meters", "contents": "It\u2019s the holiday season, so you know what that means: online shopping! When I started developing Web sites back in the 90s, many of my first clients were small local shops wanting to sell their goods online, so I developed many a checkout system. And because of slow dial-up speeds back then, informing the user about where they were in the checkout process was pretty important.\n\nEven though we\u2019re (mostly) beyond the dial-up days, informing users about where they are in a flow is still important. In usability tests at the companies I\u2019ve worked at, I\u2019ve seen time and time again how not adequately informing the user about their state can cause real frustration. This is especially true for two sets of users: mobile users and users of assistive devices, in particular, screen readers.\n\nThe progress meter is a very common design solution used to indicate to the user\u2019s state within a flow. On the design side, much effort may go in to crafting a solution that is as visually informative as possible. On the development side, however, solutions range widely. I\u2019ve checked out the checkouts at a number of sites and here\u2019s what I\u2019ve found when it comes to progress meters: they\u2019re sometimes inaccessible and often confusing or unhelpful \u2014 all because of the way in which they\u2019re coded. For those who use assistive devices or text-only browsers, there must be a better way to code the progress meter \u2014 and there is.\n\n(Note: All code samples are from live sites but have been tweaked to hide the culprits\u2019 identities.)\n\nHow not to make progress\n\nA number of sites assemble their progress meters using non- or semi-semantic markup and images with no alternate text. On text-only browsers (like my mobile phone) and to screen readers, this looks and reads like chunks of content with no context given.\n\n
    \n\t\"\"\n\tShipping information\n\t\"\"\n\t\"\"\n\tPayment information\n\t\"\"\n\t\"\"\n\tPlace your order\n
    \n\nIn the above example, the third state, \u201cPlace your order\u201d, is the current state. But a screen reader may not know that, and my cell phone only displays \"Shipping informationPayment informationPlace your order\". Not good.\n\nIs this progress?\n\nOther sites present the entire progress meter as a graphic, like the following:\n\n\n\nNow, I have no problem with using a graphic to render a very stylish progress meter (my sample above is probably not the most stylish example, of course, but you understand my point). What becomes important in this case is the use of appropriate alternate text to describe the image. Disappointingly, sites today have a wide range of solutions, including using no alternate text. Check out these code samples which call progress meter images.\n\n\"\"\n\nI think we can all agree that the above is bad, unless you really don\u2019t care whether or not users know where they are in a flow.\n\n\"Shipping\n\nThe alt text in the example above just copies all of the text found in the graphic, but it doesn\u2019t represent the status at all. So for every page in the checkout, the user sees or hears the same text. Sure, by the second or third page in the flow, the user has figured out what\u2019s going on, but she or he had to think about it. I don\u2019t think that\u2019s good.\n\n\"Checkout:\n\nThe above probably has the best alternate text out of these examples, because the user at least understands that they\u2019re in the Checkout process, on the Place your order page. But going through the flow with alt text like this, the user doesn\u2019t know how many steps are in the flow.\n\nSemantic progress\n\nOf course, there are some sites that use an ordered list when marking up the progress meter. Hooray! Unfortunately, no text-only browser or screen reader would be able to describe the user\u2019s current state given this markup.\n\n
      \n\t
    1. shipping information
    2. \n\t
    3. payment information
    4. \n\t
    5. place your order
    6. \n
    \n\nWithout CSS enabled, the above is rendered as follows:\n\n\n\nProgress at last\n\nWe all know that semantic markup makes for the best foundation, so we\u2019ll start with the markup found above. In order to make the state information accessible, let\u2019s add some additional text in paragraph and span elements.\n\n
    \n\t

    There are three steps in this checkout process.

    \n\t
      \n\t\t
    1. Enter your shipping information
    2. \n\t\t
    3. Enter your payment information
    4. \n\t\t
    5. Review details and place your order
    6. \n\t
    \n
    \n\nAdd on some simple CSS to hide the paragraph and spans, and arrange the list items on a single line with a background image to represent the large number, and this is what you\u2019ll get:\n\n \n\tThere are three steps in this checkout process.\n\t\n\t\tEnter your shipping information\n\t\tEnter your payment information\n\t\tReview details and place your order\n\t\n \n\nTo display and describe a state as active, add the class \u201ccurrent\u201d to one of the list items. Then change the hidden content such that it better describes the state to the user.\n\n
    \n\t

    There are three steps in this checkout process.

    \n\t
      \n\t\t
    1. You are currently entering your shipping information
    2. \n\t\t
    3. In the next step, you will enter your payment information
    4. \n\t\t
    5. In the last step, you will review the details and place your order
    6. \n\t
    \n
    \n\nThe end result is an attractive progress meter that gives much greater semantic and contextual information.\n\n \n\tThere are three steps in this checkout process.\n\t\n\t\tYou are currently entering your shipping information\n\t\tIn the next step, you will enter your payment information\n\t\tIn the last step, you will review the details and place your order\n\t\n \n\nFor example, the above example renders in a text-only browser as follows:\n\n \n\tThere are three steps in this checkout process.\n\t\n\t\tYou are currently entering your shipping information\n\t\tIn the next step, you will enter your payment information\n\t\tIn the last step, you will review the details and place your order\n\t\n \n\nAnd the screen reader I use for testing announces the following:\n\n \n\tThere are three steps in this checkout process. List of three items. You are currently entering your shipping information. In the next step, you will enter your payment information. In the last step, you will review the details and place your order. List end.\n \n\nHere\u2019s a sample code page that summarises this approach.\n\nHappy frustration-free online shopping with this improved progress meter!", "year": "2008", "author": "Kimberly Blessing", "author_slug": "kimberlyblessing", "published": "2008-12-12T00:00:00+00:00", "url": "https://24ways.org/2008/checking-out-progress-meters/", "topic": "ux"} {"rowid": 117, "title": "The First Tool You Reach For", "contents": "Microsoft recently announced that Internet Explorer 8 will be released in the first half of 2009. Compared to the standards support of other major browsers, IE8 will not be especially great, but it will finally catch up with the state of the art in one specific area: support for CSS tables. This milestone has the potential to trigger an important change in the way you approach web design.\n\nTo show you just how big a difference CSS tables can make, think about how you might code a fluid, three-column layout from scratch. Just to make your life more difficult, give it one fixed-width column, with a background colour that differs from the rest of the page. Ready? Go!\n\nOkay, since you\u2019re the sort of discerning web designer who reads 24ways, I\u2019m going to assume you at least considered doing this without using HTML tables for the layout. If you\u2019re especially hardcore, I imagine you began thinking of CSS floats, negative margins, and faux columns. If you did, colour me impressed!\n\nNow admit it: you probably also gave an inward sigh about the time it would take to figure out the math on the negative margin overlaps, check for dropped floats in Internet Explorer and generally wrestle each of the major browsers into giving you what you want. If after all that you simply gave up and used HTML tables, I can\u2019t say I blame you.\n\nThere are plenty of professional web designers out there who still choose to use HTML tables as their main layout tool. Sure, they may know that users with screen readers get confused by inappropriate use of tables, but they have a job to do, and they want tools that will make that job easy, not difficult.\n\nNow let me show you how to do it with CSS tables. First, we have a div element for each of our columns, and we wrap them all in another two divs:\n\n
    \n\t
    \n\t\t
    \n\t\t\u22ee\n\t\t
    \n\t\t
    \n\t\t\u22ee\n\t\t
    \n\t\t
    \n\t\t\u22ee\n\t\t
    \n\t
    \n
    \n\nDon\u2019t sweat the \u201cdiv clutter\u201d in this code. Unlike tables, divs have no semantic meaning, and can therefore be used liberally (within reason) to provide hooks for the styles you want to apply to your page.\n\nUsing CSS, we can set the outer div to display as a table with collapsed borders (i.e. adjacent cells share a border) and a fixed layout (i.e. cell widths unaffected by their contents):\n\n.container {\n\tdisplay: table;\n\tborder-collapse: collapse;\n\ttable-layout: fixed;\n}\n\nWith another two rules, we set the middle div to display as a table row, and each of the inner divs to display as table cells:\n\n.container > div {\n\tdisplay: table-row;\n}\n.container > div > div {\n\tdisplay: table-cell;\n}\n\nFinally, we can set the widths of the cells (and of the table itself) directly:\n\n.container {\n\twidth: 100%;\n}\n#menu {\n\twidth: 200px;\n}\n#content {\n\twidth: auto;\n}\n#sidebar {\n\twidth: 25%;\n}\n\nAnd, just like that, we have a rock solid three-column layout, ready to be styled to your own taste, like in this example:\n\n\n\nThis example will render perfectly in reasonably up-to-date versions of Firefox, Safari and Opera, as well as the current beta release of Internet Explorer 8.\n\nCSS tables aren\u2019t only useful for multi-column page layout; they can come in handy in most any situation that calls for elements to be displayed side-by-side on the page. Consider this simple login form layout:\n\n\n\nThe incantation required to achieve this layout using CSS floats may be old hat to you by now, but try to teach it to a beginner, and watch his eyes widen in horror at the hoops you have to jump through (not to mention the assumptions you have to build into your design about the length of the form labels).\n\nHere\u2019s how to do it with CSS tables:\n\n
    \n\t
    \n\t\t
    \n\t\t\t\n\t\t\t\n\t\t
    \n\t\t
    \n\t\t\t\n\t\t\t\n\t\t
    \n\t\t
    \n\t\t\t\n\t\t\t\n\t\t
    \n\t
    \n
    \n\nThis time, we\u2019re using a mixture of divs and spans as semantically transparent styling hooks. Let\u2019s look at the CSS code.\n\nFirst, we set up the outer div to display as a table, the inner divs to display as table rows, and the labels and spans as table cells (with right-aligned text):\n\nform > div {\n\tdisplay: table;\n}\nform > div > div {\n\tdisplay: table-row;\n}\nform label,\nform span {\n\tdisplay: table-cell;\n\ttext-align: right;\n}\n\nWe want the first column of the table to be wide enough to accommodate our labels, but no wider. With CSS float techniques, we had to guess at what that width was likely to be, and adjust it whenever we changed our form labels. With CSS tables, we can simply set the width of the first column to something very small (1em), and then use the white-space property to force the column to the required width:\n\nform label {\n\twhite-space: nowrap;\n\twidth: 1em;\n}\n\nTo polish off the layout, we\u2019ll make our text and password fields occupy the full width of the table cells that contain them:\n\ninput[type=text],\ninput[type=password] {\n\twidth: 100%;\n}\n\nThe rest is margins, padding and borders to get the desired look. Check out the finished example.\n\nAs the first tool you reach for when approaching any layout task, CSS tables make a lot more sense to your average designer than the cryptic incantations called for by CSS floats. When IE8 is released and all major browsers support CSS tables, we can begin to gradually deploy CSS table-based layouts on sites that are more and more mainstream.\n\nIn our new book, Everything You Know About CSS Is Wrong!, Rachel Andrew and I explore in much greater detail how CSS tables work as a page layout tool in the real world. CSS tables have their quirks just like floats do, but they don\u2019t tend to affect common layout tasks, and the workarounds tend to be less fiddly too. Check it out, and get ready for the next big step forward in web design with CSS.", "year": "2008", "author": "Kevin Yank", "author_slug": "kevinyank", "published": "2008-12-13T00:00:00+00:00", "url": "https://24ways.org/2008/the-first-tool-you-reach-for/", "topic": "code"} {"rowid": 119, "title": "Rocking Restrictions", "contents": "I love my job. I live my job. For every project I do, I try to make it look special. I\u2019ll be honest: I have a fetish for comments like \u201cI never saw anything like that!\u201d or, \u201cI wish I thought of that!\u201d. I know, I have an ego-problem. (Eleven I\u2019s already)\n\nBut sometimes, you run out of inspiration. Happens to everybody, and everybody hates it. \u201cI\u2019m the worst designer in the world.\u201d \u201cEverything I designed before this was just pure luck!\u201d No it wasn\u2019t.\n\nCountless articles about finding inspiration have already been written. Great, but they\u2019re not the magic potion you\u2019d expect them to be when you need it. Here\u2019s a list of small tips that can have immediate effect when applying them/using them. Main theme: Liberate yourself from the designers\u2019 block by restricting yourself.\n\nDo\u2019s\n\nGrids\n\nIf you aren\u2019t already using grids, you\u2019re doing something wrong. Not only are they a great help for aligning your design, they also restrict you to certain widths and heights. (For more information about grids, I suggest you read Mark Boulton\u2019s series on designing grid systems. Oh, he\u2019s also publishing a book I think.)\n\nSo what\u2019s the link between grids and restrictions? Instead of having the option to style a piece of layout with a width of 1 to 960 pixels, you have to choose from values like 60 pixels, 140, 220, 300, \u2026\n\nStart small\n\nHaving a hard time finding a style for the layout, why don\u2019t you start with one small object? No, not that small object, I meant a piece of a form, or a link, or try styling your headers (h1 \u2013 h6).\n\nLet\u2019s take a submit button of a form: it\u2019s small, but needs much attention. People will click it. People will hover it. Maybe sometimes it\u2019s disabled? Also: a button needs to look like a button, so typically it requires more styling then a regular link. Once you\u2019ve got the button, move on, following the button\u2019s style.\n\nColor palettes\n\nThere are lots of resources on the web for finding inspiration for color palettes. Some of the most famous are COLOURlovers, wear palettes and Adobe\u2019s Kuler. Browse through them (or create your own from a picture), pick a color palette you like and which works with the subject you\u2019re handling, and stick with it. 4-5 colors, maybe with some tonal variations, but that\u2019s it.\n\nFonts\n\nThere aren\u2019t many fonts available for the web (Richard Rutter has a great article on this subject), but you\u2019d be surprised how long they go. A simple text-transform: uppercase; or font-style: italic; can change a dull looking font into something entirely fresh.\n\nPlay around with the fonts you want to use and the variations you\u2019ll be using, and make a list. Pick five combinations of fonts and their variations, and stick with them throughout the layout.\n\nSingle-task\n\nMost of us use multiple monitors. They\u2019re great to increase productivity, but make it harder to focus on a single task. Here\u2019s what you do: try using only your smallest monitor. Maybe it\u2019s the one from your laptop, maybe it\u2019s an old 1024\u00d7768 you found in the attic. Having Photoshop (or Fireworks or\u2026) taking over your entire workspace blocks out all the other distractions on your screen, and works quite liberating.\n\nMute everything\u2026\n\n\u2026but not entirely. I noticed I was way more focused when I set NetNewsWire to refresh it\u2019s feeds only once every two hours. After two hours, I need a break anyway. Turning off Twitterrific was a mistake, as it\u2019s my window to the world, and it\u2019s the place where the people I like to call colleagues live. You can\u2019t exactly ask them to bring you a cup of coffee when they go to the vending machine, but they do keep you fresh, and it stops you from going human-shy. Instead I changed the settings to not play a notification sound when new Tweets arrive so it doesn\u2019t disturb me when I\u2019m zoning.\n\nDon\u2019ts\n\nCSS galleries\n\nDon\u2019t start browsing all kinds of CSS galleries. Either you\u2019ll feel bad, or you just start using elements in a way you can\u2019t call \u201cinspired\u201d anymore. Instead gather your own collection of inspiration. Example: I use LittleSnapper in which I dump everything I find inspiring. This goes from a smart layout idea, to a failed picture someone posted on Flickr. Everything is inspiring.\n\nPanicking\n\nDon\u2019t panic. It\u2019s the worst thing you could do. Instead, get away from the computer, and go to bed early. A good night of sleep combined with a hot/cold shower can give you a totally new perspective on a design. Got a deadline by tomorrow? Well, you should\u2019ve started earlier. Got a good excuse to start on this design this late? Tell your client it was either that or a bad design.\n\n120-hour work-week\n\nDon\u2019t work all day long, including evenings and early mornings. Write off that first hour, you don\u2019t really think you\u2019ll get anything productive done before 9AM?! I don\u2019t even think you should work on one and the same design all day long. If you\u2019re stuck, try working in blocks of 1 or 2 hours on a certain design. Mixing projects isn\u2019t for everyone, but it might just do the trick for you.\n\nSummary\n\n\n\tUse grids, not only for layout purposes.\n\tPick a specific element to start with.\n\tUse a colour palette.\n\tLimit the amount of fonts and variations you\u2019ll use.\n\tSearch for the smallest monitor around, and restrict yourself to that one.\n\tReduce the amount of noise.\n\tDon\u2019t start looking on the internet for inspiration. Build your own little inspirarchive.\n\tWork in blocks.", "year": "2008", "author": "Tim Van Damme", "author_slug": "timvandamme", "published": "2008-12-14T00:00:00+00:00", "url": "https://24ways.org/2008/rocking-restrictions/", "topic": "process"} {"rowid": 97, "title": "Making Modular Layout Systems", "contents": "For all of the advantages the web has with distribution of content, I\u2019ve always lamented the handiness of the WYSIWYG design tools from the print publishing world. When I set out to redesign my personal website, I wanted to have some of the same abilities that those tools have, laying out pages how I saw fit, and that meant a flexible system for dealing with imagery. \n\nBuilding on some of the CSS that Eric Meyer employed a few years back on the A List Apart design, I created a set of classes to use together to achieve the variety I was after. Employing multiple classes isn\u2019t a new technique, but most examples aren\u2019t coming at this from strictly editorial and visual perspectives; I wanted to have options to vary my layouts depending on content.\n\nIf you want to skip ahead, you can view the example first.\n\nLaying the Foundation\n\nWe need to be able to map out our page so that we have predictable canvas, and then create a system of image sizes that work with it. For the sake of this article, let\u2019s use a simple uniform 7-column grid, consisting of seven 100px-wide columns and 10px of space between each column, though you can use any measurements you want as long as they remain constant.\n\n\nAll of our images will have a width that references the grid column widths (in our example, 100px, 210px, 320px, 430px, 540px, 650px, or 760px), but the height can be as large as needed.\n\n\nOnce we know our images will all have one of those widths, we can setup our CSS to deal with the variations in layout. In the most basic form, we\u2019re going to be dealing with three classes: one each that represent an identifier, a size, and a placement for our elements.\n\n\nThis is really a process of abstracting the important qualities of what you would do with a given image in a layout into separate classes, allowing you to quickly customize their appearance by combining the appropriate classes. Rather than trying to serve up a one-size-fits-all approach to styling, we give each class only one or two attributes and rely on the combination of classes to get us there.\n\n\nIdentifier\n\nThis specifies what kind of element we have: usually either an image (pic) or some piece of text (caption).\n\n\nSize\n\nSince we know how our grid is constructed and the potential widths of our images, we can knock out a space equal to the width of any number of columns. In our example, that value can be one, two, three, four, five, six, or seven.\n\nPlacement\n\nThis tells the element where to go. In our example we can use a class of left or right, which sets the appropriate floating rule.\n\n\nAdditions\n\nI created a few additions that be tacked on after the \u201cplacement\u201d in the class stack: solo, for a bit more space beneath images without captions, frame for images that need a border, and inset for an element that appears inside of a block of text. Outset images are my default, but you could easily switch the default concept to use inset images and create a class of outset to pull them out of the content columns.\n\n\nThe CSS\n\n/* I D E N T I F I E R */\n.pic p, .caption {\n font-size: 11px;\n line-height: 16px;\n font-family: Verdana, Arial, sans-serif;\n color: #666;\n margin: 4px 0 10px;\n}\n/* P L A C E M E N T */\n.left {float: left; margin-right: 20px;}\n.right {float: right; margin-left: 20px;}\n.right.inset {margin: 0 120px 0 20px;} /* img floated right within text */\n.left.inset {margin-left: 230px;} /* img floated left within text */\n/* S I Z E */\n.one {width: 100px;}\n.two {width: 210px;}\n.three {width: 320px;}\n.four {width: 430px;}\n.five {width: 540px;}\n.six {width: 650px;}\n.seven {width: 760px;}\n.eight {width: 870px;}\n/* A D D I T I O N S */\n.frame {border: 1px solid #999;}\n.solo img {margin-bottom: 20px;}\n\nIn Use\n\nYou can already see how powerful this approach can be. If you want an image and a caption on the left to stretch over half of the page, you would use:\n\n
    \n\t\n\t

    Caption goes here.

    \n
    \n\nOr, for that same image with a border and no caption:\n\n\n\nYou just tack on the classes that contain the qualities you need. And because we\u2019ve kept each class so simple, we can apply these same stylings to other elements too:\n\n

    Caption goes here.

    \n\nCaveats\n\nObviously there are some potential semantic hang-ups with these methods. While classes like pic and caption stem the tide a bit, others like left and right are tougher to justify. This is something that you have to decide for yourself; I\u2019m fine with the occasional four or left class because I think there\u2019s a good tradeoff. Just as a fully semantic solution to this problem would likely be imperfect, this solution is imperfect from the other side of the semantic fence. Additionally, IE6 doesn\u2019t understand the chain of classes within a CSS selector (like .right.inset). If you need to support IE6, you may have to write a few more CSS rules to accommodate any discrepancies.\n\nOpportunities\n\nThis is clearly a simple example, but starting with a modular foundation like this leaves the door open for opportunity. We\u2019ve created a highly flexible and human-readable system for layout manipulation. Obviously, this is something that would need to be tailored to the spacing and sizes of your site, but the systematic approach is very powerful, especially for editorial websites whose articles might have lots of images of varying sizes. It may not get us fully to the flexibility of WYSIWYG print layouts, but methods like this point us in a direction of designs that can adapt to the needs of the content.\n\n\nView the example: without grid and with grid.", "year": "2008", "author": "Jason Santa Maria", "author_slug": "jasonsantamaria", "published": "2008-12-15T00:00:00+00:00", "url": "https://24ways.org/2008/making-modular-layout-systems/", "topic": "process"} {"rowid": 113, "title": "What Your Turkey Can Teach You About Project Management", "contents": "The problem with project management is that everyone thinks it\u2019s boring. Well, that\u2019s not really the problem. The problem is that everyone thinks it\u2019s boring but it\u2019s still really important. Project management is what lets you deliver your art \u2013 whether that be design or development. \n\nIn the same way, a Christmas dinner cooked by a brilliant chef with no organizational skills is disastrous \u2013 courses arrive in the wrong order, some things are cold whilst others are raw and generally it\u2019s a trip to the ER waiting to happen. Continuing the Christmas dinner theme, here are my top tips for successful projects, wrapped up in a nice little festive analogy. Enjoy!\n\nTip 1: Know What You\u2019re Aiming For\n\n(Turkey? Ham? Both??)\n\nThe underlying cause for the failure of so many projects is mismatched expectations. Christmas dinner cannot be a success if you serve glazed ham and your guests view turkey as the essential Christmas dinner ingredient. It doesn\u2019t matter how delicious and well executed your glazed ham is, it\u2019s still fundamentally just not turkey. You might win one or two adventurous souls over, but the rest will go home disappointed.\n\nAdd to the mix the fact that most web design projects are nowhere near as emotive as Christmas dinner (trust me, a ham vs turkey debate will rage much longer than a fixed vs fluid debate in normal human circles) and the problem is compounded. In particular, as technologists, we forget that our ability to precisely imagine the outcome of a project, be it a website, a piece of software, or similar, is much more keenly developed than the average customer of such projects. \n\nSo what\u2019s the solution? Get very clear, from the very beginning, on exactly what the project is about. What are you trying to achieve? How will you measure success? Is the presence of turkey a critical success factor?\n\nSummarize all this information in some form of document (in PM-speak, it\u2019s called a Project Initiation Document typically). Ideally, get the people who are the real decision makers to sign their agreement to that summary in their own blood. Well, you get the picture, I suppose actual blood is not strictly necessary, but a bit of gothic music to set the tone can be useful!\n\nTip 2: Plan at the Right Level of Detail\n\nHugely detailed and useless Gantt charts are a personal bugbear of mine. For any project, you should plan at the appropriate level of detail (and in an appropriate format) for the project itself. In our Christmas dinner example, it may be perfectly fine to have a list of tasks for the preparation work, but for the intricate interplay of oven availability and cooking times, something more complex is usually due. Having cooked roast dinners for fourteen in a student house where only the top oven and two of the rings on the hob actually worked, I can attest to the need for sequence diagrams in some of these situations!\n\nThe mistake many small teams make is to end up with a project plan that is really the amalgamation of their individual todo lists. What is needed is a project plan that will:\n\n\n\treflect reality\n\tbe easy to update\n\thelp to track progress (i.e. are we on track or not?)\n\n\nA good approach is to break your project into stages (each representing something tangible) and then into deliverables (again, something tangible for each milestone, else you\u2019ll never know if you\u2019ve hit it or not!). \n\nMy personal rule of thumb is that the level of granularity needed on most projects is 2-3 days \u2013 i.e. we should never be more than two to three days from a definitive milestone which will either be complete or not. The added advantage of this approach is that if find yourself off track, you can only be two to three days off track\u2026 much easier to make up than if you went weeks or even months working hard but not actually delivering what was needed!\n\nIn our Christmas dinner example, there are a number of critical milestones \u2013 a tick list of questions. Do we have all the ingredients? Check. Has the turkey been basted? Check. On the actual day, the sequencing and timing will mean more specific questions: It\u2019s 12pm. Are the Brussels sprouts cooked to death yet? Check. (Allowing for the extra hour of boiling to go from soft and green to mushy and brown\u2026 Yeuch!) \n\nTip 3: Actively Manage Risks and Issues\n\nA risk is something that could go wrong. An issue is something that has already gone wrong. Risks and issues are where project management superstars are born. Anyone can manage things when everything is going according to plan; it\u2019s what you do when Cousin Jim refuses to eat anything but strawberry jam sandwiches that sorts the men from the boys. \n\nThe key with a Christmas dinner, as with any project, is to have contingency plans for the most likely and most damaging risks. These depend on your own particular situation, but some examples might be:\n\n \n\t\t\n\t\t\tRISK\n\t\t\tCONTINGENCY PLAN\n\t\t\n\t\t\n\t\t\tCousin Jim is a picky eater.\n\t\t\tHave strawberry jam and sliced white bread on hand to placate.\n\t\t\n\t\t\n\t\t\tPrime organic turkey might not be available at Waitrose on Christmas eve.\n\t\t\tShop in advance!\n\t\t\n\t\t\n\t\t\tYou live somewhere remote that seems to lose power around Christmas on a disturbingly regular basis.\n\t\t\t(number of options here depending on how far you want to go\u2026)\n\n\t\t\t\t\tBuy a backup generator.\n\n\t\t\t\t\tInvent a new cooking method using only candles.\n\n\t\t\t\t\tStock up on \u201cChristmas dinner in a tin\u201d.\n\t\t\n\t\t\n\t\t\tYour mother in law is likely to be annoying.\n\t\t\tBottle of sherry at the ready (whether it\u2019s for you or her, you can decide!).\n\t\t\n \n\n\nThe point of planning in advance is so that most of your issues don\u2019t blindside you \u2013 you can spring into action with the contingency plan immediately. This leaves you with plenty of ingenuity and ability to cope in reserve for those truly unexpected events. \n\nBack in your regular projects, you should have a risk management plan (developed at the beginning of the project and regularly reviewed) as well as an issue list, tracking open, in progress and closed issues. Importantly, your issue list should be separate from any kind of bug list \u2013 issues are at a project level, bugs are at a technical level.\n\nTip 4: Have a Project Board\n\nA project board consists of the overall sponsor of your project (often, but not always, the guy with the cheque book) and typically a business expert and a technical expert to help advise the sponsor. The project board is the entity that is meant to make the big, critical decisions. As a project manager, your role is to prepare a recommendation, but leave the actual decision up to the board. \n\nAdmittedly this is where our Christmas dinner analogy has to stretch the most, but if you imagine that instead of just cooking for your family you are the caterer preparing a Christmas feast for a company. In this case, you obviously want to please the diners who will be eating the food, but key decisions are likely to be taken by whoever is organizing the event. They, in turn, will involve the boss if there are really big decisions that would affect the project drastically \u2013 for instance, having to move it to January, or it exceeding the set budget by a significant amount.\n\nMost projects suffer from not having a project board to consult for these major decisions, or from having the wrong people selected. The first ailment is eased by ensuring that you have a functioning project board, with whom you either meet regularly to update on status, or where there is a special process for convening the board if they are needed. The second problem is a little more subtle. Key questions to ask yourself are:\n\n\n\tWho is funding this project?\n\tWho has the authority to stop the project if it was the right thing to do?\n\tWho are the right business and technical advisors?\n\tWho are the folks who don\u2019t look like they are powerful on the org chart, but in fact might scupper this project? (e.g. administrators, tech support, personal assistants\u2026)\n\n\nTip 5: Finish Unequivocably and Well\n\nNo one is ever uncertain as to when Christmas dinner ends. Once the flaming pudding has been consumed and the cheese tray picked at, the end of the dinner is heralded by groaning and everyone collapsing in their chairs. Different households have different rituals, so you might only open your presents after Christmas dinner (unlikely if you have small children!), or you might round off the afternoon watching the Queen\u2019s speech (in Britland, certainly) or if you live in warmer climes you might round off Christmas dinner with a swim (which was our tradition in Cape Town \u2013 after 30 mins of food settling so you didn\u2019t get cramp, of course!). \n\nThe problem with projects is that they are one time efforts and so nowhere near as ritualized. Unless you have been incredibly lucky, you\u2019ve probably worked on a project where you thought you were finished but seemed unable to lose your \u201czombie customers\u201d \u2013 those folks who just didn\u2019t realise it was over and kept coming back with more and more requests. You might even have fallen prey to this yourself, believing that the website going live was the end of the project and not realising that a number of things still needed to be wrapped up.\n\nThe essence of this final tip is to inject some of that end-of-Christmas finality ritual into your projects. Find your own ritual for closing down projects \u2013 more than just sending the customer the invoice and archiving the files. Consider things like documentation, support structure handover and training to make sure that those zombies are going to the right people (hopefully not you!). \n\nSo, to summarise:\n\n\n\tMake sure you start your projects well \u2013 with an agreed (written) vision of what you\u2019re trying to achieve.\n\tPlan your projects at the right level of detail and in an appropriate format \u2013 never be more than a few days away from knowing for sure whether you\u2019re on track or not.\n\tPlan for likely and important risks and make sure you track and resolve those you actually encounter.\n\tInstitute a project board, made up of the people with the real power over your project.\n\tCreate rituals for closing projects well \u2013 don\u2019t leave anyone in doubt that the project has been delivered, or of who they should go to for further help.", "year": "2008", "author": "Meri Williams", "author_slug": "meriwilliams", "published": "2008-12-16T00:00:00+00:00", "url": "https://24ways.org/2008/what-your-turkey-can-teach-you-about-project-management/", "topic": "business"} {"rowid": 108, "title": "A Festive Type Folly", "contents": "\u2018Tis the season to be jolly, so the carol singers tell us. At 24 ways, we\u2019re keeping alive another British tradition that includes the odd faux-Greco-Roman building dotted around the British countryside, Tower Bridge built in 1894, and your Dad\u2019s Christmas jumper with the dancing reindeer motif. \u2018Tis the season of the folly!\n\n \n 24 Ways to impress your friends\n \n\nThe example is not an image, just text. You may wish to see a screenshot in Safari to compare with your own operating system and browser rendering.\n\nLike all follies this is an embellishment\u200a\u2014\u200aa bit of web typography fun. It\u2019s similar to the masthead text at my place, but it\u2019s also a hyperlink. Unlike the architectural follies of the past, no child labour was used to fund or build it, just some HTML flavoured with CSS, and a heavy dose of Times New Roman. Why Times New Roman, you ask? Well, after a few wasted hours experimenting with heaps of typefaces, seeking an elusive consistency of positioning and rendering across platforms, it proved to be the most consistent. Who\u2019d\u2018a thought? To make things more interesting, I wanted to use a traditional scale and make the whole thing elastic by using relative lengths that would react to a person\u2019s font size. So, to the meat of this festive frippery:\n\nThere are three things we rely on to create this indulgence:\n\n\n\tDescendant selectors\n\tAbsolute positioning\n\tInheritance\n\n\nHTML & Descendant Selectors\n\nThe markup for the folly might seem complex at first glance. To semantics pedants and purists it may seem outrageous. If that\u2019s you, read on at your peril! Here it is with lots of whitespace:\n\n
    \n

    \n\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a02\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a04 \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0w\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0a\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0y\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0s\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0to \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0i\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0m\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pre\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0s\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0s \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0your \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0friends\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\t\n\u00a0\u00a0\n

    \n
    \n\nWhy so much markup? Well, we want to individually style many of the glyphs. By nesting the elements, we can pick out the bits we need as descendant selectors.\n\nTo retain a smidgen of semantics, the text is wrapped in

    and elements. The two phrases, \u201c24 ways\u201d and \u201cto impress your friends\u201d are wrapped in and tags, respectively. Within those loving arms, their descendant s cascade invisibly, making a right mess of our source, but ready to be picked out in our CSS rules.\n\nSo, to select the \u201c2\u201d from the example we can simply write, #type h1 em{ }. Of course, that selects everything within the tags, but as we drill down the document tree, selecting other glyphs, any property / value styles can be reset or changed as required.\n\nPixels Versus Ems\n\nBefore we get stuck into the CSS, I should say that the goal here is to have everything expressed in relative \u201cem\u201d lengths. However, when I\u2019m starting out, I use pixels for all values, and only convert them to ems after I\u2019ve finished. It saves re-calculating the em length for every change I make as the folly evolves, but still makes the final result elastic, without relying on browser zoom.\n\nTo skip ahead, see the complete CSS.\n\nAbsolutely Positioned Glyphs\n\nIf a parent element has position: relative, or position: absolute applied to it, all children of that parent can be positioned absolutely relative to it. (See Dave Shea\u2019s excellent introduction to this.) That\u2019s exactly how the folly is achieved. As the parent, #type also has a font-size of 16px set, a width and height, and some basic style with a background and border:\n\n#type{\n\tfont-size: 16px;\n\ttext-align: left;\n\tbackground: #e8e9de;\n\tborder: 0.375em solid #fff;\n\twidth: 22.5em;\n\theight: 13.125em;\n\tposition: relative;\n}\n\nThe h1 is also given a default style with a font-size of 132px in ems relative to the parent font-size of 16px:\n\n#type h1{\n\tfont-family: \"Times New Roman\", serif;\n\tfont-size: 8.25em; /* 132px */\n\tline-height: 1em;\n\tfont-weight: 400;\n\tmargin: 0;\n\tpadding: 0;\n}\n\nTo get the em value, we divide the required size in pixels by the actual parent font-size in pixels\n\n132 \u00f7 16 = 8.25\n\nWe also give the descendants of the h1 some default properties. The line height, style and weight are normalised, they are positioned absolutely relative to #type, and a border and padding is applied:\n\n#type h1 em,\n#type h1 strong,\n#type h1 span{\n\tline-height: 1em;\n\tfont-style: normal;\n\tfont-weight: 400;\n\tposition: absolute;\n\tpadding: 0.1em;\n\tborder: 1px solid transparent;\n}\n\nThe padding ensures that some browsers don\u2019t forget about parts of a glyph that are drawn outside of their invisible container. When this happens, IE will trim the glyph, cutting off parts of descenders, for example. The border is there to make sure the glyphs have layout. Without this, positioning can be problematic. IE6 will not respect the transparent border colour\u200a\u2014\u200ait uses the actual text colour\u200a\u2014\u200abut in all other respects renders the example. You can hack around it, but it seemed unnecessary for this example.\n\nOnce these defaults are established, the rest is trial and error. As a quick example, the numeral \u201c2\u201d is first to be positioned:\n\n#type h1 a em{\n\tfont-size: 0.727em; /* (2) 96px */\n\tleft: 0.667em;\n\ttop: 0;\n}\n\nEvery element of the folly is positioned in exactly the same way as you can see in the complete CSS. When converting pixels to ems, the font-size is set first. Then, because we know what that is, we calculate the equivalent x- and y-position accordingly.\n\nInheritance\n\nCSS inheritance gave me a headache a long time ago when I first encountered it. After the penny dropped I came to experience something disturbingly close to affection for this characteristic. What it basically means is that children inherit the characteristics of their parents. For example:\n\n\n\tWe gave #type a font-size of 16px.\n\tFor #type h1 we changed it by setting font-size: 8.25em;. Than means that #type h1 now has a computed font-size of 8.25 \u00d7 16px = 132px.\n\tNow, all children of #type h1 in the document tree will inherit a font-size of 132px unless we explicitly change it as we did for #type h1 a em.\n\n\nThe \u201c2\u201d in the example\u200a\u2014\u200aselected with #type h1 a em\u200a\u2014\u200ais set at 96px with left and top positioning calculated relatively to that. So, the left position of 0.667em is 0.667 \u00d7 96 = 64px, approximately (three decimal points in em lengths don\u2019t always give exact pixel equivalents).\n\nOne way to look at inheritance is as a cascade of dependancy: In our example, the computed font size of any given element depends on that of the parent, and the absolute x- and y-position depends on the computed font size of the element itself.\n\nLink Colours\n\nThe same descendant selectors we use to set and position the type are also used to apply the colour by combining them with pseudo-selectors like :focus and :hover. Because the descendant selectors are available to us, we can pretty much pick out any glyph we like. First, we need to disable the underline:\n\n#type h1 a:link,\n#type h1 a:visited{\n\ttext-decoration: none;\n}\n\nIn our example, the \u201c24\u201d has a unique default state (colour):\n\n#type h1 a:link em,\n#type h1 a:visited em{\n\tcolor: #624;\n}\n\nThe rest of the \u201cWays\u201d text has a different colour, which it shares with the large \u201cs\u201d in \u201cimpress\u201d:\n\n#type h1 a:link em span span,\n#type h1 a:visited em span span,\n#type h1 a:link strong span span span span,\n#type h1 a:visited strong span span span span{\n\tcolor: #b32720;\n}\n\n\u201c24\u201d changes on :focus, :hover and :active. Critically though, the whole of the \u201c24 Ways\u201d text, and the large \u201cs\u201d in \u201cimpress\u201d all have the same style in this instance:\n\n#type h1 a:focus em,\n#type h1 a:hover em,\n#type h1 a:active em,\n#type h1 a:focus em span span,\n#type h1 a:hover em span span,\n#type h1 a:active em span span,\n#type h1 a:focus strong span span span span,\n#type h1 a:hover strong span span span span,\n#type h1 a:active strong span span span span{\n\tcolor: #804;\n}\n\nIf a descendant selector has a :link and :visited state set as a pseudo element, it needs to also have the corresponding :focus, :hover and :active states set.\n\nA Final Note About Web Typography\n\nFrom grids to basic leading to web fonts, and even absolute positioning, there\u2019s a wealth of things we can do to treat type on the Web with love and respect. However, experiments like this can highlight the vagaries of rasterisation and rendering that limit our ability to achieve truly subtle and refined results. At the operating system level, the differences in type rendering are extreme, and even between sequential iterations in Windows\u200a\u2014\u200afrom Standard to ClearType\u200a\u2014\u200athey can be daunting. Add to that huge variations in screen quality, and even the paper we print our type onto has many potential variations. Compare our example in Safari 3.2.1 / OS X 10.5.5 (left) and IE7 / Win XP (right). Both rendered on a 23\u201d Apple Cinema HD (LCD):\n\n\n\nBrowser developers continue to make great strides. However, those of us who set type on the Web need more consistency and quality if we want to avoid technologies like Flash and evolve web typography. Although web typography is inevitably\u200a\u2014\u200aand mistakenly\u200a\u2014\u200acompared unfavourably to print, it has the potential to achieve the same refinement in a different way. Perhaps one day, the glyphs of our favourite faces, so carefully crafted, kerned and hinted for the screen, will be rendered with the same precision with which they were drawn by type designers and styled by web designers. That would be my wish for the new year. Happy holidays!", "year": "2008", "author": "Jon Tan", "author_slug": "jontan", "published": "2008-12-17T00:00:00+00:00", "url": "https://24ways.org/2008/a-festive-type-folly/", "topic": "design"} {"rowid": 110, "title": "Shiny Happy Buttons", "contents": "Since Mac OS X burst onto our screens, glossy, glassy, shiny buttons have been almost de rigeur, and have essentially, along with reflections and rounded corners, become a clich\u00e9 of Web 2.0 \u201cdesign\u201d. But if you can\u2019t beat \u2018em you\u2019d better join \u2018em. So, in this little contribution to our advent calendar, we\u2019re going to take a plain old boring HTML button, and 2.0 it up the wazoo. \n\nBut, here\u2019s the catch. We\u2019ll use no images, either in our HTML or our CSS. No sliding doors, no image replacement techniques. Just straight up, CSS, CSS3 and a bit of experimental CSS. And, it will be compatible with pretty much any browser (though with some progressive enhancement for those who keep up with the latest browsers).\n\nThe HTML\n\nWe\u2019ll start with our HTML.\n\n\n\nOK, so it\u2019s not shiny yet \u2013 but boy will it ever be.\n\nBefore styling, that\u2019s going to look like this.\n\nIronically, depending on the operating system and browser you are using, it may well be a shiny button already, but that\u2019s not the point. We want to make it shiny 2.0. Our mission is to make it look something like this\n\n\n\nIf you want to follow along at home keep in mind that depending on which browser you are using you may see fewer of the CSS effects we\u2019ve added to create the button. As of writing, only in Safari are all the effects we\u2019ll apply supported.\n\nTaking a look at our finished product, here\u2019s what we\u2019ve done to it:\n\n\n\tWe\u2019ve given the button some padding and a width.\n\tWe\u2019ve changed the text color, and given the text a drop shadow.\n\tWe\u2019ve given the button a border.\n\tWe\u2019ve given the button some rounded corners.\n\tWe\u2019ve given the button a drop shadow.\n\tWe\u2019ve given the button a gradient background.\n\n\nand remember, all without using any images.\n\nStyling the button\n\nSo, let\u2019s get to work.\n\nFirst, we\u2019ll add given the element some padding and a width:\n\nbutton {\n\tpadding: .5em;\n\twidth: 15em;\n}\n\nNext, we\u2019ll add the text color, and the drop shadow:\n\ncolor: #ffffff;\ntext-shadow: 1px 1px 1px #000;\n\nA note on text-shadow\n\nIf you\u2019ve not seen text-shadows before well, here\u2019s the quick back-story. Text shadow was introduced in CSS2, but only supported in Safari (version 1!) some years later. It was removed from CSS2.1, but returned in CSS3 (in the text module). It\u2019s now supported in Safari, Opera and Firefox (3.1). Internet Explorer has a shadow filter, but the syntax is completely different.\n\nSo, how do text-shadows work? The three length values specify respectively a horizontal offset, a vertical offset and a blur (the greater the number the more blurred the shadow will be), and finally a color value for the shadow.\n\nRounding the corners\n\nNow we\u2019ll add a border, and round the corners of the element:\n\nborder: solid thin #882d13;\n-webkit-border-radius: .7em;\n-moz-border-radius: .7em;\nborder-radius: .7em;\n\nHere, we\u2019ve used the same property in three slightly different forms. We add the browser specific prefix for Webkit and Mozilla browsers, because right now, both of these browsers only support border radius as an experimental property. We also add the standard property name, for browsers that do support the property fully in the future. \n\nThe benefit of the browser specific prefix is that if a browser only partly supports a given property, we can easily avoid using the property with that browser simply by not adding the browser specific prefix. At present, as you might guess, border-radius is supported in Safari and Firefox, but in each the relevant prefix is required.\n\nborder-radius takes a length value, such as pixels. (It can also take two length values, but that\u2019s for another Christmas.) In this case, as with padding, I\u2019ve used ems, which means that as the user scales the size of text up and down, the radius will scale as well. You can test the difference by making the radius have a value of say 5px, and then zooming up and down the text size. \n\nWe\u2019re well and truly on the way now. All we need to do is add a shadow to the button, and then a gradient background.\n\nIn CSS3 there\u2019s the box-shadow property, currently only supported in Safari 3. It\u2019s very similar to text-shadow \u2013 you specify a horizontal and vertical offset, a blur value and a color.\n\n-webkit-box-shadow: 2px 2px 3px #999; \nbox-shadow: 2px 2px 2px #bbb;\n\nOnce more, we require the \u201cexperimental\u201d -webkit- prefix, as Safari\u2019s support for this property is still considered by its developers to be less than perfect.\n\nGradient Background\n\nSo, all we have left now is to add our shiny gradient effect. Now of course, people have been doing this kind of thing with images for a long time. But if we can avoid them all the better. Smaller pages, faster downloads, and more scalable designs that adapt better to the user\u2019s font size preference. But how can we add a gradient background without an image?\n\nHere we\u2019ll look at the only property that is not as yet part of the CSS standard \u2013 Apple\u2019s gradient function for use anywhere you can use images with CSS (in this case backgrounds). In essence, this takes SVG gradients, and makes them available via CSS syntax.\n\nHere\u2019s what the property and its value looks like:\n\nbackground-image: -webkit-gradient(linear, left top, left bottom, from(#e9ede8), to(#ce401c),color-stop(0.4, #8c1b0b));\n\nZooming in on the gradient function, it has this basic form:\n\n-webkit-gradient(type, point, point, from(color), to(color),color-stop(where, color));\n\nWhich might look complicated, but is less so than at first glance.\n\nThe name of the function is gradient (and in this case, because it is an experimental property, we use the -webkit- prefix).\n\nYou might not have seen CSS functions before, but there are others, including the attr() function, used with generated content. A function returns a value that can be used as a property value \u2013 here we are using it as a background image.\n\nNext we specify the type of the gradient. Here we have a linear gradient, and there are also radial gradients. \n\nAfter that, we specify the start and end points of the gradient \u2013 in our case the top and bottom of the element, in a vertical line. \n\nWe then specify the start and end colors \u2013 and finally one stop color, located at 40% of the way down the element. Together, this creates a gradient that smoothly transitions from the start color in the top, vertically to the stop color, then smoothly transitions to the end color.\n\nThere\u2019s one last thing. What color will the background of our button be if the browser doesn\u2019t support gradients? It will be white (or possibly some default color for buttons). Which may make the text difficult or impossible to read. So, we\u2019ll add a background color as well (see why the validator is always warning you when a color but not a background color is specified for an element?).\n\nIf we put it all together, here\u2019s what we have:\n\nbutton {\n\twidth: 15em;\n\tpadding: .5em;\n\tcolor: #ffffff;\n\ttext-shadow: 1px 1px 1px #000;\n\tborder: solid thin #882d13;\n\t-webkit-border-radius: .7em;\n\t-moz-border-radius: .7em;\n\tborder-radius: .7em;\n\t-webkit-box-shadow: 2px 2px 3px #999; \n\tbox-shadow: 2px 2px 2px #bbb;\n\tbackground-color: #ce401c;\n\tbackground-image: -webkit-gradient(linear, left top, left bottom, from(#e9ede8), to(#ce401c),color-stop(0.4, #8c1b0b));\n}\n\nWhich looks like this in various browsers:\n\nIn Safari (3)\n\n\n\nIn Firefox 3.1 (3.0 supports border-radius but not text-shadow)\n\n\n\nIn Opera 10\n\n\n\nand of course in Internet Explorer (version 8 shown here)\n\n\n\nBut it looks different in different browsers\n\nYes, it does look different in different browsers, but we all know the answer to the question \u201cdo web sites need to look the same in every browser?\u201c.\n\nEven if you really think sites should look the same in every browser, hopefully this little tutorial has whet your appetite for what CSS3 and experimental CSS that\u2019s already supported in widely used browsers (and we haven\u2019t even touched on animations and similar effects!).\n\nI hope you\u2019ve enjoyed out little CSSMas present, and look forward to seeing your shiny buttons everywhere on the web.\n\nOh, and there\u2019s just a bit of homework \u2013 your job is to use the :hover selector, and make a gradient in the hover state.", "year": "2008", "author": "John Allsopp", "author_slug": "johnallsopp", "published": "2008-12-18T00:00:00+00:00", "url": "https://24ways.org/2008/shiny-happy-buttons/", "topic": "code"} {"rowid": 100, "title": "Moo'y Christmas", "contents": "A note from the editors: Moo has changed their API since this article was written.\n \n \n \n As the web matures, it is less and less just about the virtual world. It is becoming entangled with our world and it is harder to tell what is virtual and what is real. There are several companies who are blurring this line and make the virtual just an extension of the physical. Moo is one such company. \n\nMoo offers simple print on demand services. You can print business cards, moo mini cards, stickers, postcards and more. They give you the ability to upload your images, customize them, then have them sent to your door. Many companies allow this sort of digital to physical interaction, but Moo has taken it one step further and has built an API. \n\nPrintable stocking stuffers \n\nThe Moo API consists of a simple XML file that is sent to their servers. It describes all the information needed to dynamically assemble and print your object. This is very helpful, not just for when you want to print your own stickers, but when you want to offer them to your customers, friends, organization or community with no hassle. Moo handles the check-out and shipping, all you need to do is what you do best, create! \n\nNow using an API sounds complicated, but it is actually very easy. I am going to walk you through the options so you can easily be printing in no time. \n\nBefore you can begin sending data to the Moo API, you need to register and get an API key. This is important, because it allows Moo to track usage and to credit you. To register, visit http://www.moo.com/api/ and click \u201cRequest an API key\u201d. \n\nIn the following examples, I will use {YOUR API KEY HERE} as a place holder, replace that with your API key and everything will work fine. \n\nFirst thing you need to do is to create an XML file to describe the check-out basket. Open any text-editor and start with some XML basics. Don\u2019t worry, this is pretty simple and Moo gives you a few tools to check your XML for errors before you order. \n\n \n \n\t \n\t\t 0.7\n\t\t {YOUR API KEY HERE}\n\t\t build\n\t\t http://www.example.com/return.html\n\t\t http://www.example.com/fail.html\n\t \n\t \n\t ...\n\t \n\n\nMuch like HTML\u2019s and , Moo has created and elements all wrapped in a element. \n\nThe element contains a few pieces of information that is the same across all the API calls. The element describes which version of the API is being used. This is more important for Moo than for you, so just stick with \u201c0.7\u201d for now. \n\nThe allows Moo to track sales, referrers and credit your account. \n\nThe element can only take \u201cbuild\u201d so that is pretty straight forward. The and elements are URLs. These are optional and are the URLs the customer is redirected to if there is an error, or when the check out process is complete. This allows for some basic branding and a custom \u201cthank you\u201d page which is under your control. That\u2019s it for the element, pretty easy so far! \n\nNext up is the element. What goes inside here describes what is to be printed. There are two possible elements, we can put or we can put directly inside . They work in a similar ways, but they drop the customer into different parts of the Moo checkout process. \n\nIf you specify then you send the customer straight to the Moo payment process. If you specify then you send the customer one-step earlier where they are allowed to pick and choose some images, remove the ones they don\u2019t like, adjust the crop, etc. The example here will use but with a little bit of homework you can easily adjust to if you desire. \n\n... \n \n\t sticker \n\t \n\t\t http://example.com/images/christmas1.jpg \n\t \n \n...\n\nInside the element, we can see there are two basic piece of information. The type of product we want to print, and the images that are to be printed. The element can take one of five options and is required! The possibilities are: minicard, notecard, sticker, postcard or greetingcard. We\u2019ll now look at two of these more closely. \n\nMoo Stickers \n\nIn the Moo sticker books you get 90 small squarish stickers in a small little booklet. \n\n\n\nThe simplest XML you could send would be something like the following payload:\n\n...\n\n\t\n\t\tsticker\n\t\t\n\t\t\thttp://example.com/image1.jpg\n\t\t\n\t\t\n\t\t\thttp://example.com/image2.jpg\n\t\t\n\t\t\n\t\t\thttp://example.com/image3.jpg\n\t\t\n\t\n\n...\n\nThis creates a sticker book with only 3 unique images, but 30 copies of each image. The Sticker books always print 90 stickers in multiples of the images you uploaded. That example only has 3 elements, but you can easily duplicate the XML and send up to 90. The should be the full path to your image and the image needs to be a minimum of 300 pixels by 300 pixels.\n\nYou can add more XML to describe cropping, but the simplest option is to either, let your customers choose or to pre-crop all your images square so there are no issues.\n\nThe full XML you would post to the Moo API to print sticker books would look like this:\n\n \n \n\t\n\t\t0.7\n\t\t{YOUR API KEY HERE}\n\t\tbuild\n\t\thttp://www.example.com/return.html\n\t\thttp://www.example.com/fail.html\n\t\n\t\n\t\t\n\t\t\tsticker\n\t\t\t\n\t\t\t\thttp://example.com/image1.jpg\n\t\t\t\n\t\t\t\n\t\t\t\thttp://example.com/image2.jpg\n\t\t\t\n\t\t\t\n\t\t\t\thttp://example.com/image3.jpg\n\t\t\t\n\t\t\n\t \n\n\nMini-cards \n\nThe mini-cards are the small cute business cards in 14\u00d735 dimensions and come in packs of 100. \n\n\n\nSince the mini-cards are print on demand, this allows you to have 100 unique images on the back of the cards.\n\nJust like the stickers example, we need the same XML setup. The element and elements will be the same as before. The part you will focus on is the section. \n\nSince you are sending along specific information, we can\u2019t use the option any more. Switch this to which has a child of , which in turn has a and . This might seem like a lot of work, but once you have it set up you won\u2019t need to change it.\n\n...\n\n\t\n\t\t\n\t\t\tminicard\n\t\t\t\n\t\t\t\t...\n\t\t\t\n\t\t\n\t\n\n...\n\nSo now that we have the basic framework, we can talk about the information specific to minicards. Inside the element, you will have one for each card. Much like before, this contains a way to describe the image. Note that this time the element is called , not images plural. \n\nInside the element you have a which points to where the image lives and a . The should just be set to \u2018variable\u2019. You can pass crop information here instead, but we\u2019re going to keep it simple for this tutorial. If you are interested in how that works, you should refer to the official API documentation.\n\n...\n\n\t\n\t\thttp://example.com/image1.jpg\n\t\tvariable\n\t\n\n...\n\nSo far, we have managed to build a pack of 100 Moo mini-cards with the same image on the front. If you wanted 100 different images, you just need to replicate this snippit, 99 more times.\n\nThat describes the front design, but the flip-side of your mini-cards can contain 6 lines of text, which is customizable in a variety of colors, fonts and styles.\n\nThe API allows you to create different text on the back of each mini-card, something the web interface doesn\u2019t implement. To describe the text on the mini-card we need to add a element inside the element. If you skip this element, the back of your mini-card will just be blank, but that\u2019s not very festive!\n\nInside the element, we need to describe the type of text we want to format, so we add a element, which in turn contains all the lines of text. Each of Moo\u2019s printed products take different numbers of lines of text, so if you are not planning on making mini-cards, be sure to consult the documentation.\n\nFor mini-cards, we can have 6 distinct lines, each with their own style and layout. Each line is represented by an element which has several optional children. The tells which line of the 6 to print the text one. The is the text you want to print and it must be shorter than 38 characters. The element is false by default, but if you want your text bolded, then add this and set it to true. \n\nThe element is also optional. By default it is set to align left. You can also set this to right or center if you desirer. The element takes one of 3 types, modern, traditional or typewriter. The default is modern. Finally, you can set the , yes that\u2019s color with a \u2018u\u2019, Moo is a British company, so they get to make the rules. When you start a print on demand company, you can spell it however you want. The element takes a 6 character hex value with a leading #.\n\n\n\t...\n\t\n\t\t\n\t\t\t\n\t\t\t\t(1-6)\n\t\t\t\tString, I must be less than 38 chars!\n\t\t\t\ttrue\n\t\t\t\tleft\n\t\t\t\tmodern\n\t\t\t\t#ff0000 \n\t\t\t\n\t\t\n\t\n\n\nIf you combine all of this into a mini-card request you\u2019d get this example:\n\n \n \n\t\n\t\t0.7\n\t\t{YOUR API KEY HERE}\n\t\tbuild\n\t\thttp://www.example.com/return.html\n\t\thttp://www.example.com/fail.html\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\tminicard\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\thttp://example.com/image1.jpg\n\t\t\t\t\t\t\tvariable\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t1\n\t\t\t\t\t\t\t\tString, I must be less than 38 chars!\n\t\t\t\t\t\t\t\ttrue\n\t\t\t\t\t\t\t\tleft\n\t\t\t\t\t\t\t\tmodern\n\t\t\t\t\t\t\t\t#ff0000 \n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t \n\n\nNow you know how to construct the XML that describes what to print. Next, you need to know how to send it to Moo to make it happen!\n\nPosting to the API\n\nSo your XML is file ready to go. First thing we need to do is check it to make sure it\u2019s valid. Moo has created a simple validator where you paste in your XML, and it alerts you to problems.\n\nWhen you have a fully valid XML file, you\u2019ll want to send that to the Moo API. There are a few ways to do this, but the simplest is with an HTML form. \n\nThis is the sample code for an HTML form with a big \u201cBuy My Stickers\u201d button. Once you know that it is working, you can use all your existing HTML knowledge to style it up any way you like.\n\n
    \n\t .... ... \"> \n\t\n
    \n\nThis is just a basic
    element that submits to the Moo API, http://www.moo.com/api/api.php, when someone clicks the button. There is a hidden input called \u201cxml\u201d which contains the value the XML file we created previously.\n\nFor those of you who need to \u201cview source\u201d to fully understand what\u2019s happening can see a working version and peek under the hood.\n\nUsing the API has advantages over uploading the images directly yourself. The images and text that you send via the API can be dynamic. Some companies, like Dopplr, have taken user profiles and dynamic data that changes every minute to generate customer stickers of places that you\u2019ve travelled to or mini-cards with a world map of all the cities you have visited. Every single customer has different travel plans and therefore different sets of stickers and mini-card maps. The API allows for the utmost current information to be printed, on demand, in real-time.\n\nGo forth and Moo\u2019ltiply\n\nSee, making an API call wasn\u2019t that hard was it? You are now 90% of the way to creating anything with the Moo API. With a bit of reading, you can learn that extra 10% and print any Moo product. Be on the lookout in 2009 for the official release of the 1.0 API with improvements and some extras that were not available when this article was written.\n\nThis article is released under the creative-commons attribution share-a-like license. That means you are free to re-distribute it, mash it up, translate it and otherwise re-using it ways the author never considered, in return he only asks you mention his name.\n\n\nThis work by Brian Suda is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.", "year": "2008", "author": "Brian Suda", "author_slug": "briansuda", "published": "2008-12-19T00:00:00+00:00", "url": "https://24ways.org/2008/mooy-christmas/", "topic": "code"} {"rowid": 118, "title": "Ghosts On The Internet", "contents": "By rights the internet should be full of poltergeists, poor rootless things looking for their real homes. Many events on the internet are not properly associated with their correct timeframe. I don\u2019t mean a server set to the wrong time, though that happens too. Much of the content published on the internet is separated from any proper reference to its publication time. What does publication even mean? Let me tell you a story\u2026\n\n\n\t\u201cIt is 2019 and this is Kathy Clees reporting on the story of the moment, the shock purchase of Microsoft by Apple Inc. A Internet Explorer security scare story from 2008 was responsible, yes from 11 years ago, accidently promoted by an analyst, who neglected to check the date of their sources.\u201d\n\n\nIf you think this is fanciful nonsense, then cast your mind back to September 2008, this story in Wired or The Times (UK) about a huge United Airlines stock tumble. A Florida newspaper had a automated popular story section. A random reader looking at a story about United\u2019s 2002 Bankruptcy proceedings caused this story to get picked up by Google\u2019s later visit to the South Florida Sun Sentinel\u2019s news home page. \n\nThe story was undated, Google\u2019s news engine apparently gave it a 2008 date, an analyst picked it up and pushed it to Bloomberg and within minutes the United stock was tumbling. Their stock price dropped from $12 to $3, then recovered to $11 over the day. An eight percent fall in share price over a mis-configured date\n\nCompleting this out of order Christmas Carol, lets look at what is current practice and how dates are managed, we might even get to clank some chains. Publication date used to be inseparable from publication, the two things where stamped on the same piece of paper. How can we determine when things have been published, now?\n\nDetermining publication dates\n\nTime as defined by http://www.w3.org/TR/NOTE-datetime extends ISO 8601, mandating the use of a year value. This is pretty well defined, we can even get very accurate timings down to milliseconds, Ruby and other languages can even handle Calendar reformation. So accuracy is not the issue.\n\nOne problem is that there are many dates which could be interpreted as the publication date. Publication can mean any of date written or created; date placed on server; last modified date; or the current date from the web server. Created and modified have parallels with file systems, but the large number of database driven websites means that this no longer holds much meaning, as there are no longer any files. \n\nChecking web server HEAD may also not correspond, it might give the creation time for the HTML file you are viewing or it might give the last modified time for a file from disk. It is too unreliable and lacking in context to be of real value. So if the web server will not help, then how can we get the right timeframe for our content? \n\nWe are left with URLs and the actual page content.\n\n\n\nLooking at Flickr, this picture (by Douglas County History Research Center) has four date values which can be associated with it. It was taken around 1900, scanned in 1992 and placed on Flickr on July 29th, 2008 and replaced later that day. Which dates should be represented here? \n\nThis is hard question to answer, but currently the date of upload to Flickr is the best represented in terms of the date URL, /photos/douglascountyhistory/archives/date-posted/2008/07/29/, plus some Dublin Core RDF for the year. Flickr uses 2008 as the value for this image. Not accurate, but a reasonable compromise for the millions of other images on their site.\n\nFlickr represents location much better than it represents time. For the most part this is fine, but once you go back in time to the 1800s then the maps of the world start to change a lot and you need to reference both time and place.\n\nThe Google timeline search offers another interesting window on the world, showing results organised by decade for any search term. Being able to jump to a specific occurrence of a term makes it easier to get primary results rather than later reporting. \n\nThe 1918 \u201cSpanish flu\u201d results jump out in this timeline. \n\n\n\nAny major news event will have multiple analysis articles after the event, finding the original reporting of hurricane Katrina is harder now. Many publishers are putting older content online, e.g. Harpers or Nature or The Times, often these use good date based URLs, sometimes they are unhelpful database references. If this content is available for free, then how much better would it be to provide good metadata on date of publication.\n\nDate based URLs\n\nA quick word on date based URLs, they can be brilliant at capturing first published date. However they can be hard to interpret. Is /03/04 a date in March or April, what about 08/03/04? Obviously 2008/03/04 is easier to understand, it is probably March 4th. Including a proper timestamp in the page content avoid this kind of guesswork. \n\nMany sites represent the date as a plain text string; a few hook an HTML class of date around it, a very few provide an actual timestamp. Associating the date with the individual content makes it harder to get the date wrong.\n\nMovable Type and TypePad are a notable exceptions, they will embed Dublin Core RDF to represent each posting e.g. dc:date=\"2008-12-18T02:57:28-08:00\". WordPress doesn\u2019t support date markup out of the box, though there is a patch and a howto for hAtom available.\n\nIn terms of newspapers, the BBC use along with opaque URLs such as http://news.bbc.co.uk/1/hi/technology/7787335.stm. \n\nThe Guardian use nice clear URLs http://www.guardian.co.uk/business/2008/dec/18/car-industry-recession but have no marked up date on the page. \n\nThe New York Times are similar to the Guardian with nice URLs, http://www.nytimes.com/2008/12/19/business/19markets.html, but again no timestamps. All of these papers have all the data available, but it is not marked up in a useful manner.\n\nSyndication formats\n\nSyndication formats are better at supporting dates, RSS uses RFC 822 for dates, just like email so dates such as Wed, 17 Dec 2008 12:52:40 GMT are valid, with all the white space issues that entails. \n\nThe Atom syndication format uses the much clearer http://tools.ietf.org/html/rfc3339 with timestamps of the form 1996-12-19T16:39:57-08:00. Both syndication formats encourage the use of last modified. This is understandable, but a pity as published date is a very useful value. The Atom syndication format supports \u201cpublished\u201d and mandates \u201cupdated\u201d as timestamps, see the Atom RFC 4287 for more detail.\n\nMarking up dates\n\nHowever the aim of this short article is to encourage you to use microformats or RDF to encode dates. A good example of this is Twitter, they use hAtom for each individual entry, http://twitter.com/zzgavin/status/1065835819 contains the following markup, which represents a human and a machine readable version of the time of that tweet.\n\nabout 3 hours ago \n\nThe spec for datetime is still draft at the minute and there is still ongoing conversation around the right format and semantics for representing date and time in microformats, see the datetime design pattern for details. \n\nThe hAtom example page shows the minimal changes required to implement hAtom on well formed blog post content and for other less well behaved content. You have the information already in your content publication systems, this is not some additional onerous content entry task, simply some template formatting.\n\nI started to see this as a serious issue after reading Stewart Brand\u2019s Clock of the Long Now about five years ago. Brand\u2019s book explores the issues of short term thinking that permeate our society, thinking beyond the end of the financial year is a stretch for many people. The Long Now has a world view of a 10,000 year timeframe, see http://longnow.org/ for much more information. Freebase from Long Now Board member Danny Hillis, supports dates quite well \u2013 see the entry for A Christmas Carol.\n\nIn conclusion\n\nI feel we should be making it easier for people searching for our content in the future. We\u2019ve moved through tagging content and on to geo-tagging content. Now it is time to get the timestamps right on our content. How do I know when something happened and how can I find other things that happened at the same time is a fair question. This should be something I can satisfy simply and easily. There are a range of tools available to us in either hAtom or RDF to specify time accurately alongside the content, so what is stopping you?\n\nThinking of the long term it is hard for us to know now what will be of relevance for future generations, so we should aim to raise the floor for publishing tools so that all content has the right timeframe associated with it. We are moving from publishing words and pictures on the internet to being able to associate publication with an individual via XFN and OpenID. We can associate place quite well too, the last piece of useful metadata is timeframe.", "year": "2008", "author": "Gavin Bell", "author_slug": "gavinbell", "published": "2008-12-20T00:00:00+00:00", "url": "https://24ways.org/2008/ghosts-on-the-internet/", "topic": "ux"} {"rowid": 109, "title": "Geotag Everywhere with Fire Eagle", "contents": "A note from the editors: Since this article was written Yahoo! has retired the Fire Eagle service.\n \n \n \n Location, they say, is everywhere. Everyone has one, all of the time. But on the web, it\u2019s taken until this year to see the emergence of location in the applications we use and build.\n\nThe possibilities are broad. Increasingly, mobile phones provide SDKs to approximate your location wherever you are, browser extensions such as Loki and Mozilla\u2019s Geode provide browser-level APIs to establish your location from the proximity of wireless networks to your laptop. Yahoo\u2019s Brickhouse group launched Fire Eagle, an ambitious location broker enabling people to take their location from any of these devices or sources, and provide it to a plethora of web services. It enables you to take the location information that only your iPhone knows about and use it anywhere on the web.\n\nThat said, this is still a time of location as an emerging technology. Fire Eagle stores your location on the web (protected by application-specific access controls), but to try and give an idea of how useful and powerful your location can be \u2014 regardless of the services you use now \u2014 today\u2019s 24ways is going to build a bookmarklet to call up your location on demand, in any web application.\n\nLocation Support on the Web\n\nOver the past year, the number of applications implementing location features has increased dramatically. Plazes and Brightkite are both full featured social networks based around where you are, whilst Pownce rolled in Fire Eagle support to allow geotagging of all the content you post to their microblogging service. Dipity\u2019s beautiful timeline shows for you moving from place to place and Six Apart\u2019s activity stream for Movable Type started exposing your movements.\n\nThe number of services that hook into Fire Eagle will increase as location awareness spreads through the developer community, but you can use your location on other sites indirectly too.\n\nConsider Flickr. Now world renowned for their incredible mapping and places features, geotagging on Flickr started out as a grassroots extension of regular tagging. That same technique can be used to start rolling geotagging in any publishing platform you come across, for any kind of content. Machine-tags (geo:lat= and geo:lon=) and the adr and geo microformats can be used to enhance anything you write with location information.\n\nA crash course in avian inflammability\n\nFire Eagle is a location store. A broker between services and devices which provide location and those which consume it. It\u2019s a switchboard that controls which pieces of your location different applications can see and use, and keeps hidden anything you want kept private. A blog widget that displays your current location in public can be restricted to display just your current city, whilst a service that provides you with a list of the nearest ATMs will operate better with a precise street address. \n\nEven if your iPhone tells Fire Eagle exactly where you are, consuming applications only see what you want them to see. That\u2019s important for users to realise that they\u2019re in control, but also important for application developers to remember that you cannot rely on having super-accurate information available all the time. You need to build location aware applications which degrade gracefully, because users will provide fuzzier information \u2014 either through choice, or through less accurate sources.\n\nApplication specific permissions are controlled through an OAuth API. Each application has a unique key, used to request a second, user-specific key that permits access to that user\u2019s information. You store that user key and it remains valid until such a time as the user revokes your application\u2019s access. Unlike with passwords, these keys are unique per application, so revoking the access rights of one application doesn\u2019t break all the others.\n\nBuilding your first Fire Eagle app; Geomarklet\n\nFire Eagle\u2019s developer documentation can take you through examples of writing simple applications using server side technologies (PHP, Python). Here, we\u2019re going to write a client-side bookmarklet to make your location available in every site you use. It\u2019s designed to fast-track the experience of having location available everywhere on web, and show you how that can be really handy. Hopefully, this will set you thinking about how location can enhance the new applications you build in 2009.\n\nAn oddity of bookmarklets\n\nBookmarklets (or \u2018favlets\u2019, for those of an MSIE persuasion) are a strange environment to program in. Critically, you have no persistent storage available. As such, using token-auth APIs in a static environment requires you to build you application in a slightly strange way; authing yourself in advance and then hardcoding the keys into your script.\n\nGet started\n\nBefore you do anything else, go to http://fireeagle.com and log in, get set up if you need to and by all means take a look around. Take a look at the mobile updaters section of the application gallery and perhaps pick out an app that will update Fire Eagle from your phone or laptop.\n\nOnce that\u2019s done, you need to register for an application key in the developer section. Head straight to /developer/create and complete the form. Since you\u2019re building a standalone application, choose \u2018Auth for desktop applications\u2019 (rather than web applications), and select that you\u2019ll be \u2018accessing location\u2019, not updating.\n\nAt the end of this process, you\u2019ll have two application keys, a \u2018Consumer Key\u2019 and a \u2018Consumer Secret\u2019, which look like these:\n\n \n Consumer Key\n luKrM9U1pMnu\n Consumer Secret\n ZZl9YXXoJX5KLiKyVrMZffNEaBnxnd6M\n \n\nThese keys combined allow your application to make requests to Fire Eagle.\n\nNext up, you need to auth yourself; granting your new application permission to use your location. Because bookmarklets don\u2019t have local storage, you can\u2019t integrate the auth process into the bookmarklet itself \u2014 it would have no way of storing the returned key. Instead, I\u2019ve put together a simple web frontend through which you can auth with your application.\n\nHead to Auth me, Amadeus!, enter the application keys you just generated and hit \u2018Authorize with Fire Eagle\u2019. You\u2019ll be taken to the Fire Eagle website, just as in regular Fire Eagle applications, and after granting access to your app, be redirected back to Amadeus which will provide you your user tokens. These tokens are used in subsequent requests to read your location.\n\nAnd, skip to the end\u2026\n\nThe process of building the bookmarklet, making requests to Fire Eagle, rendering it to the page and so forth follows, but if you\u2019re the impatient type, you might like to try this out right now. Take your four API keys from above, and drag the following link to your Bookmarks Toolbar; it contains all the code described below. Before you can use it, you need to edit in your own API keys. Open your browser\u2019s bookmark editor and where you find text like \u2018YOUR_CONSUMER_KEY_HERE\u2019, swap in the corresponding key you just generated.\n\nGet Location\n\nBookmarklet Basics\n\nTo start on the bookmarklet code, set out a basic JavaScript module-pattern structure:\n\nvar Geomarklet = function() {\n\treturn ({\n\t\tcallback: function(json) {},\n\t\trun: function() {}\n\t});\n};\nGeomarklet.run();\n\nNext we\u2019ll add the keys obtained in the setup step, and also some basic Fire Eagle support objects:\n\nvar Geomarklet = function() {\n\tvar Keys = {\n\t\t\tconsumer_key: 'IuKrJUHU1pMnu',\n\t\t\tconsumer_secret: 'ZZl9YXXoJX5KLiKyVEERTfNEaBnxnd6M',\n\t\t\tuser_token: 'xxxxxxxxxxxx',\n\t\t\tuser_secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'\n\t};\n\tvar LocationDetail = {\n\t\t\tEXACT: 0,\n\t\t\tPOSTAL: 1,\n\t\t\tNEIGHBORHOOD: 2,\n\t\t\tCITY: 3,\n\t\t\tREGION: 4,\n\t\t\tSTATE: 5,\n\t\t\tCOUNTRY: 6\n\t};\n\tvar index_offset;\n\treturn ({\n\t\tcallback: function(json) {},\n\t\trun: function() {}\n\t});\n};\nGeomarklet.run();\n\nThe Location Hierarchy\n\nA successful Fire Eagle query returns an object called the \u2018location hierarchy\u2019. Depending on the level of detail shared, the index of a particular piece of information in the array will vary. The LocationDetail object maps the array indices of each level in the hierarchy to something comprehensible, whilst the index_offset variable is an adjustment based on the detail of the result returned.\n\nThe location hierarchy object looks like this, providing a granular breakdown of a location, in human consumable and machine-friendly forms.\n\n\"user\": {\n\t\t\"location_hierarchy\": [{\n\t\t\t\"level\": 0,\n\t\t\t\"level_name\": \"exact\",\n\t\t\t\"name\": \"707 19th St, San Francisco, CA\",\n\t\t\t\"normal_name\": \"94123\",\n\t\t\t\"geometry\": {\n\t\t\t\t\t\"type\": \"Point\",\n\t\t\t\t\t\"coordinates\": [ - 0.2347530752, 67.232323]\n\t\t\t},\n\t\t\t\"label\": null,\n\t\t\t\"best_guess\": true,\n\t\t\t\"id\": ,\n\t\t\t\"located_at\": \"2008-12-18T00:49:58-08:00\",\n\t\t\t\"query\": \"q=707%2019th%20Street,%20Sf\"\n\t\t},\n\t\t{\n\t\t\t\t\"level\": 1,\n\t\t\t\t\"level_name\": \"postal\",\n\t\t\t\t\"name\": \"San Francisco, CA 94114\",\n\t\t\t\t\"normal_name\": \"12345\",\n\t\t\t\t\"woeid\": ,\n\t\t\t\t\"place_id\": \"\",\n\t\t\t\t\"geometry\": {\n\t\t\t\t\t\t\"type\": \"Polygon\",\n\t\t\t\t\t\t\"coordinates\": [],\n\t\t\t\t\t\t\"bbox\": []\n\t\t\t\t},\n\t\t\t\t\"label\": null,\n\t\t\t\t\"best_guess\": false,\n\t\t\t\t\"id\": 59358791,\n\t\t\t\t\"located_at\": \"2008-12-18T00:49:58-08:00\"\n\t\t},\n\t\t{\n\t\t\t\t\"level\": 2,\n\t\t\t\t\"level_name\": \"neighborhood\",\n\t\t\t\t\"name\": \"The Mission, San Francisco, CA\",\n\t\t\t\t\"normal_name\": \"The Mission\",\n\t\t\t\t\"woeid\": 23512048,\n\t\t\t\t\"place_id\": \"Y12JWsKbApmnSQpbQg\",\n\t\t\t\t\"geometry\": {\n\t\t\t\t\t\t\"type\": \"Polygon\",\n\t\t\t\t\t\t\"coordinates\": [],\n\t\t\t\t\t\t\"bbox\": []\n\t\t\t\t},\n\t\t\t\t\"label\": null,\n\t\t\t\t\"best_guess\": false,\n\t\t\t\t\"id\": 59358801,\n\t\t\t\t\"located_at\": \"2008-12-18T00:49:58-08:00\"\n\t\t\t},\n\t\t}\n\nIn this case the first object has a level of 0, so the index_offset is also 0.\n\nPrerequisites\n\nTo query Fire Eagle we call in some existing libraries to handle the OAuth layer and the Fire Eagle API call. Your bookmarklet will need to add the following scripts into the page:\n\n\n\tThe SHA1 encryption algorithm\n\tThe OAuth wrapper\n\tAn extension for the OAuth wrapper\n\tThe Fire Eagle wrapper itself\n\n\nWhen the bookmarklet is first run, we\u2019ll insert these scripts into the document. We\u2019re also inserting a stylesheet to dress up the UI that will be generated.\n\nIf you want to follow along any of the more mundane parts of the bookmarklet, you can download the full source code.\n\nRendering\n\nThis bookmarklet can be extended to support any formatting of your location you like, but for sake of example I\u2019m going to build three common formatters that you\u2019ll find useful for common location scenarios: Sites which already ask for your location; and in publishing systems that accept tags or HTML mark-up.\n\nAll the rendering functions are items in a renderers object, so they can be iterated through easily, making it trivial to add new formatting functions as your find new use cases (just add another function to the object).\n\nvar renderers = {\ngeotag: function(user) {\n\tif(LocationDetail.EXACT !== index_offset) {\n\t\t\treturn false;\n\t}\n\telse {\n\t\tvar coords =\n\t\t\tuser.location_hierarchy[LocationDetail.EXACT].geometry.coordinates;\n\t\treturn \"geo:lat=\" + coords[0] + \", geo:lon=\" + coords[1];\n\t}\n},\ncity: function(user) {\n\tif(LocationDetail.CITY < index_offset) {\n\t\treturn false;\n\t}\n\telse {\n\t\treturn user.location_hierarchy[LocationDetail.CITY - index_offset].name; \n\t}\t\t\t\t\t\t \n}\n\nYou should always fail gracefully, and in line with catering to users who choose not to share their location precisely, always check that the location has been returned at the level you require. Geotags are expected to be precise, so if an exact location is unavailable, returning false will tell the rendering aspect of the bookmarklet to ignore the function altogether.\n\nThese first two are quite simple, geotag returns geo:lat=-0.2347530752, geo:lon=67.232323 and city returns San Francisco, CA.\n\nThis final renderer creates a chunk of HTML using the adr and geo microformats, using all available aspects of the location hierarchy, and can be used to geotag any content you write on your blog or in comments:\n\nhtml: function(user) {\n\tvar geostring = '';\n\tvar adrstring = '';\n\tvar adr = [];\t\t \n\tadr.push('

    ');\n\t// city\n\tif(LocationDetail.CITY >= index_offset) {\n\t\tadr.push(\n\t\t\t'\\n\t\t '\n\t\t+ user.location_hierarchy[LocationDetail.CITY-index_offset].normal_name\n\t\t+ ','\n\t\t);\n\t}\n\t// county\n\tif(LocationDetail.REGION >= index_offset) {\n\t\tadr.push(\n\t\t\t'\\n\t\t ' \n\t\t+ user.location_hierarchy[LocationDetail.REGION-index_offset].normal_name\n\t\t+ ','\n\t\t\t);\n\t}\n\t// locality\n\tif(LocationDetail.STATE >= index_offset) {\n\t\tadr.push(\n\t\t\t'\\n\t\t '\n\t\t+ user.location_hierarchy[LocationDetail.STATE-index_offset].normal_name\n\t\t+ ','\n\t\t);\n\t}\n\t// country\n\tif(LocationDetail.COUNTRY >= index_offset) {\n\t\tadr.push(\n\t\t\t'\\n\t\t '\n\t\t+ user.location_hierarchy[LocationDetail.COUNTRY-index_offset].normal_name\n\t\t+ ''\n\t\t);\n\t}\n\t// postal\n\tif(LocationDetail.POSTAL >= index_offset) {\n\t\tadr.push(\n\t\t\t'\\n\t\t '\n\t\t+ user.location_hierarchy[LocationDetail.POSTAL-index_offset].normal_name\n\t\t+ ','\n\t\t);\n\t}\n\tadr.push('\\n

    \\n');\n\tadrstring = adr.join('');\n\tif(LocationDetail.EXACT === index_offset) {\n\t\tvar coords = \n\t\t\tuser.location_hierarchy[LocationDetail.EXACT].geometry.coordinates;\n\t\tgeostring = '

    '\n\t\t\t+'\\n\t\t'\n\t\t\t+ coords[0]\n\t\t\t+ ';'\n\t\t\t+ '\\n\t\t '\n\t\t\t+ coords[1]\n\t\t\t+ '\\n

    \\n';\n\t}\n\treturn (adrstring + geostring);\n}\n\nHere we check the availability of every level of location and build it into the adr and geo patterns as appropriate. Just as for the geotag function, if there\u2019s no exact location the geo markup won\u2019t be returned.\n\nFinally, there\u2019s a rendering method which creates a container for all this data, renders all the applicable location formats and then displays them in the page for a user to copy and paste. You can throw this together with DOM methods and some simple styling, or roll in some components from YUI or JQuery to handle drawing full featured overlays.\n\nYou can see this simple implementation for rendering in the full source code.\n\nMake the call\n\nWith a framework in place to render Fire Eagle\u2019s location hierarchy, the only thing that remains is to actually request your location. Having already authed through Amadeus earlier, that\u2019s as simple as instantiating the Fire Eagle JavaScript wrapper and making a single function call. It\u2019s a big deal that whilst a lot of new technologies like OAuth add some complexity and require new knowledge to work with, APIs like Fire Eagle are really very simple indeed.\n\nreturn {\n\trun: function() {\n\t\tinsert_prerequisites();\n\t\tsetTimeout(\n\t\t\tfunction() {\n\t\t\t\tvar fe = new FireEagle(\n\t\t\t\t\tKeys.consumer_key,\n\t\t\t\t\tKeys.consumer_secret,\n\t\t\t\t\tKeys.user_token,\n\t\t\t\t\tKeys.user_secret\n\t\t\t\t);\n\t\t\t\tvar script = document.createElement('script');\n\t\t\t\tscript.type = 'text/javascript';\n\t\t\t\tscript.src = fe.getUserUrl(\n\t\t\t\t\tFireEagle.RESPONSE_FORMAT.json,\n\t\t\t\t\t'Geomarklet.callback'\n\t\t\t\t);\n\t\t\t\tdocument.body.appendChild(script);\n\t\t\t},\n\t\t\t2000\n\t\t);\n\t},\n\tcallback: function(json) {\n\t\tif(json.rsp && 'fail' == json.rsp.stat) {\n\t\t\talert('Error ' + json.rsp.code + \": \" + json.rsp.message);\n\t\t}\n\t\telse {\n\t\t\tindex_offset = json.user.location_hierarchy[0].level;\t\t\t\t\t\t \n\t\t\tdraw_selector(json);\n\t\t}\n\t}\n};\n\nWe first insert the prerequisite scripts required for the Fire Eagle request to function, and to prevent trying to instantiate the FireEagle object before it\u2019s been loaded over the wire, the remaining instantiation and request is wrapped inside a setTimeout delay.\n\nWe then create the request URL, referencing the Geomarklet.callback callback function and then append the script to the document body \u2014 allowing a cross-domain request.\n\nThe callback itself is quite simple. Check for the presence and value of rsp.status to test for errors, and display them as required. If the request is successful set the index_offset \u2014 to adjust for the granularity of the location hierarchy \u2014 and then pass the object to the renderer.\n\nThe result? When Geomarklet.run() is called, your location from Fire Eagle is read, and each renderer displayed on the page in an easily copy and pasteable form, ready to be used however you need.\n\nDeploy\n\nThe final step is to convert this code into a long string for use as a bookmarklet. Easiest for Mac users is the JavaScript bundle in TextMate \u2014 choose Bundles: JavaScript: Copy as Bookmarklet to Clipboard. Then create a new \u2018Get Location\u2019 bookmark in your browser of choice and paste in.\n\nThose without TextMate can shrink their code down into a single line by first running their code through the JSLint tool (to ensure the code is free from errors and has all the required semi-colons) and then use a find-and-replace tool to remove line breaks from your code (or even run your code through JSMin to shrink it down).\n\nWith the bookmarklet created and added to your bookmarks bar, you can now call up your location on any page at all. Get a feel for a web where your location is just another reliable part of the browsing experience.\n\nWhere next?\n\nSo, the Geomarklet you\u2019ve been guided through is a pretty simple premise and pretty simple output. But from this base you can start to extend: Add code that will insert each of the location renderings directly into form fields, perhaps, or how about site-specific handlers to add your location tags into the correct form field in Wordpress or Tumblr? Paste in your current location to Google Maps? Or Flickr?\n\nGeomarklet gives you a base to start experimenting with location on your own pages and the sites you browse daily.\n\nThe introduction of consumer accessible geo to the web is an adventure of discovery; not so much discovering new locations, but discovering location itself.", "year": "2008", "author": "Ben Ward", "author_slug": "benward", "published": "2008-12-21T00:00:00+00:00", "url": "https://24ways.org/2008/geotag-everywhere-with-fire-eagle/", "topic": "code"} {"rowid": 98, "title": "Absolute Columns", "contents": "CSS layouts have come quite a long way since the dark ages of web publishing, with all sorts of creative applications of floats, negative margins, and even background images employed in order to give us that most basic building block, the column. As the title implies, we are indeed going to be discussing columns today\u2014more to the point, a handy little application of absolute positioning that may be exactly what you\u2019ve been looking for\u2026\n\nCare for a nightcap?\n\nIf you\u2019ve been developing for the web for long enough, you may be familiar with this little children\u2019s fable, passed down from wizened Shaolin monks sitting atop the great Mt. Geocities: \u201cOnce upon a time, multiple columns of the same height could be easily created using TABLES.\u201d Now, though we\u2019re all comfortably seated on the standards train (and let\u2019s be honest: even if you like to think you\u2019ve fallen off, if you\u2019ve given up using tables for layout, rest assured your sleeper car is still reserved), this particular\u2014and as page layout goes, quite basic\u2014trick is still a thorn in our CSSides compared to the ease of achieving the same effect using said Tables of Evil\u2122.\n\nSee, the orange juice masks the flavor\u2026\n\nCreative solutions such as Dan Cederholm\u2019s Faux Columns do a good job of making it appear as though adjacent columns maintain equal height as content expands, using a background image to fill the space that the columns cannot.\n\nNow, the Holy Grail of CSS columns behaving exactly how they would as table cells\u2014or more to the point, as columns\u2014still eludes us (cough CSS3 Multi-column layout module cough), but sometimes you just need, for example, a secondary column (say, a sidebar) to match the height of a primary column, without involving the creation of images. This is where a little absolute positioning can save you time, while possibly giving your layout a little more flexibility.\n\nShaken, not stirred\n\nYou\u2019re probably familiar by now with the concept of Making the Absolute, Relative as set forth long ago by Doug Bowman, but let\u2019s quickly review just in case: an element set to position:absolute will position itself relative to its nearest ancestor set to position:relative, rather than the browser window (see Figure 1).\n\n Figure 1.\n\nHowever, what you may not know is that we can anchor more than two sides of an absolutely positioned element. Yes, that\u2019s right, all four sides (top, right, bottom, left) can be set, though in this example we\u2019re only going to require the services of three sides (see Figure 2 for the end result).\n\n Figure 2.\n\nTrust me, this will make you feel better\n\nOur requirements are essentially the same as the standard \u201cabsolute-relative\u201d trick\u2014a container
    set to position:relative, and our sidebar
    set to position:absolute \u2014 plus another
    that will serve as our main content column. We\u2019ll also add a few other common layout elements (wrapper, header, and footer) so our example markup looks more like a real layout and less like a test case:\n\n
    \n\t
    \n\t\t

    #header

    \n\t
    \n\t
    \n\t\t
    \n\t\t\t

    #left

    \n\t\t\t

    Lorem ipsum dolor sit amet\u2026

    \n\t\t
    \n\t\t
    \n\t\t\t

    #right

    \n\t\t
    \n\t
    \n\t
    \n\t\t

    #footer

    \n\t
    \n
    \n\nIn this example, our main column (#column-left) is only being given a width to fit within the context of the layout, and is otherwise untouched (though we\u2019re using pixels here, this trick will of course work with fluid layouts as well), and our right keeping our styles nice and minimal:\n\n#container {\n\tposition: relative;\n}\n#column-left {\n\twidth: 480px;\n}\n#column-right {\n\tposition: absolute;\n\ttop: 10px;\n\tright: 10px;\n\tbottom: 10px;\n\twidth: 250px;\n}\n\nThe trick is a simple one: the #container
    will expand vertically to fit the content within #column-left. By telling our sidebar
    (#column-right) to attach itself not only to the top and right edges of #container, but also to the bottom, it too will expand and contract to match the height of the left column (duplicate the \u201clorem ipsum\u201d paragraph a few times to see it in action).\n\n Figure 3.\n\nOn the rocks\n\n\u201cBut wait!\u201d I hear you exclaim, \u201cwhen the right column has more content than the left column, it doesn\u2019t expand! My text runneth over!\u201d Sure enough, that\u2019s exactly what happens, and what\u2019s more, it\u2019s supposed to: Absolutely positioned elements do exactly what you tell them to do, and unfortunately aren\u2019t very good at thinking outside the box (get it? sigh\u2026). \n\nHowever, this needn\u2019t get your spirits down, because there\u2019s an easy way to address the issue: by adding overflow:auto to #column-right, a scrollbar will automatically appear if and when needed:\n\n#column-right {\n\tposition: absolute;\n\ttop: 10px;\n\tright: 10px;\n\tbottom: 10px;\n\twidth: 250px;\n\toverflow: auto;\n}\n\nWhile this may limit the trick\u2019s usefulness to situations where the primary column will almost always have more content than the secondary column\u2014or where the secondary column\u2019s content can scroll with wild abandon\u2014a little prior planning will make it easy to incorporate into your designs.\n\nDriving us to drink\n\nIt just wouldn\u2019t be right to have a friendly, festive holiday tutorial without inviting IE6, though in this particular instance there will be no shaming that old browser into admitting it has a problem, nor an intervention and subsequent 12-step program. That\u2019s right my friends, this tutorial has abstained from IE6-abuse now for 30 days, thanks to the wizard Dean Edwards and his amazingly talented IE7 Javascript library.\n\nSimply drop the Conditional Comment and