{"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\n\n\nOnce this is done you can add links to Flickr pages anywhere in your document, and when you give them the CSS class getflickrphotos they get turned into gallery links. When a visitor clicks these links they turn into loading messages and show a \u201cpopup\u201d gallery with the connected photos once they were loaded. As the JSON returned is very small it won\u2019t take long. You can close the gallery, or click any of the thumbnails to view a photo. Clicking the photo makes it disappear and go back to the thumbnails.\n\nCheck out the example page and click the different gallery links to see the results.\n\nNotice that getFlickr works with Unobtrusive JavaScript as when scripting is disabled the links still get to the photos on Flickr.\n\ngetFlickr for JavaScript Hackers\n\nIf you want to use getFlickr with your own JavaScripts you can use its main method leech():\n\ngetFlickr.leech(sTag, sCallback);\n\n \n\tsTag\n\tthe tag you are looking for\n\tsCallback\n\tan optional function to call when the data was retrieved.\n \n\nAfter you called the leech() method you have two strings to use:\n\n \n\tgetFlickr.html[sTag]\n\tcontains an HTML list (without the outer UL element) of all the images linked to the correct pages at flickr. The images are the medium size, you can easily change that by replacing _m.jpg with _s.jpg for thumbnails.\n\tgetFlickr.tags[sTag]\n\tcontains a string of all the other tags flickr users added with the tag you searched for(space separated)\n \n\nYou can call getFlickr.leech() several times when the page has loaded to cache several result feeds before the page gets loaded. This\u2019ll make the photos quicker for the end user to show up. If you want to offer a form for people to search for flickr photos and display them immediately you can use the following HTML:\n\n
\n \n \n \n

Tags:

\n

Photos:

    \n
    \n\nAll the JavaScript you\u2019ll need (for a basic display) is this:\n\nfunction populate(){\n var tag = document.getElementById('tag').value;\n document.getElementById('photos').innerHTML = getFlickr.html[tag].replace(/_m\\.jpg/g,'_s.jpg');\n document.getElementById('tags').innerHTML = getFlickr.tags[tag];\n return false;\n}\n\nEasy as pie, enjoy!\n\nCheck out the example page and try the form to see the results.", "year": "2006", "author": "Christian Heilmann", "author_slug": "chrisheilmann", "published": "2006-12-03T00:00:00+00:00", "url": "https://24ways.org/2006/flickr-photos-on-demand/", "topic": "code"} {"rowid": 138, "title": "Rounded Corner Boxes the CSS3 Way", "contents": "If you\u2019ve been doing CSS for a while you\u2019ll know that there are approximately 3,762 ways to create a rounded corner box. The simplest techniques rely on the addition of extra mark-up directly to your page, while the more complicated ones add the mark-up though DOM manipulation. While these techniques are all very interesting, they do seem somewhat of a kludge. The goal of CSS is to separate structure from presentation, yet here we are adding superfluous mark-up to our code in order to create a visual effect. The reason we are doing this is simple. CSS2.1 only allows a single background image per element.\n\nThankfully this looks set to change with the addition of multiple background images into the CSS3 specification. With CSS3 you\u2019ll be able to add not one, not four, but eight background images to a single element. This means you\u2019ll be able to create all kinds of interesting effects without the need of those additional elements.\n\nWhile the CSS working group still seem to be arguing over the exact syntax, Dave Hyatt went ahead and implemented the currently suggested mechanism into Safari. The technique is fiendishly simple, and I think we\u2019ll all be a lot better off once the W3C stop arguing over the details and allow browser vendors to get on and provide the tools we need to build better websites.\n\nTo create a CSS3 rounded corner box, simply start with your box element and apply your 4 corner images, separated by commas.\n\n.box {\n\tbackground-image: url(top-left.gif), url(top-right.gif), url(bottom-left.gif), url(bottom-right.gif);\n}\n\nWe don\u2019t want these background images to repeat, which is the normal behaviour, so lets set all their background-repeat properties to no-repeat.\n\n.box {\n\tbackground-image: url(top-left.gif), url(top-right.gif), url(bottom-left.gif), url(bottom-right.gif);\n\tbackground-repeat: no-repeat, no-repeat, no-repeat, no-repeat;\n}\n\nLastly, we need to define the positioning of each corner image.\n\n.box {\n\tbackground-image: url(top-left.gif), url(top-right.gif), url(bottom-left.gif), url(bottom-right.gif);\n\tbackground-repeat: no-repeat, no-repeat, no-repeat, no-repeat;\n\tbackground-position: top left, top right, bottom left, bottom right;\n}\n\nAnd there we have it, a simple rounded corner box with no additional mark-up.\n\nAs well as using multiple background images, CSS3 also has the ability to create rounded corners without the need of any images at all. You can do this by setting the border-radius property to your desired value as seen in the next example.\n\n.box {\n\tborder-radius: 1.6em;\n}\n\nThis technique currently works in Firefox/Camino and creates a nice, if somewhat jagged rounded corner. If you want to create a box that works in both Mozilla and WebKit based browsers, why not combine both techniques and see what happens.", "year": "2006", "author": "Andy Budd", "author_slug": "andybudd", "published": "2006-12-04T00:00:00+00:00", "url": "https://24ways.org/2006/rounded-corner-boxes-the-css3-way/", "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": 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\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": 131, "title": "Random Lines Made With Mesh", "contents": "I know that Adobe Illustrator can be a bit daunting for people who aren\u2019t really advanced users of the program, but you would be amazed by how easy you can create cool effects or backgrounds. In this short tutorial I show you how to create a cool looking background only in 5 steps. \n\nStep 1 \u2013 Create Lines\n\n\n\nCreate lines using random widths and harmonious suitable colors. If you get stuck on finding the right colors, check out Adobe\u2019s Kuler and start experimenting.\n\nStep 2 \u2013 Convert Strokes to Fills\n\n\n\nSelect all lines and convert them to fills. Go to the Object menu, select Path > 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": 143, "title": "Marking Up a Tag Cloud", "contents": "Everyone\u2019s doing it. \n\nThe problem is, everyone\u2019s doing it wrong. \n\nHarsh words, you might think. But the crimes against decent markup are legion in this area. You see, I\u2019m something of a markup and semantics junkie. So I\u2019m going to analyse some of the more well-known tag clouds on the internet, explain what\u2019s wrong, and then show you one way to do it better. \n\ndel.icio.us \n\nI think the first ever tag cloud I saw was on del.icio.us. Here\u2019s how they mark it up. \n\n
    \n\t.net\n\tadvertising\n\tajax\n\t...\n
    \n\nUnfortunately, that is one of the worst examples of tag cloud markup I have ever seen. The page states that a tag cloud is a list of tags where size reflects popularity. However, despite describing it in this way to the human readers, the page\u2019s author hasn\u2019t described it that way in the markup. It isn\u2019t a list of tags, just a bunch of anchors in a
    . This is also inaccessible because a screenreader will not pause between adjacent links, and in some configurations will not announce the individual links, but rather all of the tags will be read as just one link containing a whole bunch of words. Markup crime number one. \n\nFlickr \n\nAh, Flickr. The darling photo sharing site of the internet, and the biggest blind spot in every standardista\u2019s vision. Forgive it for having atrocious markup and sometimes confusing UI because it\u2019s just so much damn fun to use. Let\u2019s see what they do. \n\n

    \n\t\u00a006\u00a0\n\t\u00a0africa\u00a0\n\t\u00a0amsterdam\u00a0\n\t...\n

    \n\nAgain we have a simple collection of anchors like del.icio.us, only this time in a paragraph. But rather than using a class to represent the size of the tag they use an inline style. An inline style using a pixel-based font size. That\u2019s so far away from the goal of separating style from content, they might as well use a tag. You could theoretically parse that to extract the information, but you have more work to guess what the pixel sizes represent. Markup crime number two (and extra jail time for using non-breaking spaces purely for visual spacing purposes.)\n\nTechnorati \n\nAh, now. Here, you\u2019d expect something decent. After all, the Overlord of microformats and King of Semantics Tantek \u00c7elik works there. Surely we\u2019ll see something decent here? \n\n
      \n\t
    1. Britney Spears
    2. \n\t
    3. Bush
    4. \n\t
    5. Christmas
    6. \n\t...\n\t
    7. SEO
    8. \n\t
    9. Shopping
    10. \n\t...\n
    \n\nUnfortunately it turns out not to be that decent, and stop calling me Shirley. It\u2019s not exactly terrible code. It does recognise that a tag cloud is a list of links. And, since they\u2019re in alphabetical order, that it\u2019s an ordered list of links. That\u2019s nice. However \u2026 fifteen nested tags? FIFTEEN? That\u2019s emphasis for you. Yes, it is parse-able, but it\u2019s also something of a strange way of looking at emphasis. The HTML spec states that is emphasis, and is for stronger emphasis. Nesting tags seems counter to the idea that different tags are used for different levels of emphasis. Plus, if you had a screen reader that stressed the voice for emphasis, what would it do? Shout at you? Markup crime number three. \n\nSo what should it be? \n\nAs del.icio.us tells us, a tag cloud is a list of tags where the size that they are rendered at contains extra information. However, by hiding the extra context purely within the CSS or the HTML tags used, you are denying that context to some users. The basic assumption being made is that all users will be able to see the difference between font sizes, and this is demonstrably false. \n\nA better way to code a tag cloud is to put the context of the cloud within the content, not the markup or CSS alone. As an example, I\u2019m going to take some of my favourite flickr tags and put them into a cloud which communicates the relative frequency of each tag. \n\nTo start with a tag cloud in its most basic form is just a list of links. I am going to present them in alphabetical order, so I\u2019ll use an ordered list. Into each list item I add the number of photos I have with that particular tag. The tag itself is linked to the page on flickr which contains those photos. So we end up with this first example. To display this as a traditional tag cloud, we need to alter it in a few ways: \n\n\n\tThe items need to be displayed next to each other, rather than one-per-line\n\tThe context information should be hidden from display (but not from screen readers)\n\tThe tag should link to the page of items with that tag\n\n\nDisplaying the items next to each other simply means setting the display of the list elements to inline. The context can be hidden by wrapping it in a and then using the off-left method to hide it. And the link just means adding an anchor (with rel=\"tag\" for some extra microformats bonus points). So, now we have a simple collection of links in our second example. \n\nThe last stage is to add the sizes. Since we already have context in our content, the size is purely for visual rendering, so we can just use classes to define the different sizes. For my example, I\u2019ll use a range of class names from not-popular through ultra-popular, in order of smallest to largest, and then use CSS to define different font sizes. If you preferred, you could always use less verbose class names such as size1 through size6. Anyway, adding some classes and CSS gives us our final example, a semantic and more accessible tag cloud.", "year": "2006", "author": "Mark Norman Francis", "author_slug": "marknormanfrancis", "published": "2006-12-09T00:00:00+00:00", "url": "https://24ways.org/2006/marking-up-a-tag-cloud/", "topic": "code"} {"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": 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": 141, "title": "Compose to a Vertical Rhythm", "contents": "\u201cSpace in typography is like time in music. It is infinitely divisible, but a few proportional intervals can be much more useful than a limitless choice of arbitrary quantities.\u201d So says the typographer Robert Bringhurst, and just as regular use of time provides rhythm in music, so regular use of space provides rhythm in typography, and without rhythm the listener, or the reader, becomes disorientated and lost.\n\nOn the Web, vertical rhythm \u2013 the spacing and arrangement of text as the reader descends the page \u2013 is contributed to by three factors: font size, line height and margin or padding. All of these factors must calculated with care in order that the rhythm is maintained. \n\nThe basic unit of vertical space is line height. Establishing a suitable line height that can be applied to all text on the page, be it heading, body copy or sidenote, is the key to a solid dependable vertical rhythm, which will engage and guide the reader down the page. To see this in action, I\u2019ve created an example with headings, footnotes and sidenotes. \n\nEstablishing a suitable line height\n\nThe easiest place to begin determining a basic line height unit is with the font size of the body copy. For the example I\u2019ve chosen 12px. To ensure readability the body text will almost certainly need some leading, that is to say spacing between the lines. A line-height of 1.5em would give 6px spacing between the lines of body copy. This will create a total line height of 18px, which becomes our basic unit. Here\u2019s the CSS to get us to this point:\n\nbody {\n\tfont-size: 75%; \n}\nhtml>body {\n\tfont-size: 12px; \n}\np {\n\tline-height 1.5em; \n}\n\nThere are many ways to size text in CSS and the above approach provides and accessible method of achieving the pixel-precision solid typography requires. By way of explanation, the first font-size reduces the body text from the 16px default (common to most browsers and OS set-ups) down to the 12px we require. This rule is primarily there for Internet Explorer 6 and below on Windows: the percentage value means that the text will scale predictably should a user bump the text size up or down. The second font-size sets the text size specifically and is ignored by IE6, but used by Firefox, Safari, IE7, Opera and other modern browsers which allow users to resize text sized in pixels.\n\nSpacing between paragraphs\n\nWith our rhythmic unit set at 18px we need to ensure that it is maintained throughout the body copy. A common place to lose the rhythm is the gaps set between margins. The default treatment by web browsers of paragraphs is to insert a top- and bottom-margin of 1em. In our case this would give a spacing between the paragraphs of 12px and hence throw the text out of rhythm. If the rhythm of the page is to be maintained, the spacing of paragraphs should be related to the basic line height unit. This is achieved simply by setting top- and bottom-margins equal to the line height.\n\nIn order that typographic integrity is maintained when text is resized by the user we must use ems for all our vertical measurements, including line-height, padding and margins.\n\np {\n\tfont-size:1em;\n\tmargin-top: 1.5em;\n\tmargin-bottom: 1.5em; \n}\n\nBrowsers set margins on all block-level elements (such as headings, lists and blockquotes) so a way of ensuring that typographic attention is paid to all such elements is to reset the margins at the beginning of your style sheet. You could use a rule such as:\n\nbody,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,p,blockquote,th,td { \n\tmargin:0; \n\tpadding:0; \n}\n\nAlternatively you could look into using the Yahoo! UI Reset style sheet which removes most default styling, so providing a solid foundation upon which you can explicitly declare your design intentions.\n\nVariations in text size\n\nWhen there is a change in text size, perhaps with a heading or sidenotes, the differing text should also take up a multiple of the basic leading. This means that, in our example, every diversion from the basic text size should take up multiples of 18px. This can be accomplished by adjusting the line-height and margin accordingly, as described following.\n\nHeadings\n\nSubheadings in the example page are set to 14px. In order that the height of each line is 18px, the line-height should be set to 18\u00a0\u00f7\u00a014 =\u00a01.286. Similarly the margins above and below the heading must be adjusted to fit. The temptation is to set heading margins to a simple 1em, but in order to maintain the rhythm, the top and bottom margins should be set at 1.286em so that the spacing is equal to the full 18px unit.\n\nh2 {\n\tfont-size:1.1667em;\n\tline-height: 1.286em;\n\tmargin-top: 1.286em;\n\tmargin-bottom: 1.286em; \n}\n\nOne can also set asymmetrical margins for headings, provided the margins combine to be multiples of the basic line height. In our example, a top margin of 1\u00bd lines is combined with a bottom margin of half a line as follows:\n\nh2 {\n\tfont-size:1.1667em;\n\tline-height: 1.286em;\n\tmargin-top: 1.929em;\n\tmargin-bottom: 0.643em; \n}\n\nAlso in our example, the main heading is given a text size of 18px, therefore the line-height has been set to 1em, as has the margin:\n\nh1 {\n\tfont-size:1.5em;\n\tline-height: 1em;\n\tmargin-top: 0;\n\tmargin-bottom: 1em; \n}\n\nSidenotes\n\nSidenotes (and other supplementary material) are often set at a smaller size to the basic text. To keep the rhythm, this smaller text should still line up with body copy, so a calculation similar to that for headings is required. In our example, the sidenotes are set at 10px and so their line-height must be increased to 18\u00a0\u00f7\u00a010 =\u00a01.8.\n\n.sidenote {\n\tfont-size:0.8333em;\n\tline-height:1.8em; \n}\n\nBorders\n\nOne additional point where vertical rhythm is often lost is with the introduction of horizontal borders. These effectively act as shims pushing the subsequent text downwards, so a two pixel horizontal border will throw out the vertical rhythm by two pixels. A way around this is to specify horizontal lines using background images or, as in our example, specify the width of the border in ems and adjust the padding to take up the slack. \n\nThe design of the footnote in our example requires a 1px horizontal border. The footnote contains 12px text, so 1px in ems is 1\u00a0\u00f7\u00a012 =\u00a00.0833. I have added a margin of 1\u00bd lines above the border (1.5\u00a0\u00d7\u00a018\u00a0\u00f7\u00a012 =\u00a02.5ems), so to maintain the rhythm the border + padding must equal a \u00bd (9px). We know the border is set to 1px, so the padding must be set to 8px. To specify this in ems we use the familiar calculation: 8\u00a0\u00f7\u00a012 =\u00a00.667.\n\nHit me with your rhythm stick\n\nComposing to a vertical rhythm helps engage and guide the reader down the page, but it takes typographic discipline to do so. It may seem like a lot of fiddly maths is involved (a few divisions and multiplications never hurt anyone) but good type setting is all about numbers, and it is this attention to detail which is the key to success.", "year": "2006", "author": "Richard Rutter", "author_slug": "richardrutter", "published": "2006-12-12T00:00:00+00:00", "url": "https://24ways.org/2006/compose-to-a-vertical-rhythm/", "topic": "design"} {"rowid": 142, "title": "Revealing Relationships Can Be Good Form", "contents": "A few days ago, a colleague of mine \u2013 someone I have known for several years, who has been doing web design for several years and harks back from the early days of ZDNet \u2013 was running through a prototype I had put together for some user testing. As with a lot of prototypes, there was an element of \u2018smoke and mirrors\u2019 to make things look like they were working. \n\nOne part of the form included a yes/no radio button, and selecting the Yes option would, in the real and final version of the form, reveal some extra content. Rather than put too much JavaScript in the prototype, I took a preverbial shortcut and created a link which I wrapped around the text next to the radio button \u2013 clicking on that link would cause the form to mimic a change event on the radio button. But it wasn\u2019t working for him. \n\nWhy was that? Because whereas I created the form using a