{"rowid": 136, "title": "Making XML Beautiful Again: Introducing Client-Side XSL", "contents": "Remember that first time you saw XML and got it? When you really understood what was possible and the deep meaning each element could carry? Now when you see XML, it looks ugly, especially when you navigate to a page of XML in a browser. Well, with every modern browser now supporting XSL 1.0, I\u2019m going to show you how you can turn something as simple as an ATOM feed into a customised page using a browser, Notepad and some XSL.\n\nWhat on earth is this XSL?\n\nXSL is a family of recommendations for defining XML document transformation and presentation. It consists of three parts:\n\n\n\tXSLT 1.0 \u2013 Extensible Stylesheet Language Transformation, a language for transforming XML\n\tXPath 1.0 \u2013 XML Path Language, an expression language used by XSLT to access or refer to parts of an XML document. (XPath is also used by the XML Linking specification)\n\tXSL-FO 1.0 \u2013 Extensible Stylesheet Language Formatting Objects, an XML vocabulary for specifying formatting semantics\n\n\nXSL transformations are usually a one-to-one transformation, but with newer versions (XSL 1.1 and XSL 2.0) its possible to create many-to-many transformations too. So now you have an overview of XSL, on with the show\u2026\n\nSo what do I need?\n\nSo to get going you need a browser an supports client-side XSL transformations such as Firefox, Safari, Opera or Internet Explorer. Second, you need a source XML file \u2013 for this we\u2019re going to use an ATOM feed from Flickr.com. And lastly, you need an editor of some kind. I find Notepad++ quick for short XSLs, while I tend to use XMLSpy or Oxygen for complex XSL work. \n\nBecause we\u2019re doing a client-side transformation, we need to modify the XML file to tell it where to find our yet-to-be-written XSL file. Take a look at the source XML file, which originates from my Flickr photos tagged sky, in ATOM format.\n\nThe top of the ATOM file now has an additional instruction, as can been seen on Line 2 below. This instructs the browser to use the XSL file to transform the document.\n\n\n\n\n\nYour first transformation\n\nYour first XSL will look something like this:\n\n\n\n\t\n\n\nThis is pretty much the starting point for most XSL files. You will notice the standard XML processing instruction at the top of the file (line 1). We then switch into XSL mode using the XSL namespace on all XSL elements (line 2). In this case, we have added namespaces for ATOM (line 4) and Dublin Core (line 5). This means the XSL can now read and understand those elements from the source XML. \n\nAfter we define all the namespaces, we then move onto the xsl:output element (line 6). This enables you to define the final method of output. Here we\u2019re specifying html, but you could equally use XML or Text, for example. The encoding attributes on each element do what they say on the tin. As with all XML, of course, we close every element including the root.\n\nThe next stage is to add a template, in this case an as can be seen below:\n\n\n\n\t\n\t\n\t\t\n\t\t\t\n\t\t\t\tMaking XML beautiful again : Transforming ATOM\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\n\n\nThe beautiful thing about XSL is its English syntax, if you say it out loud it tends to make sense. \n\nThe / value for the match attribute on line 8 is our first example of XPath syntax. The expression / matches any element \u2013 so this will match against any element in the document. As the first element in any XML document is the root element, this will be the one matched and processed first.\n\nOnce we get past our standard start of a HTML document, the only instruction remaining in this is to look for and match all elements using the in line 14, above.\n\n\n\n\t\n\t\n\t\t\n\t\n\t\n\t\t
\n\t\t\t

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

\n\t\t\t

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

\n\t\t\t
    \n\t\t\t\t\n\t\t\t
\n\t\t
\n\t
\n
\n\nThis new template (line 12, above) matches and starts to write the new HTML elements out to the output stream. The does exactly what you\u2019d expect \u2013 it finds the value of the item specifed in its select attribute. With XPath you can select any element or attribute from the source XML. \n\nThe last part is a repeat of the now familiar from before, but this time we\u2019re using it inside of a called template. Yep, XSL is full of recursion\u2026\n\n\n\t
  • \n\t\t

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

    \n\t\t

    \n\t\t\t()\n\t\t

    \n\t\t

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

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

    with a link wrapped within it (lines 3-7). We can select attributes using XPath using @. \n\nThe second part of this template selects the date, but performs a XPath string function on it. This means that we only get the date and not the time from the string (line 9). This is achieved by getting only the part of the string that exists before the T. \n\nRegular Expressions are not part of the XPath 1.0 string functions, although XPath 2.0 does include them. Because of this, in XSL we tend to rely heavily on the available XML output. \n\nThe third part of the template (line 12) is a again, but this time we use an attribute of called disable output escaping to turn escaped characters back into XML. \n\nThe very last section is another call, taking us three templates deep. Do not worry, it is not uncommon to write XSL which go 20 or more templates deep!\n\n\n\t\n\t\t\n\t\t\t\n\t\t\t\ttag\n\t\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\t\n\t\t\n\t\t \n\t\n\n\nIn our final , we see a combination of what we have done before with a couple of twists. Once we match atom:category we then count how many elements there are at that same level (line 2). The XPath . means \u2018self\u2019, so we count how many category elements are within the element. \n\nFollowing that, we start to output a link with a rel attribute of the predefined text, tag (lines 4-6). In XSL you can just type text, but results can end up with strange whitespace if you do (although there are ways to simply remove all whitespace). \n\nThe only new XPath function in this example is concat(), which simply combines what XPaths or text there might be in the brackets. We end the output for this tag with an actual tag name (line 10) and we add a space afterwards (line 12) so it won\u2019t touch the next tag. (There are better ways to do this in XSL using the last() XPath function). \n\nAfter that, we go back to the element again if there is another category element, otherwise we end the loop and end this .\n\nA touch of style\n\nBecause we\u2019re using recursion through our templates, you will find this is the end of the templates and the rest of the XML will be ignored by the parser. Finally, we can add our CSS to finish up. (I have created one for Flickr and another for News feeds)\n\n\n\nSo we end up with a nice simple to understand but also quick to write XSL which can be used on ATOM Flickr feeds and ATOM News feeds. With a little playing around with XSL, you can make XML beautiful again.\n\nAll the files can be found in the zip file (14k)", "year": "2006", "author": "Ian Forrester", "author_slug": "ianforrester", "published": "2006-12-07T00:00:00+00:00", "url": "https://24ways.org/2006/beautiful-xml-with-xsl/", "topic": "code"} {"rowid": 135, "title": "A Scripting Carol", "contents": "We all know the stories of the Ghost of Scripting Past \u2013 a time when the web was young and littered with nefarious scripting, designed to bestow ultimate control upon the developer, to pollute markup with event handler after event handler, and to entrench advertising in the minds of all that gazed upon her.\n\nAnd so it came to be that JavaScript became a dirty word, thrown out of solutions by many a Scrooge without regard to the enhancements that JavaScript could bring to any web page. JavaScript, as it was, was dead as a door-nail.\n\nWith the arrival of our core philosophy that all standardistas hold to be true: \u201cseparate your concerns \u2013 content, presentation and behaviour,\u201d we are in a new era of responsible development the Web Standards Way\u2122. Or are we? Have we learned from the Ghosts of Scripting Past? Or are we now faced with new problems that come with new ways of implementing our solutions?\n\nThe Ghost of Scripting Past\n\nIf the Ghost of Scripting Past were with us it would probably say: \n\n\n\tYou must remember your roots and where you came from, and realize the misguided nature of your early attempts for control. That person you see down there, is real and they are the reason you exist in the first place\u2026 without them, you are nothing.\n\n\nIn many ways we\u2019ve moved beyond the era of control and we do take into account the user, or at least much more so than we used to. Sadly \u2013 there is one advantage that old school inline event handlers had where we assigned and reassigned CSS style property values on the fly \u2013 we knew that if JavaScript wasn\u2019t supported, the styles wouldn\u2019t be added because we ended up doing them at the same time.\n\nIf anything, we need to have learned from the past that just because it works for us doesn\u2019t mean it is going to work for anyone else \u2013 we need to test more scenarios than ever to observe the multitude of browsing arrangements we\u2019ll observe: CSS on with JavaScript off, CSS off/overridden with JavaScript on, both on, both off/not supported. It is a situation that is ripe for conflict.\n\nThis may shock some of you, but there was a time when testing was actually easier: back in the day when Netscape 4 was king. Yes, that\u2019s right. I actually kind of enjoyed Netscape 4 (hear me out, please). With NS4\u2019s CSS implementation known as JavaScript Style Sheets, you knew that if JavaScript was off the styles were off too.\n\nThe Ghost of Scripting Present\n\nWith current best practice \u2013 we keep our CSS and JavaScript separate from each other. So what happens when some of our fancy, unobtrusive DOM Scripting doesn\u2019t play nicely with our wonderfully defined style rules?\n\nLets look at one example of a collapsing and expanding menu to illustrate where we are now:\n\nSimple Collapsing/Expanding Menu Example\n\nWe\u2019re using some simple JavaScript (I\u2019m using jquery in this case) to toggle between a CSS state for expanded and not expanded:\n\nJavaScript\n\n$(document).ready(function(){\n\tTWOFOURWAYS.enableTree();\n});\nvar TWOFOURWAYS = new Object();\nTWOFOURWAYS.enableTree = function ()\n{\n\t$(\"ul li a\").toggle(function(){\n\t\t$(this.parentNode).addClass(\"expanded\");\n\t}, function() {\n\t\t$(this.parentNode).removeClass(\"expanded\");\n\t});\n\treturn false;\t\n}\n\nCSS\n\nul li ul {\n\tdisplay: none;\n}\nul li.expanded ul {\n\tdisplay: block;\n}\n\nAt this point we\u2019ve separated our presentation from our content and behaviour, and all is well, right?\n\nNot quite.\n\nHere\u2019s where I typically see failures in the assessment work that I do on web sites and applications (Yes, call me Scrooge \u2013 I don\u2019t care!). We know our page needs to work with or without scripting, and we know it needs to work with or without CSS. All too often the testing scenarios don\u2019t take into account combinations.\n\nTesting it out\n\nSo what happens when we test this? Make sure you test with:\n\n\n\tCSS off\n\tJavaScript off\n\n\nUse the simple example again.\n\nWith CSS off, we revert to a simple nested list of links and all functionality is maintained. With JavaScript off, however, we run into a problem \u2013 we have now removed the ability to expand the menu using the JavaScript triggered CSS change.\n\nHopefully you see the problem \u2013 we have a JavaScript and CSS dependency that is critical to the functionality of the page. Unobtrusive scripting and binary on/off tests aren\u2019t enough. We need more.\n\nThis Ghost of Scripting Present sighting is seen all too often.\n\nLets examine the JavaScript off scenario a bit further \u2013 if we require JavaScript to expand/show the branch of the tree we should use JavaScript to hide them in the first place. That way we guarantee functionality in all scenarios, and have achieved our baseline level of interoperability. \n\nTo revise this then, we\u2019ll start with the sub items expanded, use JavaScript to collapse them, and then use the same JavaScript to expand them.\n\nHTML\n\n\n\nCSS\n\n/* initial style is expanded */\nul li ul.collapseme {\n\tdisplay: block;\n}\n\nJavaScript\n\n// remove the class collapseme after the page loads\n$(\"ul ul.collapseme\").removeClass(\"collapseme\");\n\nAnd there you have it \u2013 a revised example with better interoperability.\n\nThis isn\u2019t rocket surgery by any means. It is a simple solution to a ghostly problem that is too easily overlooked (and often is).\n\nThe Ghost of Scripting Future\n\nWell, I\u2019m not so sure about this one, but I\u2019m guessing that in a few years\u2019 time, we\u2019ll all have seen a few more apparitions and have a few more tales to tell. And hopefully we\u2019ll be able to share them on 24 ways.\n\nThanks to Drew for the invitation to contribute and thanks to everyone else out there for making this a great (and haunting) year on the web!", "year": "2006", "author": "Derek Featherstone", "author_slug": "derekfeatherstone", "published": "2006-12-21T00:00:00+00:00", "url": "https://24ways.org/2006/a-scripting-carol/", "topic": "code"} {"rowid": 134, "title": "Photographic Palettes", "contents": "How many times have you seen a colour combination that just worked, a match so perfect that it just seems obvious? \n\nNow, how many times do you come up with those in your own work? A perfect palette looks easy when it\u2019s done right, but it\u2019s often maddeningly difficult and time-consuming to accomplish.\n\nChoosing effective colour schemes will always be more art than science, but there are things you can do that will make coming up with that oh-so-smooth palette just a little a bit easier. A simple trick that can lead to incredibly gratifying results lies in finding a strong photograph and sampling out particularly harmonious colours.\n\nPhoto Selection\n\nNot all photos are created equal. You certainly want to start with imagery that fits the eventual tone you\u2019re attempting to create. A well-lit photo of flowers might lead to a poor colour scheme for a funeral parlour\u2019s web site, for example. It\u2019s worth thinking about what you\u2019re trying to say in advance, and finding a photo that lends itself to your message.\n\nAs a general rule of thumb, photos that have a lot of neutral or de-saturated tones with one or two strong colours make for the best palette; bright and multi-coloured photos are harder to derive pleasing results from. Let\u2019s start with a relatively neutral image.\n\nSampling\n\n\n\nIn the above example, I\u2019ve surrounded the photo with three different background colours directly sampled from the photo itself. Moving from left to right, you can see how each of the sampled colours is from an area of increasingly smaller coverage within the photo, and yet there\u2019s still a strong harmony between the photo and the background image. I don\u2019t really need to pick the big obvious colours from the photo to create that match, I can easily concentrate on more interesting colours that might work better for what I intend.\n\nUsing a similar palette, let\u2019s apply those colour choices to a more interesting layout:\n\n\n\nIn this mini-layout, I\u2019ve re-used the same tan colour from the previous middle image as a background, and sampled out a nicely matching colour for the top and bottom overlays, as well as the two different text colours. Because these colours all fall within a narrow range, the overall balance is harmonious.\n\nWhat if I want to try something a little more daring? I have a photo of stacked chairs of all different colours, and I\u2019d like to use a few more of those. No problem, provided I watch my colour contrast:\n\n\n\nThough it uses varying shades of red, green, and yellow, this palette actually works because the values are even, and the colours muted. Placing red on top of green is usually a hideous combination of death, but if the green is drab enough and the red contrasts well enough, the result can actually be quite pleasing. I\u2019ve chosen red as my loudest colour in this palette, and left green and yellow to play the quiet supporting roles.\n\nObviously, there are no hard and fast rules here. You might not want to sample absolutely every colour in your scheme from a photo. There are times where you\u2019ll need a variation that\u2019s just a little bit lighter, or a blue that\u2019s not in the photo. You might decide to start from a photo base and tweak, or add in colours of your own. That\u2019s okay too.\n\nTonal Variations\n\nI\u2019ll leave you with a final trick I\u2019ve been using lately, a way to bring a bit more of a formula into the equation and save some steps.\n\n\n\nStarting with the same base palette I sampled from the chairs, in the above image I\u2019ve added a pair of overlaying squares that produce tonal variations of each primary. The lighter variation is simply a solid white square set to 40% opacity, the darker one is a black square at 20%. That gives me a highlight and shadow for each colour, which would prove handy if I had to adapt this colour scheme to a larger layout.\n\nI could add a few more squares of varying opacities, or adjust the layer blending modes for different effects, but as this looks like a great place to end, I\u2019ll leave that up to your experimental whims. Happy colouring!", "year": "2006", "author": "Dave Shea", "author_slug": "daveshea", "published": "2006-12-22T00:00:00+00:00", "url": "https://24ways.org/2006/photographic-palettes/", "topic": "design"} {"rowid": 133, "title": "Gravity-Defying Page Corners", "contents": "While working on Stikkit, a \u201cpage curl\u201d came to be.\nNot being as crafty as Veerle, you see.\nI fired up Photoshop to see what could be.\n\u201cAnother copy is running on the network\u201c \u2026 oopsie.\n\nWith license issues sorted out and a concept in mind\nI set out to create something flexible and refined.\nOne background image and code that is sure to be lean.\nA simple solution for lazy people like me.\n\nThe curl I\u2019ll be showing isn\u2019t a curl at all.\nIt\u2019s simply a gradient that\u2019s 18 pixels tall.\nWith a fade to the left that\u2019s diagonally aligned\nand a small fade on the right that keeps the illusion defined.\n\n\n\nCreate a selection with the marquee tool (keeping in mind a reasonable minimum width) and drag a gradient (black to transparent) from top to bottom.\n\n\n\nNow drag a gradient (the background color of the page to transparent) from the bottom left corner to the top right corner.\n\n\n\nFinally, drag another gradient from the right edge towards the center, about 20 pixels or so.\n\nBut the top is flat and can be positioned precisely\njust under the bottom right edge very nicely.\nAnd there it will sit, never ever to be busted\nby varying sizes of text when adjusted.\n\n
    \n\t
    \n\t\t

    Gravity-Defying!

    \n\t\t

    Lorem ipsum dolor ...

    \n\t
    \n
    \n\nLet\u2019s dive into code and in the markup you\u2019ll see\n\u201cis that an extra div?\u201d \u2026 please don\u2019t kill me?\nThe #page div sets the width and bottom padding\nwhose height is equal to the shadow we\u2019re adding.\n\n\n\nThe #page-contents div will set padding in ems\nto scale with the text size the user intends.\nThe background color will be added here too\nbut not overlapping the shadow where #page\u2019s padding makes room.\n\nA simple technique that you may find amusing\nis to substitute a PNG for the GIF I was using.\nFor that would be crafty and future-proof, too.\nThe page curl could sit on any background hue.\n\nI hope you\u2019ve enjoyed this easy little trick.\nIt\u2019s hardly earth-shattering, and arguably slick.\nBut it could come in handy, you just never know.\nHappy Holidays! And pleasant dreams of web three point oh.", "year": "2006", "author": "Dan Cederholm", "author_slug": "dancederholm", "published": "2006-12-24T00:00:00+00:00", "url": "https://24ways.org/2006/gravity-defying-page-corners/", "topic": "design"} {"rowid": 132, "title": "Tasty Text Trimmer", "contents": "In most cases, when designing a user interface it\u2019s best to make a decision about how data is best displayed and stick with it. Failing to make a decision ultimately leads to too many user options, which in turn can be taxing on the poor old user. \n\nUnder some circumstances, however, it\u2019s good to give the user freedom in customising their workspace. One good example of this is the \u2018Article Length\u2019 tool in Apple\u2019s Safari RSS reader. Sliding a slider left of right dynamically changes the length of each article shown. It\u2019s that kind of awesomey magic stuff that\u2019s enough to keep you from sleeping. Let\u2019s build one.\n\nThe Setup\n\nLet\u2019s take a page that has lots of long text items, a bit like a news page or like Safari\u2019s RSS items view. If we were to attach a class name to each element we wanted to resize, that would give us something to hook onto from the JavaScript. \n\nExample 1: The basic page.\n\nAs you can see, I\u2019ve wrapped my items in a DIV and added a class name of chunk to them. It\u2019s these chunks that we\u2019ll be finding with the JavaScript. Speaking of which \u2026\n\nOur Core Functions\n\nThere are two main tasks that need performing in our script. The first is to find the chunks we\u2019re going to be resizing and store their original contents away somewhere safe. We\u2019ll need this so that if we trim the text down we\u2019ll know what it was if the user decides they want it back again. We\u2019ll call this loadChunks. \n\nvar loadChunks = function(){\n\tvar everything = document.getElementsByTagName('*');\n\tvar i, l;\n\tchunks\t= [];\n\tfor (i=0, l=everything.length; i -1){\n\t\t\tchunks.push({\n\t\t\t\tref: everything[i],\n\t\t\t\toriginal: everything[i].innerHTML\n\t\t\t});\n\t\t}\n\t}\n};\n\nThe variable chunks is stored outside of this function so that we can access it from our next core function, which is doTrim.\n\nvar doTrim = function(interval) {\n\tif (!chunks) loadChunks();\n\tvar i, l;\n\tfor (i=0, l=chunks.length; i Outline Stroke. Select the Rectangle tool and draw 1 big rectangle on top the lines. Give the rectangle a suitable color. With the rectangle still selected, go to the Object menu, select Arrange > Send to Back.\n\nStep 3 \u2013 Convert to Mesh\n\n\n\nSelect all objects by pressing the command key (for Mac users), control key (for Windows users) + the \u201ca\u201d key. Go to the Object menu and select the Envelope Distort > Make with Mesh option. Enter 2 rows and 2 columns. Check the preview box to see what happens and click the OK button.\n\nStep 4 \u2013 Play Around with The Mesh Points \n\n\n\nPlay around with the points of the mesh using the Direct Selection tool (the white arrow in the Toolbox). Click on the top right point of the mesh. Once you\u2019re starting to drag hold down the shift key and move the point upwards. \n\n\n\nNow start dragging the bezier handles on the mesh to achieve the effect as shown in the above picture. Of course you can try out all kind of different effects here. \n\nThe Final Result\n\n\n\nThis is an example of how the final result can look. You can try out all kinds of different shapes dragging the handles of the mesh points. This is just one of the many results you can get. So next time you haven\u2019t got inspiration for a background of a header, a banner or whatever, just experiment with a few basic shapes such as lines and try out the \u2018Envelope Distort\u2019 options in Illustrator or the \u2018Make with Mesh\u2019 option and experiment, you\u2019ll be amazed by the unexpected creative results.", "year": "2006", "author": "Veerle Pieters", "author_slug": "veerlepieters", "published": "2006-12-08T00:00:00+00:00", "url": "https://24ways.org/2006/random-lines-made-with-mesh/", "topic": "design"} {"rowid": 130, "title": "Faster Development with CSS Constants", "contents": "Anyone even slightly familiar with a programming language will have come across the concept of constants \u2013 a fixed value that can be used through your code. For example, in a PHP script I might have a constant which is the email address that all emails generated by my application get sent to. \n\n$adminEmail = 'info@example.com';\n\nI could then use $adminEmail in my script whenever I wanted an email to go to that address. The benefit of this is that when the client decides they want the email to go to a different address, I only need change it in one place \u2013 the place where I initially set the constant. I could also quite easily make this value user defined and enable the administrator to update the email address.\n\nUnfortunately CSS doesn\u2019t support constants. It would be really useful to be able to define certain values initially and then use them throughout a CSS file, so in this article I\u2019m going to take a look at some of the methods we do have available and provide pointers to more in depth commentary on each. If you have a different method, or tip to share please add it to the comments.\n\nSo what options do we have?\n\nOne way to get round the lack of constants is to create some definitions at the top of your CSS file in comments, to define \u2018constants\u2019. A common use for this is to create a \u2018color glossary\u2019. This means that you have a quick reference to the colors used in the site to avoid using alternates by mistake and, if you need to change the colors, you have a quick list to go down and do a search and replace. \n\nIn the below example, if I decide I want to change the mid grey to #999999, all I need to do is search and replace #666666 with #999999 \u2013 assuming I\u2019ve remember to always use that value for things which are mid grey.\n\n/*\nDark grey (text): #333333\nDark Blue (headings, links) #000066\nMid Blue (header) #333399\nLight blue (top navigation) #CCCCFF\nMid grey: #666666\n*/\n\nThis is a fairly low-tech method, but if used throughout the development of the CSS files can make changes far simpler and help to ensure consistency in your color scheme.\n\nI\u2019ve seen this method used by many designers however Garrett Dimon documents the method, with more ideas in the comments.\n\nGoing server-side\n\nTo truly achieve constants you will need to use something other than CSS to process the file before it is sent to the browser. You can use any scripting language \u2013 PHP, ASP, ColdFusion etc. to parse a CSS file in which you have entered constants. So that in a constants section of the CSS file you would have:\n\n$darkgrey = '#333333';\n$darkblue = '#000066';\n\nThe rest of the CSS file is as normal except that when you come to use the constant value you would use the constant name instead of adding the color:\n\np {\n\tcolor: $darkgrey;\n}\n\nYour server-side script could then parse the CSS file, replace the constant names with the constant values and serve a valid CSS file to the browser. Christian Heilmann has done just this for PHP however this could be adapted for any language you might have available on your server.\n\nShaun Inman came up with another way \n of doing this that removes the need to link to a PHP script and also enables the adding of constants using the syntax of at-rules . This method is again using PHP and will require you to edit an .htaccess file. \n\nA further method is to generate static CSS files either using a script locally \u2013 if the constants are just to enable speed of development \u2013 or as part of the web application itself. Storing a template stylesheet with constant names in place of the values you will want to update means that your script can simply open the template, replace the variables and save the result as a new stylesheet file.\n\nWhile CSS constants are a real help to developers, they can also be used to add new functionality to your applications. As with the email address example that I used at the beginning of this article, using a combination of CSS and server-side scripting you could enable a site administrator to select the colours for a new theme to be used on a page of a content managed site. By using constants you need only give them the option to change certain parts of the CSS and not upload a whole different CSS file, which could lead to some interesting results!\n\nAs we are unlikely to find real CSS constants under the tree this Christmas the above methods are some possibilities for better management of your stylesheets. However if you have better methods, CSS Constant horror stories or any other suggestions, add your comments below.", "year": "2006", "author": "Rachel Andrew", "author_slug": "rachelandrew", "published": "2006-12-02T00:00:00+00:00", "url": "https://24ways.org/2006/faster-development-with-css-constants/", "topic": "process"} {"rowid": 129, "title": "Knockout Type - Thin Is Always In", "contents": "OS X has gorgeous native anti-aliasing (although I will admit to missing 10px aliased Geneva \u2014 *sigh*). This is especially true for dark text on a light background. However, things can go awry when you start using light text on a dark background. Strokes thicken. Counters constrict. Letterforms fill out like seasonal snackers.\n\n \n\nSo how do we combat the fat? In Safari and other Webkit-based browsers we can use the CSS \u2018text-shadow\u2019 property. While trying to add a touch more contrast to the navigation on haveamint.com I noticed an interesting side-effect on the weight of the type. \n\n\n\nThe second line in the example image above has the following style applied to it:\n\n \n\nThis creates an invisible drop-shadow. (Why is it invisible? The shadow is positioned directly behind the type (the first two zeros) and has no spread (the third zero). So the color, black, is completely eclipsed by the type it is supposed to be shadowing.)\n\n \n\nWhy applying an invisible drop-shadow effectively lightens the weight of the type is unclear. What is clear is that our light-on-dark text is now of a comparable weight to its dark-on-light counterpart.\n\n \n\nYou can see this trick in effect all over ShaunInman.com and in the navigation on haveamint.com and Subtraction.com. The HTML and CSS source code used to create the example images used in this article can be found here.", "year": "2006", "author": "Shaun Inman", "author_slug": "shauninman", "published": "2006-12-17T00:00:00+00:00", "url": "https://24ways.org/2006/knockout-type/", "topic": "code"} {"rowid": 128, "title": "Boost Your Hyperlink Power", "contents": "There are HTML elements and attributes that we use every day. Headings, paragraphs, lists and images are the mainstay of every Web developer\u2019s toolbox. Perhaps the most common tool of all is the anchor. The humble a element is what joins documents together to create the gloriously chaotic collection we call the World Wide Web.\n\nAnatomy of an Anchor\n\nThe power of the anchor element lies in the href attribute, short for hypertext reference. This creates a one-way link to another resource, usually another page on the Web:\n\n\n\nThe href attribute sits in the opening a tag and some descriptive text sits between the opening and closing tags:\n\nDrew McLellan\n\n\u201cWhoop-dee-freakin\u2019-doo,\u201d I hear you say, \u201cthis is pretty basic stuff\u201d \u2013 and you\u2019re quite right. But there\u2019s more to the anchor element than just the href attribute.\n\nThe Theory of relativity\n\nYou might be familiar with the rel attribute from the link element. I bet you\u2019ve got something like this in the head of your documents:\n\n\n\nThe rel attribute describes the relationship between the linked document and the current document. In this case, the value of rel is \u201cstylesheet\u201d. This means that the linked document is the stylesheet for the current document: that\u2019s its relationship.\n\nHere\u2019s another common use of rel:\n\n\n\nThis describes the relationship of the linked file \u2013 an RSS feed \u2013 as \u201calternate\u201d: an alternate view of the current document.\n\nBoth of those examples use the link element but you are free to use the rel attribute in regular hyperlinks. Suppose you\u2019re linking to your RSS feed in the body of your page:\n\nSubscribe to my RSS feed.\n\nYou can add extra information to this anchor using the rel attribute:\n\nSubscribe to my RSS feed.\n\nThere\u2019s no prescribed list of values for the rel attribute so you can use whatever you decide is semantically meaningful. Let\u2019s say you\u2019ve got a complex e-commerce application that includes a link to a help file. You can explicitly declare the relationship of the linked file as being \u201chelp\u201d:\n\nneed help?\n\nElemental Microformats\n\nAlthough it\u2019s completely up to you what values you use for the rel attribute, some consensus is emerging in the form of microformats. Some of the simplest microformats make good use of rel. For example, if you are linking to a license that covers the current document, use the rel-license microformat:\n\nLicensed under a Creative Commons attribution license\n\nThat describes the relationship of the linked document as \u201clicense.\u201d\n\nThe rel-tag microformat goes a little further. It uses rel to describe the final part of the URL of the linked file as a \u201ctag\u201d for the current document:\n\nLearn more about semantic markup\n\nThis states that the current document is being tagged with the value \u201cMicroformats.\u201d\n\nXFN, which stands for XHTML Friends Network, is a way of describing relationships between people:\n\nDrew McLellan\n\nThis microformat makes use of a very powerful property of the rel attribute. Like the class attribute, rel can take multiple values, separated by spaces:\n\nDrew McLellan\n\nHere I\u2019m describing Drew as being a friend, someone I\u2019ve met, and a colleague (because we\u2019re both Web monkies).\n\nYou Say You Want a revolution\n\nWhile rel describes the relationship of the linked resource to the current document, the rev attribute describes the reverse relationship: it describes the relationship of the current document to the linked resource. Here\u2019s an example of a link that might appear on help.html:\n\ncontinue shopping\n\nThe rev attribute declares that the current document is \u201chelp\u201d for the linked file.\n\nThe vote-links microformat makes use of the rev attribute to allow you to qualify your links. By using the value \u201cvote-for\u201d you can describe your document as being an endorsement of the linked resource:\n\nI agree with Richard Dawkins.\n\nThere\u2019s a corresponding vote-against value. This means that you can link to a document but explicitly state that you don\u2019t agree with it.\n\nI agree with Richard Dawkins\nabout those creationists. \n\nOf course there\u2019s nothing to stop you using both rel and rev on the same hyperlink:\n\nRichard Dawkins\n\nThe Wisdom of Crowds\n\nThe simplicity of rel and rev belies their power. They allow you to easily add extra semantic richness to your hyperlinks. This creates a bounty that can be harvested by search engines, aggregators and browsers. Make it your New Year\u2019s resolution to make friends with these attributes and extend the power of hypertext.", "year": "2006", "author": "Jeremy Keith", "author_slug": "jeremykeith", "published": "2006-12-18T00:00:00+00:00", "url": "https://24ways.org/2006/boost-your-hyperlink-power/", "topic": "code"} {"rowid": 127, "title": "Showing Good Form", "contents": "Earlier this year, I forget exactly when (it\u2019s been a good year), I was building a client site that needed widgets which look like this (designed, incidentally, by my erstwhile writing partner, Cameron Adams):\n\n\n\nBuilding this was a challenge not just in CSS, but in choosing the proper markup \u2013 how should such a widget be constructed?\n\nMmm \u2026 markup\n\nIt seemed to me there were two key issues to deal with:\n\n\n\tThe function of the interface is to input information, so semantically this is a form, therefore we have to find a way of building it using form elements: fieldset, legend, label and input\n\tWe can\u2019t use a table for layout, even though that would clearly be the easiest solution!\n\n\nAbusing tables for layout is never good \u2013 physical layout is not what table semantics mean. But even if this data can be described as a table, we shouldn\u2019t mix forms markup with non-forms markup, because of the behavioral impact this can have on a screen reader:\n\nTo take a prominent example, the screen reader JAWS has a mode specifically for interacting with forms (cunningly known as \u201cforms mode\u201d). When running in this mode its output only includes relevant elements \u2013 legends, labels and form controls themselves. Any other kind of markup \u2013 like text in a previous table cell, a paragraph or list in between \u2013 is simply ignored. The user in this situation would have to switch continually in and out of forms mode to hear all the content. (For more about this issue and some test examples, there\u2019s a thread at accessify forum which wanders in that direction.)\n\nOne further issue for screen reader users is implied by the design: the input fields are associated together in rows and columns, and a sighted user can visually scan across and down to make those associations; but a blind user can\u2019t do that. For such a user the row and column header data will need to be there at every axis; in other words, the layout should be more like this:\n\n\n\nAnd constructed with appropriate semantic markup to convey those relationships. By this point the selection of elements seems pretty clear: each row is a fieldset, the row header is a legend, and each column header is a label, associated with an input.\n\nHere\u2019s what that form looks like with no CSS:\n\n\n\nAnd here\u2019s some markup for the first row (with most of the attributes removed just to keep this example succinct):\n\n
    \n\t\n\t\tMatch points\n\t\n\t\n\t\n\t\n\t\n
    \n\nThe span inside each legend is because legend elements are highly resistant to styling! Indeed they\u2019re one of the most stubborn elements in the browsers\u2019 vocabulary. Oh man \u2026 how I wrestled with the buggers \u2026 until this obvious alternative occurred to me! So the legend element itself is just a container, while all the styling is on the inner span.\n\nOh yeah, there was some CSS too\n\nI\u2019m not gonna dwell too much on the CSS it took to make this work \u2013 this is a short article, and it\u2019s all there in the demo [demo page, style sheet]\n\nBut I do want to touch on the most interesting bit \u2013 where we get from a layout with headers on every row, to one where only the top row has headers \u2013 or at least, so it appears to graphical browsers. For screen readers, as we noted, we need those headers on every row, so we should employ some cunning CSS to partly negate their visual presence, without removing them from the output.\n\nThe core styling for each label span is like this:\n\nlabel span\n{\n\tdisplay:block;\n\tpadding:5px;\n\tline-height:1em;\n\tbackground:#423221;\n\tcolor:#fff;\n\tfont-weight:bold;\n}\n\nBut in the rows below the header they have these additional rules:\n\nfieldset.body label span\n{\n\tpadding:0 5px;\n\tline-height:0;\n\tposition:relative;\n\ttop:-10000em;\n}\n\nThe rendered width of the element is preserved, ensuring that the surrounding label is still the same width as the one in the header row above, and hence a unified column width is preserved all the way down. But the element effectively has no height, and so it\u2019s effectively invisible. The styling is done this way, rather than just setting the height to zero and using overflow:hidden, because to do that would expose an unrelated quirk with another popular screen reader! (It would hide the output from Window Eyes, as shown in this test example at access matters.)\n\nThe finished widget\n\nIt\u2019s an intricate beast allright! But after all that we do indeed get the widget we want:\n\n\n\tDemo page\n\tStyle sheet\n\n\nIt\u2019s not perfect, most notably because the legends have to have a fixed width; this can be in em to allow for text scaling, but it still doesn\u2019t allow the content to break into multiple lines. It also doesn\u2019t look quite right in Safari; and some CSS hacking was needed to make it look right in IE6 and IE7.\n\nStill it worked well enough for the purpose, and satisfied the client completely. And most of all it re-assured me in my faith \u2013 that there\u2019s never any need to abuse tables for layout. (Unless of course you think this content is a table anyway, but that\u2019s another story!)", "year": "2006", "author": "James Edwards", "author_slug": "jamesedwards", "published": "2006-12-11T00:00:00+00:00", "url": "https://24ways.org/2006/showing-good-form/", "topic": "ux"} {"rowid": 126, "title": "Intricate Fluid Layouts in Three Easy Steps", "contents": "The Year of the Script may have drawn attention away from CSS but building fluid, multi-column, cross-browser CSS layouts can still be as unpleasant as a lump of coal. Read on for a worry-free approach in three quick steps.\n\nThe layout system I developed, YUI Grids CSS, has three components. They can be used together as we\u2019ll see, or independently.\n\nThe Three Easy Steps\n\n\n\tChoose fluid or fixed layout, and choose the width (in percents or pixels) of the page.\n\tChoose the size, orientation, and source-order of the main and secondary blocks of content.\n\tChoose the number of columns and how they distribute (for example 50%-50% or 25%-75%), using stackable and nestable grid structures.\n\n\nThe Setup\n\nThere are two prerequisites: We need to normalize the size of an em and opt into the browser rendering engine\u2019s Strict Mode.\n\nEms are a superior unit of measure for our case because they represent the current font size and grow as the user increases their font size setting. This flexibility\u2014the container growing with the user\u2019s wishes\u2014means larger text doesn\u2019t get crammed into an unresponsive container. We\u2019ll use YUI Fonts CSS to set the base size because it provides consistent-yet-adaptive font-sizes while preserving user control.\n\nThe second prerequisite is to opt into Strict Mode (more info on rendering modes) by declaring a Doctype complete with URI. You can choose XHTML or HTML, and Transitional or Strict. I prefer HTML 4.01 Strict, which looks like this:\n\n\n\nIncluding the CSS\n\nA single small CSS file powers a nearly-infinite number of layouts thanks to a recursive system and the interplay between the three distinct components. You could prune to a particular layout\u2019s specific needs, but why bother when the complete file weighs scarcely 1.8kb uncompressed? Compressed, YUI Fonts and YUI Grids combine for a miniscule 0.9kb over the wire.\n\nYou could save an HTTP request by concatenating the two CSS files, or by adding their contents to your own CSS, but I\u2019ll keep them separate for now:\n\n\n\n\nExample: The Setup\n\nNow we\u2019re ready to build some layouts.\n\nStep 1: Choose Fluid or Fixed Layout\n\nChoose between preset widths of 750px, 950px, and 100% by giving a document-wrapping div an ID of doc, doc2, or doc3. These options cover most use cases, but it\u2019s easy to define a custom fixed width.\n\nThe fluid 100% grid (doc3) is what I\u2019ve been using almost exclusively since it was introduced in the last YUI released.\n\n\n\t
    \n\n\nAll pages are centered within the viewport, and grow with font size. The 100% width page (doc3) preserves 10px of breathing room via left and right margins. If you prefer your content flush to the viewport, just add doc3 {margin:auto} to your CSS.\n\nRegardless of what you choose in the other two steps, you can always toggle between these widths and behaviors by simply swapping the ID value. It\u2019s really that simple.\n\nExample: 100% fluid layout\n\nStep 2: Choose a Template Preset\n\nThis is perhaps the most frequently omitted step (they\u2019re all optional), but I use it nearly every time. In a source-order-independent way (good for accessibility and SEO), \u201cTemplate Presets\u201d provide commonly used template widths compatible with ad-unit dimension standards defined by the Interactive Advertising Bureau, an industry association.\n\nChoose between the six Template Presets (.yui-t1 through .yui-t6) by setting the class value on the document-wrapping div established in Step 1. Most frequently I use yui-t3, which puts the narrow secondary block on the left and makes it 300px wide. \n\n\n\t
    \n\n\nThe Template Presets control two \u201cblocks\u201d of content, which are defined by two divs, each with yui-b (\u201cb\u201d for \u201cblock\u201d) class values. Template Presets describe the width and orientation of the secondary block; the main block will take up the rest of the space.\n\n\n\t
    \n\t
    \n\t
    \n\t
    \n\n\nUse a wrapping div with an ID of yui-main to structurally indicate which block is the main block. This wrapper\u2014not the source order\u2014identifies the main block.\n\n\n\t
    \n\t
    \n\t
    \n\t
    \n\t
    \n\t
    \n\n\nExample: Main and secondary blocks sized and oriented with .yui-t3 Template Preset\n\nAgain, regardless of what values you choose in the other steps, you can always toggle between these Template Presets by toggling the class value of your document-wrapping div. It\u2019s really that simple.\n\nStep 3: Nest and Stack Grid Structures.\n\nThe bulk of the power of the system is in this third step. The key is that columns are built by parents telling children how to behave. By default, two children each consume half of their parent\u2019s area. Put two units inside a grid structure, and they will sit side-by-side, and they will each take up half the space. Nest this structure and two columns become four. Stack them for rows of columns.\n\nAn Even Number of Columns\n\nThe default behavior creates two evenly-distributed columns. It\u2019s easy. Define one parent grid with .yui-g (\u201cg\u201d for grid) and two child units with .yui-u (\u201cu\u201d for unit). The code looks like this:\n\n
    \n\t
    \n\t
    \n
    \n\nBe sure to indicate the \u201cfirst\u201c unit because the :first-child pseudo-class selector isn\u2019t supported across all A-grade browsers. It\u2019s unfortunate we need to add this, but luckily it\u2019s not out of place in the markup layer since it is structural information.\n\nExample: Two evenly-distributed columns in the main content block\n\nAn Odd Number of Columns\n\nThe default system does not work for an odd number of columns without using the included \u201cSpecial Grids\u201d classes. To create three evenly distributed columns, use the \u201cyui-gb\u201c Special Grid:\n\n
    \n\t
    \n\t
    \n\t
    \n
    \n\nExample: Three evenly distributed columns in the main content block\n\nUneven Column Distribution\n\nSpecial Grids are also used for unevenly distributed column widths. For example, .yui-ge tells the first unit (column) to take up 75% of the parent\u2019s space and the other unit to take just 25%.\n\n
    \n\t
    \n\t
    \n
    \n\nExample: Two columns in the main content block split 75%-25%\n\nPutting It All Together\n\nStart with a full-width fluid page (div#doc3). Make the secondary block 180px wide on the right (div.yui-t4). Create three rows of columns: Three evenly distributed columns in the first row (div.yui-gb), two uneven columns (66%-33%) in the second row (div.yui-gc), and two evenly distributed columns in the thrid row.\n\n\n\t\n\t
    \n\t\t\n\t\t
    \n\t\t\t
    \n\t\t\t\t\n\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\n\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t\t
    \n\t\t\t\t
    \n\t\t\t\t\n\t\t\t\t
    \n\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\t\n\t\t
    \n\t
    \n\n\nExample: A complex layout.\n\nWasn\u2019t that easy? Now that you know the three \u201clevers\u201d of YUI Grids CSS, you\u2019ll be creating headache-free fluid layouts faster than you can say \u201cPeace on Earth\u201d.", "year": "2006", "author": "Nate Koechley", "author_slug": "natekoechley", "published": "2006-12-20T00:00:00+00:00", "url": "https://24ways.org/2006/intricate-fluid-layouts/", "topic": "code"} {"rowid": 125, "title": "Accessible Dynamic Links", "contents": "Although hyperlinks are the soul of the World Wide Web, it\u2019s worth using them in moderation. Too many links becomes a barrier for visitors navigating their way through a page. This difficulty is multiplied when the visitor is using assistive technology, or is using a keyboard; being able to skip over a block of links doesn\u2019t make the task of finding a specific link any easier.\n\nIn an effort to make sites easier to use, various user interfaces based on the hiding and showing of links have been crafted. From drop-down menus to expose the deeper structure of a website, to a decluttering of skip links so as not to impact design considerations. Both are well intentioned with the aim of preserving a good usability experience for the majority of a website\u2019s audience; hiding the real complexity of a page until the visitor interacts with the element.\n\nWhen JavaScript is not available\n\nThe modern dynamic link techniques rely on JavaScript and CSS, but regardless of whether scripting and styles are enabled or not, we should consider the accessibility implications, particularly for screen-reader users, and people who rely on keyboard access.\n\nIn typical web standards-based drop-down navigation implementations, the rough consensus is that the navigation should be structured as nested lists so when JavaScript is not available the entire navigation map is available to the visitor. This creates a situation where a visitor is faced with potentially well over 50 links on every page of the website. Keyboard access to such structures is frustrating, there\u2019s far too many options, and the method of serially tabbing through each link looking for a specific one is tedious.\n\nInstead of offering the visitor an indigestible chunk of links when JavaScript is not available, consider instead having the minimum number of links on a page, and when JavaScript is available bringing in the extra links dynamically. Santa Chris Heilmann offers an excellent proof of concept in making Ajax navigation optional.\n\nWhen JavaScript is enabled, we need to decide how to hide links. One technique offers a means of comprehensively hiding links from keyboard users and assistive technology users. Another technique allows keyboard and screen-reader users to access links while they are hidden, and making them visible when reached.\n\nHiding the links\n\nIn JavaScript enhanced pages whether a link displays on screen depends on a certain event happening first. For example, a visitor needs to click a top-level navigation link that makes a set of sub-navigation links appear. In these cases, we need to ensure that these links are not available to any user until that event has happened.\n\nThe typical way of hiding links is to style the anchor elements, or its parent nodes with display: none. This has the advantage of taking the links out of the tab order, so they are not focusable. It\u2019s useful in reducing the number of links presented to a screen-reader or keyboard user to a minimum. Although the links are still in the document (they can be referenced and manipulated using DOM Scripting), they are not directly triggerable by a visitor.\n\nOnce the necessary event has happened, like our visitor has clicked on a top-level navigation link which shows our hidden set of links, then we can display the links to the visitor and make them triggerable. This is done simply by undoing the display: none, perhaps by setting the display back to block for block level elements, or inline for inline elements. For as long as this display style remains, the links are in the tab order, focusable by keyboard, and triggerable.\n\nA common mistake in this situation is to use visibility: hidden, text-indent: -999em, or position: absolute with left: -999em to position these links off-screen. But all of these links remain accessible via keyboard tabbing even though the links remain hidden from screen view. In some ways this is a good idea, but for hiding sub-navigation links, it presents the screen-reader user and keyboard user with too many links to be of practical use.\n\nMoving the links out of sight\n\nIf you want a set of text links accessible to screen-readers and keyboard users, but don\u2019t want them cluttering up space on the screen, then style the links with position: absolute; left: -999em. Links styled this way remain in the tab order, and are accessible via keyboard. (The position: absolute is added as a style to the link, not to a parent node of the link \u2013 this will give us a useful hook to solve the next problem).\n\na.helper {\n\tposition: absolute;\n\tleft: -999em;\n}\n\nOne important requirement when displaying links off-screen is that they are visible to a keyboard user when they receive focus. Tabbing on a link that is not visible is a usability mudpit, since the visitor has no visible cue as to what a focused link will do, or where it will go.\n\nThe simple answer is to restyle the link so that it appears on the screen when the hidden link receives focus. The anchor\u2019s :focus pseudo-class is a logical hook to use, and with the following style repositions the link onscreen when it receives the focus:\n\na.helper:focus, a.helper.focus {\n\ttop: 0;\n\tleft: 0;\n}\n\nThis technique is useful for hiding skip links, and options you want screen-reader and keyboard users to use, but don\u2019t want cluttering up the page. Unfortunately Internet Explorer 6 and 7 don\u2019t support the focus pseudo-class, which is why there\u2019s a second CSS selector a.helper.focus so we can use some JavaScript to help out. When the page loads, we look for all links that have a class of helper and add in onfocus and onblur event handlers:\n\nif (anchor.className == \"helper\") {\n\tanchor.onfocus = function() {\n\t\tthis.className = 'helper focus';\n\t}\n\tanchor.onblur = function() {\n\t\tthis.className = 'helper';\n\t}\n}\n\nSince we are using JavaScript to cover up for deficiencies in Internet Explorer, it makes sense to use JavaScript initially to place the links off-screen. That way an Internet Explorer user with JavaScript disabled can still use the skip link functionality.\n\nIt is vital that the number of links rendered in this way is kept to a minimum. Every link you offer needs to be tabbed through, and gets read out in a screen reader. Offer these off-screen links that directly benefit these types of visitor.\n\nAndy Clarke and Kimberly Blessing use a similar technique in the Web Standards Project\u2018s latest design, but their technique involves hiding the skip link in plain sight and making it visible when it receives focus. Navigate the page using just the tab key to see the accessibility-related links appear when they receive focus.\n\nThis technique is also a good way of hiding image replaced text. That way the screen-readers still get the actual text, and the website still gets its designed look.\n\nWhich way?\n\nIf the links are not meant to be reachable until a certain event has occurred, then the display: none technique is the preferred approach. If you want the links accessible but out of the way until they receive focus, then the off-screen positioning (or Andy\u2019s hiding in plain sight technique) is the way to go.", "year": "2006", "author": "Mike Davies", "author_slug": "mikedavies", "published": "2006-12-05T00:00:00+00:00", "url": "https://24ways.org/2006/accessible-dynamic-links/", "topic": "ux"} {"rowid": 124, "title": "Writing Responsible JavaScript", "contents": "Without a doubt, JavaScript has been making something of a comeback in the last year. If you\u2019re involved in client-side development in any way at all, chances are that you\u2019re finding yourself writing more JavaScript now than you have in a long time.\n\nIf you learned most of your JavaScript back when DHTML was all the rage and before DOM Scripting was in vogue, there have been some big shifts in the way scripts are written. Most of these are in the way event handlers are assigned and functions declared. Both of these changes are driven by the desire to write scripts that are responsible page citizens, both in not tying behaviour to content and in taking care not to conflict with other scripts. I thought it may be useful to look at some of these more responsible approaches to learn how to best write scripts that are independent of the page content and are safely portable between different applications.\n\nEvent Handling\n\nBack in the heady days of Web 1.0, if you wanted to have an object on the page react to something like a click, you would simply go ahead and attach an onclick attribute. This was easy and understandable, but much like the font tag or the style attribute, it has the downside of mixing behaviour or presentation in with our content. As we\u2019re learned with CSS, there are big benefits in keeping those layers separate. Hey, if it works for CSS, it should work for JavaScript too.\n\nJust like with CSS, instead of adding an attribute to our element within the document, the more responsible way to do that is to look for the item from your script (like CSS does with a selector) and then assign the behaviour to it. To give an example, take this oldskool onclick use case:\n\nPlay the animation\n\nThis could be rewritten by removing the onclick attribute, and instead doing the following from within your JavaScript.\n\ndocument.getElementById('anim-link').onclick = playAnimation;\n\nIt\u2019s all in the timing\n\nOf course, it\u2019s never quite that easy. To be able to attach that onclick, the element you\u2019re targeting has to exist in the page, and the page has to have finished loading for the DOM to be available. This is where the onload event is handy, as it fires once everything has finished loading. Common practise is to have a function called something like init() (short for initialise) that sets up all these event handlers as soon as the page is ready.\n\nBack in the day we would have used the onload attibute on the element to do this, but of course what we really want is:\n\nwindow.onload = init;\n\nAs an interesting side note, we\u2019re using init here rather than init() so that the function is assigned to the event. If we used the parentheses, the init function would have been run at that moment, and the result of running the function (rather than the function itself) would be assigned to the event. Subtle, but important.\n\nAs is becoming apparent, nothing is ever simple, and we can\u2019t just go around assigning our initialisation function to window.onload. What if we\u2019re using other scripts in the page that might also want to listen out for that event? Whichever script got there last would overwrite everything that came before it. To manage this, we need a script that checks for any existing event handlers, and adds the new handler to it. Most of the JavaScript libraries have their own systems for doing this. If you\u2019re not using a library, Simon Willison has a good stand-alone example\n\nfunction addLoadEvent(func) {\n\tvar oldonload = window.onload;\n\tif (typeof window.onload != 'function') {\n\t\twindow.onload = func;\n\t} else {\n\t\twindow.onload = function() {\n\t\t\tif (oldonload) {\n\t\t\t\toldonload();\n\t\t\t}\n\t\t\tfunc();\n\t\t}\n\t}\n}\n\nObviously this is just a toe in the events model\u2019s complex waters. Some good further reading is PPK\u2019s Introduction to Events.\n\nCarving out your own space\n\nAnother problem that rears its ugly head when combining multiple scripts on a single page is that of making sure that the scripts don\u2019t conflict. One big part of that is ensuring that no two scripts are trying to create functions or variables with the same names. Reusing a name in JavaScript just over-writes whatever was there before it.\n\nWhen you create a function in JavaScript, you\u2019ll be familiar with doing something like this.\n\nfunction foo() {\n\t... goodness ...\n}\n\nThis is actually just creating a variable called foo and assigning a function to it. It\u2019s essentially the same as the following.\n\nvar foo = function() {\n\t... goodness ...\n}\n\nThis name foo is by default created in what\u2019s known as the \u2018global namespace\u2019 \u2013 the general pool of variables within the page. You can quickly see that if two scripts use foo as a name, they will conflict because they\u2019re both creating those variables in the global namespace.\n\nA good solution to this problem is to add just one name into the global namespace, make that one item either a function or an object, and then add everything else you need inside that. This takes advantage of JavaScript\u2019s variable scoping to contain you mess and stop it interfering with anyone else.\n\nCreating An Object\n\nSay I was wanting to write a bunch of functions specifically for using on a site called \u2018Foo Online\u2019. I\u2019d want to create my own object with a name I think is likely to be unique to me.\n\nvar FOOONLINE = {};\n\nWe can then start assigning functions are variables to it like so:\n\nFOOONLINE.message = 'Merry Christmas!';\nFOOONLINE.showMessage = function() {\n\talert(this.message);\n};\n\nCalling FOOONLINE.showMessage() in this example would alert out our seasonal greeting. The exact same thing could also be expressed in the following way, using the object literal syntax.\n\nvar FOOONLINE = {\n\tmessage: 'Merry Christmas!',\n\tshowMessage: function() {\n\t\talert(this.message);\n\t}\n};\n\nCreating A Function to Create An Object\n\nWe can extend this idea bit further by using a function that we run in place to return an object. The end result is the same, but this time we can use closures to give us something like private methods and properties of our object.\n\nvar FOOONLINE = function(){\n\tvar message = 'Merry Christmas!';\n\treturn {\n\t\tshowMessage: function(){\n\t\t\talert(message);\n\t\t}\n\t}\n}();\n\nThere are two important things to note here. The first is the parentheses at the end of line 10. Just as we saw earlier, this runs the function in place and causes its result to be assigned. In this case the result of our function is the object that is returned at line 4.\n\nThe second important thing to note is the use of the var keyword on line 2. This ensures that the message variable is created inside the scope of the function and not in the global namespace. Because of the way closure works (which if you\u2019re not familiar with, just suspend your disbelief for a moment) that message variable is visible to everything inside the function but not outside. Trying to read FOOONLINE.message from the page would return undefined.\n\nThis is useful for simulating the concept of private class methods and properties that exist in other programming languages. I like to take the approach of making everything private unless I know it\u2019s going to be needed from outside, as it makes the interface into your code a lot clearer for someone else to read. \n\nAll Change, Please\n\nSo that was just a whistle-stop tour of a couple of the bigger changes that can help to make your scripts better page citizens. I hope it makes useful Sunday reading, but obviously this is only the tip of the iceberg when it comes to designing modular, reusable code.\n\nFor some, this is all familiar ground already. If that\u2019s the case, I encourage you to perhaps submit a comment with any useful resources you\u2019ve found that might help others get up to speed. Ultimately it\u2019s in all of our interests to make sure that all our JavaScript interoperates well \u2013 share your tips.", "year": "2006", "author": "Drew McLellan", "author_slug": "drewmclellan", "published": "2006-12-10T00:00:00+00:00", "url": "https://24ways.org/2006/writing-responsible-javascript/", "topic": "code"} {"rowid": 123, "title": "Fast and Simple Usability Testing", "contents": "Everyone knows by now that they should test the usability of their applications, but still hardly anybody actually does it. In this article I\u2019ll share some tips I\u2019ve picked up for doing usability tests quickly and effectively.\n\nRelatively recent tools like Django and Ruby on Rails allow us to develop projects faster and to make significant changes later in the project timeline. Usability testing methods should now be adapted to fit this modern approach to development.\n\nWhen to test\n\nIn an ideal world usability tests would be carried out frequently from an early stage of the project. Time and budget constraints lead this to be impractical; usability is often the first thing to get dropped from the project plan.\n\nIf you can only test at one stage in the project, whatever the size, the most valuable time is before your first public beta \u2014 leaving long enough to fix issues and not so late that you can\u2019t rethink your scope.\n\nThere are three main categories of usability test:\n\n\n\tTesting design mockups\n\tTesting a new working application\n\tTesting established applications\n\n\nEach category requires a slightly different approach. For small modern web projects you are most likely to be testing a new working application. You will of course have already done functional tests so you won\u2019t be worried about the user breaking things. The main differences between the categories apply in how you word The Script.\n\nTesting an established application is the most fun in my opinion. Humans are remarkably adaptable and rapidly develop coping strategies to work around usability issues in software they are forced to use. Uncovering these strategies may lead you to understand previously unspoken needs of your users. Often small changes to the application will have a dramatic affect on their everyday lives.\n\nWho to test\n\nWhen you have built a project to scratch your own itch, your intended audience will be people just like you. Test subjects in this case should be easy to find \u2013 friends, co-workers etc.\n\nThis is not always the case; your users may not be like you at all. When they are not, it\u2019s all the more important to run usability tests. Testing on friends, family and co-workers is better than not doing usability tests at all, but it can\u2019t be compared to testing on actual samples of your intended audience. People who would use the system will provide more genuine feedback and deeper insight.\n\nNever let your test subjects put themselves in the shoes of your \u2018actual\u2019 users. For example, you should discourage comments like \u201cWell, I would do this BUT if I was a bus driver I\u2019d do that\u201d. Users are not qualified to put themselves in the position of others. Inaccurate data is often worse than no data.\n\nAim for five or six test subjects: any more and you probably won\u2019t learn anything new; any less and you\u2019re likely to be overwhelmed by issues stemming from people\u2019s individual personalities.\n\nThe Script\n\nThe Script is a single side of A4 (or letter) paper, consisting of questions for your testers and reminders for yourself. Have a balance of task-based questions and expectation analysis. This helps maintain consistency across tests. Expectation analysis is more important for testing designs and new applications: \u201cWhere would you find X?\u201d, \u201cWhat would you expect to happen if you clicked on Y?\u201d. In an established system users will probably know where these things are though it can still be illuminating to ask these questions though phrased slightly differently.\n\nTask-based questions involve providing a task for the user to complete. If you are testing an established system it is a good idea to ask users to bring in tasks that they would normally perform. This is because the user will be more invested in the outcome of the task and will behave in a more realistic fashion. When designing tasks for new systems and designs ensure you only provide loose task details for the same reason. Don\u2019t tell testers to enter \u201cChantelle\u201d; have them use their own name instead. Avoid introducing bias with the way questions are phrased.\n\nIt\u2019s a good idea to ask for users\u2019 first impressions at the beginning of the test, especially when testing design mockups. \u201cWhat are the main elements on the page?\u201d or \u201cWhat strikes you first?\u201d.\n\nYou script should run for a maximum of 45 minutes. 30-35 minutes is better; after this you are likely to lose their attention. Tests on established systems can take longer as there is more to learn from them. When scheduling the test you will need to leave yourself 5 minutes between each one to collate your notes and prepare for the next. Be sure to run through the script beforehand.\n\nYour script should be flexible. It is possible that during the test a trend will come to light that opens up whole new avenues of possible questioning. For example, during one initial test of an established system I noticed that the test subject had been printing off items from the application and placing them in a folder in date order (the system ordered alphabetically). I changed the script to ask future participants in that run, if they ever used external tools to help them with tasks within the system. This revealed a number of interesting issues that otherwise would not have been found.\n\nRunning the tests\n\nTreat your test subjects like hedgehogs. Depending on your target audience they probably feel a little nervous and perhaps even scared of you. So make them a little nest out of straw, stroke their prickles and give them some cat food. Alternatively, reassure them that you are testing the system and that they can\u2019t give a wrong answer. Reward them with a doughnut or jam tart at the end. Try to ensure the test environment is relaxed and quiet, but also as close as possible to the situation where they would actually use the system.\n\nHave your subjects talk out loud is very important as you can\u2019t read their minds, but it is a very unnatural process. To loosen up your subjects and get them talking in the way you want them to, try the Stapler Trick. Give them a stapler or similar item and ask them to open it, take the staples out, replace them, shut the stapler and staple some paper \u2013 talking all the time about what they see, what they expect to happen, what actually happens and how that matches up. Make them laugh at you.\n\nSay how long the test will take up front, and tell your subject why you are doing it. After the test has been completed, conclude by thanking them for their time and assuring them that they were very useful. Then give them the sugary treat.\n\nWhat to look for\n\nPrimarily, you should look out for incidents where the user stops concentrating on her tasks and starts thinking about the tool and how she is going to use it. For example, when you are hammering in a nail you don\u2019t think about how to use a hammer; good software should be the same. Words like \u2018it\u2019 and \u2018the system\u2019 and are good indications that the test subject has stopped thinking about the task in hand. Note questioning words, especially where testers question their own judgement, \u201cwhy can\u2019t I find \u2026\u201d, \u201cI expected to see \u2026\u201d etc. as this indicates that the work flow for the task may have broken down.\n\nAlso keep an eye on occasions where the user completely fails to do a task. They may need some prompting to unstick them, but you should be careful not to bias the test. These should be the highest priority issues for you to fix. If users recover from getting stuck, make a note of how they recovered. Prolonged periods of silence from the test subject may also require prompting as they should be talking all the time. Ask them what they are thinking or looking for but avoid words like \u2018try\u2019 (e.g. \u2018what are you trying to do?\u2019) as this implies that they are currently failing.\n\nBe wary of users\u2019 opinions on aesthetics and be prepared to bring them back to the script if they get side-tracked.\n\nWriting it up\n\nEven if you are the only developer it\u2019s important to summarise the key issues that emerged during testing: your notes won\u2019t make much sense to you a week or so after the test.\n\nIf you are writing for other people, include a summary no longer than two pages; this can consist of a list or table of the issues including recommendations and their priorities. Remember to anonymise the users in the report. In team situations, you may be surprised at how many people are interested in the results of the usability test even if it doesn\u2019t relate directly to something that they can fix.\n\nTo conclude\u2026\n\nSome usability testing is better than none at all, even for small projects or those with strict deadlines. Make the most of the time and resources available. Choose your users carefully, make them comfortable, summarise your report and don\u2019t forget to leave a doughnut for yourself!", "year": "2006", "author": "Natalie Downe", "author_slug": "nataliedowne", "published": "2006-12-16T00:00:00+00:00", "url": "https://24ways.org/2006/fast-and-simple-usability-testing/", "topic": "process"} {"rowid": 122, "title": "A Message To You, Rudy - CSS Production Notes", "contents": "When more than one designer or developer work together on coding an XHTML/CSS template, there are several ways to make collaboration effective. Some prefer to comment their code, leaving a trail of bread-crumbs for their co-workers to follow. Others use accompanying files that contain their working notes or communicate via Basecamp.\n\nFor this year\u2019s 24ways I wanted to share a technique that I has been effective at Stuff and Nonsense; one that unfortunately did not make it into the final draft of Transcending CSS. This technique, CSS production notes, places your page production notes in one convenient place within an XHTML document and uses nothing more than meaningful markup and CSS.\n\nLet\u2019s start with the basics; a conversation between a group of people. In the absence of notes or conversation elements in XHTML you need to make an XHTML compound that will effectively add meaning to the conversation between designers and developers. As each person speaks, you have two elements right there to describe what has been said and who has spoken:
    and its cite attribute. \n\n
    \n\t

    This project will use XHTML1.0 Strict, CSS2.1 and all that malarkey.

    \n
    \n\nWith more than one person speaking, you need to establish a temporal order for the conversation. Once again, the element to do just that is already there in XHTML; the humble ordered list.\n\n
      \n\t
    1. \n\t\t
      \n\t\t\t

      This project will use XHTML1.0 Strict, CSS2.1 and all that malarkey.

      \n\t\t
      \n\t
    2. \n\t
    3. \n\t\t
      \n\t\t\t

      Those bits are simple and bulletproof.

      \n\t\t
      \n\t
    4. \n
    \n\nAdding a new note is as simple as adding a new item to list, and if you prefer to add more information to each note, such as the date or time that the note was written, go right ahead. Place your note list at the bottom of the source order of your document, right before the closing tag. One advantage of this approach over using conventional comments in your code is that all the notes are unobtrusive and are grouped together in one place, rather than being spread throughout your document.\n\nBasic CSS styling\n\nFor the first stage you are going to add some basic styling to the notes area, starting with the ordered list. For this design I am basing the look and feel on an instant messenger window.\n\n\n\nol#notes {\n\twidth : 300px; \n\theight : 320px; \n\tpadding : .5em 0; \n\tbackground : url(im.png) repeat; \n\tborder : 1px solid #333; \n\tborder-bottom-width : 2px; \n\t-moz-border-radius : 6px; /* Will not validate */\n\tcolor : #000; \n\toverflow : auto; \n}\nol#notes li { \n\tmargin : .5em; \n\tpadding : 10px 0 5px; \n\tbackground-color : #fff; \n\tborder : 1px solid #666; \n\t-moz-border-radius : 6px; /* Will not validate */ \n}\nol#notes blockquote { \n\tmargin : 0; \n\tpadding : 0; \n}\nol#notes p { \n\tmargin : 0 20px .75em;\n\tpadding : 0; \n}\nol#notes p.date { \n\tfont-size : 92%;\n\tcolor : #666; \n\ttext-transform : uppercase; \n}\n\nTake a gander at the first example.\n\nYou could stop right there, but without seeing who has left the note, there is little context. So next, extract the name of the commenter from the
    \u2019s cite attribute and display it before each note by using generated content.\n\nol#notes blockquote:before { \n\tcontent : \" \"attr(cite)\" said: \"; \n\tmargin-left : 20px; \n\tfont-weight : bold; \n}\n\nFun with more detailed styling\n\nNow, with all of the information and basic styling in place, it\u2019s time to have some fun with some more detailed styling to spruce up your notes. Let\u2019s start by adding an icon for each person, once again based on their cite. First, all of the first paragraphs of a
    \u2019s that includes a cite attribute are given common styles.\n\nol#notes blockquote[cite] p:first-child {\n\tmin-height : 34px;\n\tpadding-left : 40px; \n}\n\nFollowed by an individual background-image.\n\nol#notes blockquote[cite=\"Andy\"] p:first-child { \n\tbackground : url(malarkey.png) no-repeat 5px 5px; \n} \n\nIf you prefer a little more interactivity, add a :hover state to each
    and perhaps highlight the most recent comment.\n\nol#notes blockquote:hover { \n\tbackground-color : #faf8eb; \n\tborder-top : 1px solid #fff; \n\tborder-bottom : 1px solid #333; \n}\nol#notes li:last-child blockquote { \n\tbackground-color : #f1efe2; \n}\n\n\n\nYou could also adjust the style for each comment based on the department that the person works in, for example:\n\n
  • \n\t
    \n\t\t

    This project will use XHTML1.0 Strict, CSS2.1 and all that malarkey.

    \n\t
    \n
  • \n
  • \n\t
    \n\t\t

    Those bits are simple and bulletproof.

    \n\t
    \n
  • \nol#notes blockquote.designer { border-color : #600; }\n\nTake a look at the results of the second stage.\n\nShow and hide the notes using CSS positioning\n\nWith your notes now dressed in their finest, it is time to tuck them away above the top of your working XHTML/CSS prototype so that you can reveal them when you need them, no JavaScript required. Start by moving the ordered list of notes off the top of the viewport leaving only a few pixels in view. It is also a good idea to make them semi-transparent by using the opacity property for browsers that have implemented it.\n\nol#notes { \n\tposition : absolute; \n\topacity : .25;\n\tz-index : 2000; \n\ttop : -305px; \n\tleft : 20px; \n}\n\nYour last step is to add :hover and :focus dynamic pseudo-classes to reposition the list at the top of the viewport and restore full opacity to display them in their full glory when needed.\n\nol#notes:hover, ol#notes:focus {\n\ttop : 0; \n\topacity : 1; \n}\n\n\n\nNow it\u2019s time to sit back, pour yourself a long drink and bask in the glory of the final result. Your notes are all stored in one handy place at the bottom of your document rather than being spread around your code. When your templates are complete, simply dive straight to the bottom and pull out the notes.\n\nA Message To You, Rudy\n\nThank-you to everybody for making this a really great year for web standards. Have a wonderful holiday season.\n\nBuy Andy Clarke\u2019s book Transcending CSS from Amazon.com", "year": "2006", "author": "Andy Clarke", "author_slug": "andyclarke", "published": "2006-12-15T00:00:00+00:00", "url": "https://24ways.org/2006/css-production-notes/", "topic": "process"} {"rowid": 121, "title": "Hide And Seek in The Head", "contents": "If you want your JavaScript-enhanced pages to remain accessible and understandable to scripted and noscript users alike, you have to think before you code. Which functionalities are required (ie. should work without JavaScript)? Which ones are merely nice-to-have (ie. can be scripted)? You should only start creating the site when you\u2019ve taken these decisions.\n\nSpecial HTML elements\n\nOnce you have a clear idea of what will work with and without JavaScript, you\u2019ll likely find that you need a few HTML elements for the noscript version only.\n\nTake this example: A form has a nifty bit of Ajax that automatically and silently sends a request once the user enters something in a form field. However, in order to preserve accessibility, the user should also be able to submit the form normally. So the form should have a submit button in noscript browsers, but not when the browser supports sufficient JavaScript.\n\nSince the button is meant for noscript browsers, it must be hard-coded in the HTML:\n\n\n\nWhen JavaScript is supported, it should be removed:\n\nvar checkJS = [check JavaScript support];\nwindow.onload = function () {\n\tif (!checkJS) return;\n\tdocument.getElementById('noScriptButton').style.display = 'none';\n}\n\nProblem: the load event\n\nAlthough this will likely work fine in your testing environment, it\u2019s not completely correct. What if a user with a modern, JavaScript-capable browser visits your page, but has to wait for a huge graphic to load? The load event fires only after all assets, including images, have been loaded. So this user will first see a submit button, but then all of a sudden it\u2019s removed. That\u2019s potentially confusing.\n\nFortunately there\u2019s a simple solution: play a bit of hide and seek in the :\n\nvar checkJS = [check JavaScript support];\nif (checkJS) {\n\tdocument.write('');\n}\n\nFirst, check if the browser supports enough JavaScript. If it does, document.write an extra \n\n\nEggnog is supposed to be spiked, right?\n\nOf course, this is one simple example of what can be a much more powerful technique, depending on your needs and creativity. Just don\u2019t go coding up your wildest fantasies until you\u2019ve had a chance to sleep off the Christmas turkey and whatever tasty liquids you happen to imbibe along the way\u2026", "year": "2008", "author": "Dan Rubin", "author_slug": "danrubin", "published": "2008-12-22T00:00:00+00:00", "url": "https://24ways.org/2008/absolute-columns/", "topic": "code"} {"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": 96, "title": "Unwrapping the Wii U Browser", "contents": "The Wii U was released on 18 November 2012 in the US, and 30 November in the UK. It\u2019s the first eighth generation home console, the first mainstream second-screen device, and it has some really impressive browser specs.\n\nConsoles are not just for games now: they\u2019re marketed as complete entertainment solutions. Internet connectivity and browser functionality have gone from a nice-to-have feature in game consoles to a selling point. In Nintendo\u2019s case, they see it as a challenge to design an experience that\u2019s better than browsing on a desktop.\n\n\n\tLet\u2019s make a browser that users can use on a daily basis, something that can really handle everything we\u2019ve come to expect from a browser and do it more naturally.\nSasaki \u2013 Iwata Asks on Nintendo.com\n\n\nWith 11% of people using console browsers to visit websites, it\u2019s important to consider these devices right from the start of projects. Browsing the web on a TV or handheld console is a very different experience to browsing on a desktop or a mobile phone, and has many usability implications.\n\nConsole browser testing\n\nWhen I\u2019m testing a console browser, one of the first things I do is run Niels Leenheer\u2019s HTML5 test and Lea Verou\u2019s CSS3 test. I use these benchmarks as a rough comparison of the standards each browser supports.\n\nIn October, IE9 came out for the Xbox 360, scoring 120/500 in the HTML5 test and 32% in the CSS3 test. The PS Vita also had an update to its browser in recent weeks, jumping from 58/500 to 243/500 in the HTML5 test, and 32% to 55% in the CSS3 test. Manufacturers have been stepping up their game, trying to make their browsing experiences better.\n\nTo give you an idea of how the Wii U currently compares to other devices, here are the test results of the other TV consoles I\u2019ve tested. I\u2019ve written more in-depth notes on TV and portable console browsers separately.\n\n\nYear of releaseHTML5 scoreCSS3 scoreNotes\nWii U2012258/50048%Runs a Netfront browser (WebKit).\nWii200689/500Wouldn\u2019t runRuns an Opera browser.\nPS3200668/50038%Runs a Netfront browser (WebKit).\nXbox 3602005120/50032%A browser for the Xbox (IE9) was only recently released in October 2012. The Kinect provides voice and gesture support. There\u2019s also SmartGlass, a second-screen app for platforms including Android and iOS.\n\n\nThe Wii U browser is Nintendo\u2019s fifth attempt at a console browser. Based on these tests, it\u2019s already looking promising.\n\nWhy console browsers used to suck\n\nIt takes a lot of system memory to run a good browser, and the problem of older consoles is that they don\u2019t have much memory available. The original Nintendo DS needs a memory expansion pack just to run the browser, because the 4MB it has on board isn\u2019t enough. I noticed that even on newer devices, some sites fail to load because the system runs out of memory.\n\nThe Wii came out six years ago with an Opera browser. Still being used today and with such low resources available, the latest browser features can\u2019t reasonably be supported. There\u2019s also pressure to add features such as tabs, and enable gamers to use the browser while a game is paused. Nintendo\u2019s browser team have the advantage of higher specs to play with on their new console (1GB of memory dedicated to games, 1GB for the system), which makes it easier to support the latest standards. But it\u2019s still a challenge to fit everything in.\n\n\n\t\u2026even though we have more memory, the amount of memory we can use for the browser is limited compared to a PC, so we\u2019ve worked in ways that efficiently allocates the available memory per tab. To work on this, the experience working on the browser for the Nintendo 3DS system under a limited memory constraint helped us greatly.\nSasaki \u2013 Iwata Asks on Nintendo.com\n\n\nIn the box\n\nThe Wii U consists of a console unit which plugs into a TV (the first to support HD), and a wireless controller known as a gamepad. The gamepad is a lot bigger than typical TV console controllers, and it has a touchscreen on the front. The touchscreen is resistive, responding to pressure rather than electrical current. It\u2019s intended to be used with a stylus (provided) but fingers can be used.\n\nIt might look a bit like one, but the gamepad isn\u2019t a portable console designed to be taken out like the PS Vita. The gamepad can be used as a standalone screen with the TV switched off, as long as it\u2019s within range of the console unit \u2013 it basically piggybacks off it.\n\n\n\nIt\u2019s surprisingly lightweight for its size. It has a wealth of detectors including 9-axis control. Sensors wake the device from sleep when it\u2019s picked up. There\u2019s also a camera on the front, and a headphone port and speakers, with audio coming through both the TV and the gamepad giving a surround sound feel.\n\nUp to six tabs can be opened at once, and the browser can be used while games are paused. There\u2019s a really nice little feature here \u2013 the current game\u2019s name is saved as a search option, so it\u2019s really quick to look up contextual content such as walk-throughs.\n\nControls\n\nOnly one gamepad can be used to control the browser, but if there are Wiimotes connected, they can be used as pointers. This doesn\u2019t let the user do anything except point (they each get a little hand icon with a number on it displayed on the screen), but it\u2019s interesting that multiple people can be interacting with a site at once.\n\n\n\nSee a bigger version\n\nThe gamepad can also be used as a simple TV remote control, with basic functions such as bringing up the programme guide, adjusting volume and changing channel. I found the simplified interface much more usable than a full-featured remote control.\n\n\n\nI\u2019m used to scrolling being sluggish on consoles, but the Wii U feels almost as snappy as a desktop browser. Sites load considerably faster compared with others I\u2019ve tested.\n\nTilt-scroll\n\nHolding down ZL and ZR while tilting the screen activates an Instapaper-style tilt to scroll for going up and down the page quickly, useful for navigating very long pages.\n\nSecond screen\n\nThe TV mirrors most of what\u2019s on the gamepad, although the TV screen just displays the contents of the browser window, while the gamepad displays the site along with the browser toolbar.\n\nWhen the user with the gamepad is typing, the keyboard is hidden from the TV screen \u2013 there\u2019s just a bit of text at the top indicating what\u2019s happening on the gamepad.\n\nPressing X draws an on-screen curtain over the TV, hiding the content that\u2019s on the gamepad from the TV. Pressing X again opens the curtains, revealing what\u2019s on the gamepad. Holding the button down plays a drumroll before it\u2019s released and the curtains are opened. I can imagine this being used in meetings as a fun presentation tool.\n\n\n\n\n\tIn a sense, browsing is a personal activity, but you get the idea that people will be coming and going through the room. When I first saw the curtain function, it made a huge impression on me. I walked around with it all over the company saying, \u201cThey\u2019ve really come up with something amazing!\u201d\nIwata \u2013 Iwata Asks on Nintendo.com\n\n\nText\n\nWriting text\n\nUnlike the capacitive screens on smartphones, the Wii U\u2019s resistive screen needs to be pressed harder than you\u2019re probably used to for registering a touch event. The gamepad screen is big, which makes it much easier to type on this device than other handheld consoles, even without the stylus. It\u2019s still more fiddly than a full-sized keyboard though. When you\u2019re designing forms, consider the extra difficulty console users experience.\n\n\n\nAlthough TV screens are physically big, they are typically viewed from further away than desktop screens. This makes readability an issue, so Nintendo have provided not one, but four ways to zoom in and out:\n\n\n\tDouble-tapping on the screen.\n\tTapping the on-screen zoom icons in the browser toolbar.\n\tPressing the + and - buttons on the device.\n\tMoving the right analogue stick up and down.\n\n\nAs well as making it easy to zoom in and out, Nintendo have done a few other things to improve the reading experience on the TV.\n\nSystem font\n\nOne thing you\u2019ll notice pretty quickly is that the browser lacks all the fonts we\u2019re used to falling back to. Serif fonts are replaced with the system\u2019s sans-serif font. I couldn\u2019t get Typekit\u2019s font loading method to work but Fontdeck, which works slightly differently, does display custom fonts.\n\n The system font has been optimised for reading at a distance and is easy to distinguish because the lowercase e has a quirky little tilt.\n\nDon\u2019t lose :focus\n\nUsing the D-pad to navigate is similar to using a keyboard. Individual links are focused on, with a blue outline drawn around them.\n\nThe recently redesigned An Event Apart site is an example that improves the experience for keyboard and D-pad users. They\u2019ve added a yellow background colour to links on focus. It feels nicer than the default blue outline on its own.\n\n\n\nMedia\n\nThis year, television overtook PCs as the primary way to watch online video content. TV is the natural environment for video, and 42% of online TVs in the US are connected to the internet via a console. Unfortunately, the