{"rowid": 326, "title": "Don't be eval()", "contents": "JavaScript is an interpreted language, and like so many of its peers it includes the all powerful eval() function. eval() takes a string and executes it as if it were regular JavaScript code. It\u2019s incredibly powerful and incredibly easy to abuse in ways that make your code slower and harder to maintain. As a general rule, if you\u2019re using eval() there\u2019s probably something wrong with your design.\n\nCommon mistakes\n\nHere\u2019s the classic misuse of eval(). You have a JavaScript object, foo, and you want to access a property on it \u2013 but you don\u2019t know the name of the property until runtime. Here\u2019s how NOT to do it:\n\nvar property = 'bar';\nvar value = eval('foo.' + property);\n\nYes it will work, but every time that piece of code runs JavaScript will have to kick back in to interpreter mode, slowing down your app. It\u2019s also dirt ugly.\n\nHere\u2019s the right way of doing the above:\n\nvar property = 'bar';\nvar value = foo[property];\n\nIn JavaScript, square brackets act as an alternative to lookups using a dot. The only difference is that square bracket syntax expects a string.\n\nSecurity issues\n\nIn any programming language you should be extremely cautious of executing code from an untrusted source. The same is true for JavaScript \u2013 you should be extremely cautious of running eval() against any code that may have been tampered with \u2013 for example, strings taken from the page query string. Executing untrusted code can leave you vulnerable to cross-site scripting attacks.\n\nWhat\u2019s it good for?\n\nSome programmers say that eval() is B.A.D. \u2013 Broken As Designed \u2013 and should be removed from the language. However, there are some places in which it can dramatically simplify your code. A great example is for use with XMLHttpRequest, a component of the set of tools more popularly known as Ajax. XMLHttpRequest lets you make a call back to the server from JavaScript without refreshing the whole page. A simple way of using this is to have the server return JavaScript code which is then passed to eval(). Here is a simple function for doing exactly that \u2013 it takes the URL to some JavaScript code (or a server-side script that produces JavaScript) and loads and executes that code using XMLHttpRequest and eval().\n\nfunction evalRequest(url) {\n var xmlhttp = new XMLHttpRequest();\n xmlhttp.onreadystatechange = function() {\n if (xmlhttp.readyState==4 && xmlhttp.status==200) {\n eval(xmlhttp.responseText);\n }\n }\n xmlhttp.open(\"GET\", url, true);\n xmlhttp.send(null);\n }\n\nIf you want this to work with Internet Explorer you\u2019ll need to include this compatibility patch.", "year": "2005", "author": "Simon Willison", "author_slug": "simonwillison", "published": "2005-12-07T00:00:00+00:00", "url": "https://24ways.org/2005/dont-be-eval/", "topic": "code"} {"rowid": 328, "title": "Swooshy Curly Quotes Without Images", "contents": "The problem\n\nTake a quote and render it within blockquote tags, applying big, funky and stylish curly quotes both at the beginning and the end without using any images \u2013 at all.\n\nThe traditional way\n\nFeint background images under the text, or an image in the markup housed in a little float. Often designers only use the opening curly quote as it\u2019s just too difficult to float a closing one.\n\nWhy is the traditional way bad?\n\nWell, for a start there are no actual curly quotes in the text (unless you\u2019re doing some nifty image replacement). Thus with CSS disabled you\u2019ll only have default blockquote styling to fall back on. Secondly, images don\u2019t resize, so scaling text will have no affect on your graphic curlies.\n\nThe solution\n\nUse really big text. Then it can be resized by the browser, resized using CSS, and even be restyled with a new font style if you fancy it. It\u2019ll also make sense when CSS is unavailable.\n\nThe problem\n\nCreating \u201cDrop Caps\u201d with CSS has been around for a while (Big Dan Cederholm discusses a neat solution in that first book of his), but drop caps are normal characters \u2013 the A to Z or 1 to 10 \u2013 and these can all be pulled into a set space and do not serve up a ton of whitespace, unlike punctuation characters.\n\nCurly quotes aren\u2019t like traditional characters. Like full stops, commas and hashes they float within the character space and leave lots of dead white space, making it bloody difficult to manipulate them with CSS. Styles generally fit around text, so cutting into that character is tricky indeed. Also, all that extra white space is going to push into the quote text and make it look pretty uneven. This grab highlights the actual character space:\n\n\n\nSee how this is emphasized when we add a normal alphabetical character within the span. This is what we\u2019re dealing with here:\n\n\n\nThen, there\u2019s size. Call in a curly quote at less than 300% font-size and it ain\u2019t gonna look very big. The white space it creates will be big enough, but the curlies will be way too small. We need more like 700% (as in this example) to make an impression, but that sure makes for a big character space.\n\nPrepare the curlies\n\nFirstly, remove the opening \u201c from the quote. Replace it with the opening curly quote character entity \u201c. Then replace the closing \u201c with the entity reference for that, which is \u201d. Now at least the curlies will look nice and swooshy.\n\nAdd the hooks\n\nTwo reasons why we aren\u2019t using :first-letter pseudo class to manipulate the curlies. Firstly, only CSS2-friendly browsers would get what we\u2019re doing, and secondly we need to affect the last \u201cletter\u201d of our text also \u2013 the closing curly quote.\n\nSo, add a span around the opening curly, and a second span around the closing curly, giving complete control of the characters:\n\n
\u201cSpeech marks. Curly quotes. That annoying thing cool people do with their fingers to emphasize a buzzword, shortly before you hit them.\u201d
\n\nSo far nothing will look any different, aside form the curlies looking a bit nicer. I know we\u2019ve just added extra markup, but the benefits as far as accessibility are concerned are good enough for me, and of course there are no images to download.\n\nThe CSS\n\nOK, easy stuff first. Our first rule .bqstart floats the span left, changes the color, and whacks the font-size up to an exuberant 700%. Our second rule .bqend does the same tricks aside from floating the curly to the right.\n\n.bqstart {\n float: left;\n font-size: 700%;\n color: #FF0000;\n }\n\n .bqend {\n float: right;\n font-size: 700%;\n color: #FF0000;\n }\n\nThat gives us this, which is rubbish. I\u2019ve highlighted the actual span area with outlines:\n\n\n\nNote that the curlies don\u2019t even fit inside the span! At this stage on IE 6 PC you won\u2019t even see the quotes, as it only places focus on what it thinks is in the div. Also, the quote text is getting all spangled.\n\nFiddle with margin and padding\n\nThink of that span outline box as a window, and that you need to position the curlies within that window in order to see them. By adding some small adjustments to the margin and padding it\u2019s possible to position the curlies exactly where you want them, and remove the excess white space by defining a height:\n\n.bqstart {\n float: left;\n height: 45px;\n margin-top: -20px;\n padding-top: 45px;\n margin-bottom: -50px;\n font-size: 700%;\n color: #FF0000;\n }\n\n .bqend {\n float: right;\n height: 25px;\n margin-top: 0px;\n padding-top: 45px;\n font-size: 700%;\n color: #FF0000;\n }\n\nI wanted the blocks of my curlies to align with the quote text, whereas you may want them to dig in or stick out more. Be aware however that my positioning works for IE PC and Mac, Firefox and Safari. Too much tweaking seems to break the magic in various browsers at various times. Now things are fitting beautifully:\n\nI must admit that the heights, margins and spacing don\u2019t make a lot of sense if you analyze them. This was a real trial and error job. Get it working on Safari, and IE would fail. Sort IE, and Firefox would go weird.\n\nFinished\n\nThe final thing looks ace, can be resized, looks cool without styles, and can be edited with CSS at any time. Here\u2019s a real example (note that I\u2019m specifying Lucida Grande and then Verdana for my curlies):\n\n \u201cSpeech marks. Curly quotes. That annoying thing cool people do with their fingers to emphasize a buzzword, shortly before you hit them.\u201d\n\nBrowsers happy\n\nAs I said, too much tweaking of margins and padding can break the effect in some browsers. Even now, Firefox insists on dropping the closing curly by approximately 6 or 7 pixels, and if I adjust the padding for that, it\u2019ll crush it into the text on Safari or IE. Weird. Still, as I close now it seems solid through resizing tests on Safari, Firefox, Camino, Opera and IE PC and Mac. Lovely.\n\nIt\u2019s probably not perfect, but together we can beat the evil typographic limitations of the web and walk together towards a brighter, more aligned world. Merry Christmas.", "year": "2005", "author": "Simon Collison", "author_slug": "simoncollison", "published": "2005-12-21T00:00:00+00:00", "url": "https://24ways.org/2005/swooshy-curly-quotes-without-images/", "topic": "business"} {"rowid": 316, "title": "Have Your DOM and Script It Too", "contents": "When working with the XMLHttpRequest object it appears you can only go one of three ways: \n\n\n\tYou can stay true to the colorful moniker du jour and stick strictly to the responseXML property\n\tYou can play with proprietary \u2013 yet widely supported \u2013 fire and inject the value of responseText property into the innerHTML of an element of your choosing\n\tOr you can be eval() and parse JSON or arbitrary JavaScript delivered via responseText\n\n\nBut did you know that there\u2019s a fourth option giving you the best of the latter two worlds? Mint uses this unmentioned approach to grab fresh HTML and run arbitrary JavaScript simultaneously. Without relying on eval(). \u201cBut wait-\u201d, you might say, \u201cwhen would I need to do this?\u201d Besides the example below this technique is handy for things like tab groups that need initialization onload but miss the main onload event handler by a mile thanks to asynchronous scripting.\n\nConsider the problem\n\nOriginally Mint used option 2 to refresh or load new tabs into individual Pepper panes without requiring a full roundtrip to the server. This was all well and good until I introduced the new Client Mode which when enabled allows anyone to view a Mint installation without being logged in. If voyeurs are afoot as Client Mode is disabled, the next time they refresh a pane the entire login page is inserted into the current document. That\u2019s not very helpful so I needed a way to redirect the current document to the login page.\n\n\n\nEnter the solution\n\nWouldn\u2019t it be cool if browsers interpreted the contents of script tags crammed into innerHTML? Sure, but unfortunately, that just wasn\u2019t meant to be. However like the body element, image elements have an onload event handler. When the image has fully loaded the handler runs the code applied to it. See where I\u2019m going with this?\n\nBy tacking a tiny image (think single pixel, transparent spacer gif \u2013 shudder) onto the end of the HTML returned by our Ajax call, we can smuggle our arbitrary JavaScript into the existing document. The image is added to the DOM, and our stowaway can go to town.\n\n

This is the results of our Ajax call.

\n \"\"\n\nPlease be neat\n\nSo we\u2019ve just jammed some meaningless cruft into our DOM. If our script does anything with images this addition could have some unexpected side effects. (Remember The Fly?) So in order to save that poor, unsuspecting element whose innerHTML we just swapped out from sharing Jeff Goldblum\u2019s terrible fate we should tidy up after ourselves. And by using the removeChild method we do just that.\n\n

This is the results of our Ajax call.

\n \"\"", "year": "2005", "author": "Shaun Inman", "author_slug": "shauninman", "published": "2005-12-24T00:00:00+00:00", "url": "https://24ways.org/2005/have-your-dom-and-script-it-too/", "topic": "code"} {"rowid": 334, "title": "Transitional vs. Strict Markup", "contents": "When promoting web standards, standardistas often talk about XHTML as being more strict than HTML. In a sense it is, since it requires that all elements are properly closed and that attribute values are quoted. But there are two flavours of XHTML 1.0 (three if you count the Frameset DOCTYPE, which is outside the scope of this article), defined by the Transitional and Strict DOCTYPEs. And HTML 4.01 also comes in those flavours.\n\nThe names reveal what they are about: Transitional DOCTYPEs are meant for those making the transition from older markup to modern ways. Strict DOCTYPEs are actually the default \u2013 the way HTML 4.01 and XHTML 1.0 were constructed to be used.\n\nA Transitional DOCTYPE may be used when you have a lot of legacy markup that cannot easily be converted to comply with a Strict DOCTYPE. But Strict is what you should be aiming for. It encourages, and in some cases enforces, the separation of structure and presentation, moving the presentational aspects from markup to CSS. From the HTML 4 Document Type Definition:\n\n\n\tThis is HTML 4.01 Strict DTD, which excludes the presentation attributes and elements that W3C expects to phase out as support for style sheets matures. Authors should use the Strict DTD when possible, but may use the Transitional DTD when support for presentation attribute and elements is required.\n\n\nAn additional benefit of using a Strict DOCTYPE is that doing so will ensure that browsers use their strictest, most standards compliant rendering modes.\n\nTommy Olsson provides a good summary of the benefits of using Strict over Transitional in Ten questions for Tommy Olsson at Web Standards Group:\n\n\n\tIn my opinion, using a Strict DTD, either HTML 4.01 Strict or XHTML 1.0 Strict, is far more important for the quality of the future web than whether or not there is an X in front of the name. The Strict DTD promotes a separation of structure and presentation, which makes a site so much easier to maintain.\n\n\nFor those looking to start using web standards and valid, semantic markup, it is important to understand the difference between Transitional and Strict DOCTYPEs. For complete listings of the differences between Transitional and Strict DOCTYPEs, see XHTML: Differences between Strict & Transitional, Comparison of Strict and Transitional XHTML, and XHTML1.0 Element Attributes by DTD.\n\nSome of the differences are more likely than others to cause problems for developers moving from a Transitional DOCTYPE to a Strict one, and I\u2019d like to mention a few of those.\n\nElements that are not allowed in Strict DOCTYPEs\n\n\n\tcenter\n\tfont\n\tiframe\n\tstrike\n\tu\n\n\nAttributes not allowed in Strict DOCTYPEs\n\n\n\talign (allowed on elements related to tables: col, colgroup, tbody, td, tfoot, th, thead, and tr)\n\tlanguage\n\tbackground\n\tbgcolor\n\tborder (allowed on table)\n\theight (allowed on img and object)\n\thspace\n\tname (allowed in HTML 4.01 Strict, not allowed on form and img in XHTML 1.0 Strict)\n\tnoshade\n\tnowrap\n\ttarget\n\ttext, link, vlink, and alink\n\tvspace\n\twidth (allowed on img, object, table, col, and colgroup)\n\n\nContent model differences\n\nAn element type\u2019s content model describes what may be contained by an instance of the element type. The most important difference in content models between Transitional and Strict is that blockquote, body, and form elements may only contain block level elements. A few examples:\n\n\n\ttext and images are not allowed immediately inside the body element, and need to be contained in a block level element like p or div\n\tinput elements must not be direct descendants of a form element\n\ttext in blockquote elements must be wrapped in a block level element like p or div\n\n\nGo Strict and move all presentation to CSS\n\nSomething that can be helpful when doing the transition from Transitional to Strict DOCTYPEs is to focus on what each element of the page you are working on is instead of how you want it to look.\n\nWorry about looks later and get the structure and semantics right first.", "year": "2005", "author": "Roger Johansson", "author_slug": "rogerjohansson", "published": "2005-12-13T00:00:00+00:00", "url": "https://24ways.org/2005/transitional-vs-strict-markup/", "topic": "code"} {"rowid": 330, "title": "An Explanation of Ems", "contents": "Ems are so-called because they are thought to approximate the size of an uppercase letter M (and so are pronounced emm), although 1em is actually significantly larger than this. The typographer Robert Bringhurst describes the em thus:\n\n\n\tThe em is a sliding measure. One em is a distance equal to the type size. In 6 point type, an em is 6 points; in 12 point type an em is 12 points and in 60 point type an em is 60 points. Thus a one em space is proportionately the same in any size.\n\n\nTo illustrate this principle in terms of CSS, consider these styles:\n\n#box1 {\n font-size: 12px;\n width: 1em;\n height: 1em;\n border:1px solid black;\n}\n\n#box2 {\n font-size: 60px;\n width: 1em;\n height: 1em;\n border: 1px solid black;\n}\n\nThese styles will render like:\n\n M\n\nand\n\n M\n\nNote that both boxes have a height and width of 1em but because they have different font sizes, one box is bigger than the other. Box 1 has a font-size of 12px so its width and height is also 12px; similarly the text of box 2 is set to 60px and so its width and height are also 60px.", "year": "2005", "author": "Richard Rutter", "author_slug": "richardrutter", "published": "2005-12-02T00:00:00+00:00", "url": "https://24ways.org/2005/an-explanation-of-ems/", "topic": "design"} {"rowid": 332, "title": "CSS Layout Starting Points", "contents": "I build a lot of CSS layouts, some incredibly simple, others that cause sleepless nights and remind me of the torturous puzzle books that were given to me at Christmas by aunties concerned for my education. However, most of the time these layouts fit quite comfortably into one of a very few standard formats. For example:\n\n\n\tLiquid, multiple column with no footer\n\tLiquid, multiple column with footer\n\tFixed width, centred\n\n\nRather than starting out with blank CSS and (X)HTML documents every time you need to build a layout, you can fairly quickly create a bunch of layout starting points, that will give you a solid basis for creating the rest of the design and mean that you don\u2019t have to remember how a three column layout with a footer is best achieved every time you come across one! \n\nThese starting points can be really basic, in fact that\u2019s exactly what you want as the final design, the fonts, the colours and so on will be different every time. It\u2019s just the main sections we want to be able to quickly get into place. For example, here is a basic starting point CSS and XHTML document for a fixed width, centred layout with a footer.\n\n \n\n\n Fixed Width and Centred starting point document\n \n \n\n\n
\n
\n
\n

Sidebar content here

\n
\n
\n
\n
\n

Your main content goes here.

\n
\n
\n
\n
\n

Ho Ho Ho!

\n
\n
\n
\n\n\n\n body {\n text-align: center;\n min-width: 740px;\n padding: 0;\n margin: 0;\n }\n\n #wrapper {\n text-align: left;\n width: 740px;\n margin-left: auto;\n margin-right: auto;\n padding: 0;\n }\n\n #content {\n margin: 0 200px 0 0;\n }\n\n #content .inner {\n padding-top: 1px;\n margin: 0 10px 10px 10px;\n }\n\n #side {\n float: right;\n width: 180px;\n margin: 0;\n }\n\n #side .inner {\n padding-top: 1px;\n margin: 0 10px 10px 10px;\n }\n\n #footer {\n margin-top: 10px;\n clear: both;\n }\n\n #footer .inner {\n margin: 10px;\n }\n\n9 times out of 10, after figuring out exactly what main elements I have in a layout, I can quickly grab the \u2018one I prepared earlier\u2019, mark-up the relevant sections within the ready-made divs, and from that point on, I only need to worry about the contents of those different areas. The actual layout is tried and tested, one that I know works well in different browsers and that is unlikely to throw me any nasty surprises later on. In addition, considering how the layout is going to work first prevents the problem of developing a layout, then realising you need to put a footer on it, and needing to redevelop the layout as the method you have chosen won\u2019t work well with a footer.\n\nWhile enjoying your mince pies and mulled wine during the \u2018quiet time\u2019 between Christmas and New Year, why not create some starting point layouts of your own? The css-discuss Wiki, CSS layouts section is a great place to find examples that you can try out and find your favourite method of creating the various layout types.", "year": "2005", "author": "Rachel Andrew", "author_slug": "rachelandrew", "published": "2005-12-04T00:00:00+00:00", "url": "https://24ways.org/2005/css-layout-starting-points/", "topic": "code"} {"rowid": 331, "title": "Splintered Striper", "contents": "Back in March 2004, David F. Miller demonstrated a little bit of DOM scripting magic in his A List Apart article Zebra Tables.\n\nHis script programmatically adds two alternating CSS background colours to table rows, making them more readable and visually pleasing, while saving the document author the tedious task of manually assigning the styling to large static data tables.\n\nAlthough David\u2019s original script performs its duty well, it is nonetheless very specific and limited in its application. It only:\n\n\n\tworks on a single table, identified by its id, with at least a single tbody section\n\tassigns a background colour\n\tallows two colours for odd and even rows\n\tacts on data cells, rather than rows, and then only if they have no class or background colour already defined\n\n\nTaking it further\n\nIn a recent project I found myself needing to apply a striped effect to a medium sized unordered list. Instead of simply modifying the Zebra Tables code for this particular case, I decided to completely recode the script to make it more generic.\n\nBeing more general purpose, the function in my splintered striper experiment is necessarily more complex. Where the original script only expected a single parameter (the id of the target table), the new function is called as follows:\n\nstriper('[parent element tag]','[parent element class or null]','[child element tag]','[comma separated list of classes]')\n\nThis new, fairly self-explanatory function:\n\n\n\ttargets any type of parent element (and, if specified, only those with a certain class)\n\tassigns two or more classes (rather than just two background colours) to the child elements inside the parent\n\tpreserves any existing classes already assigned to the child elements\n\n\nSee it in action\n\nView the demonstration page for three usage examples. For simplicity\u2019s sake, we\u2019re making the calls to the striper function from the body\u2019s onload attribute. In a real deployment situation, we would look at attaching a behaviour to the onload programmatically \u2014 just remember that, as we need to pass variables to the striper function, this would involve creating a wrapper function which would then be attached\u2026something like:\n\nfunction stripe() {\n striper('tbody','splintered','tr','odd,even');\n}\n\nwindow.onload=stripe;\n\nA final thought\n\nJust because the function is called striper does not mean that it\u2019s limited to purely applying a striped look; as it\u2019s more of a general purpose \u201calternating class assignment\u201d script, you can achieve a whole variety of effects with it.", "year": "2005", "author": "Patrick Lauke", "author_slug": "patricklauke", "published": "2005-12-15T00:00:00+00:00", "url": "https://24ways.org/2005/splintered-striper/", "topic": "code"} {"rowid": 329, "title": "Broader Border Corners", "contents": "A note from the editors: Since this article was written the CSS border-radius property has become widely supported in browsers. It should be preferred to this image technique.\n \n \n \n A quick and easy recipe for turning those single-pixel borders that the kids love so much into into something a little less right-angled.\n\nHere\u2019s the principle: We have a box with a one-pixel wide border around it. Inside that box is another box that has a little rounded-corner background image sitting snugly in one of its corners. The inner-box is then nudged out a bit so that it\u2019s actually sitting on top of the outer box. If it\u2019s all done properly, that little background image can mask the hard right angle of the default border of the outer-box, giving the impression that it actually has a rounded corner.\n\nTake An Image, Finely Chopped\n\n\n\nAdd A Sprinkle of Markup\n\n
\n

Lorem ipsum etc. etc. etc.

\n
\n\nThrow In A Dollop of CSS\n\n#content { \n border: 1px solid #c03;\n}\n\n#content p {\n background: url(corner.gif) top left no-repeat;\n position: relative;\n left: -1px;\n top: -1px;\n padding: 1em;\n margin: 0;\n}\n\nBubblin\u2019 Hot\n\n\n\tThe content div has a one-pixel wide red border around it.\n\tThe paragraph is given a single instance of the background image, created to look like a one-pixel wide arc.\n\tThe paragraph is shunted outside of the box \u2013 back one pixel and up one pixel \u2013 so that it is sitting over the div\u2019s border. The white area of the image covers up that part of the border\u2019s corner, and the arc meets up with the top and left border.\n\tBecause, in this example, we\u2019re applying a background image to a paragraph, its top margin needs to be zeroed so that it starts at the top of its container.\n\n\nEt voil\u00e0. Bon app\u00e9tit.\n\nExtra Toppings\n\n\n\tIf you want to apply a curve to each one of the corners and you run out of meaningful markup to hook the background images on to, throw some spans or divs in the mix (there\u2019s nothing wrong with this if that\u2019s the effect you truly want \u2013 they don\u2019t hurt anybody) or use some nifty DOM Scripting to put the scaffolding in for you.\n\tNote that if you\u2019ve got more than one of these relative corners, you will need to compensate for the starting position of each box which is nested in an already nudged parent.\n\tYou\u2019re not limited to one pixel wide, rounded corners \u2013 the same principles apply to thicker borders, or corners with different shapes.", "year": "2005", "author": "Patrick Griffiths", "author_slug": "patrickgriffiths", "published": "2005-12-14T00:00:00+00:00", "url": "https://24ways.org/2005/broader-border-corners/", "topic": "design"} {"rowid": 317, "title": "Putting the World into \"World Wide Web\"", "contents": "Despite the fact that the Web has been international in scope from its inception, the predominant mass of Web sites are written in English or another left-to-right language. Sites are typically designed visually for Western culture, and rely on an enormous body of practices for usability, information architecture and interaction design that are by and large centric to the Western world.\n\nThere are certainly many reasons this is true, but as more and more Web sites realize the benefits of bringing their products and services to diverse, global markets, the more demand there will be on Web designers and developers to understand how to put the World into World Wide Web.\n\nInternationalization\n\nAccording to the W3C, Internationalization is:\n\n\n\t\u201c\u2026the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.\u201d\n\n\nMany Web designers and developers have at least heard, if not read, about Internationalization. We understand that the Web is in fact worldwide, but many of us never have the opportunity to work with Internationalization. Or, when we do, think of it in purely technical terms, such as \u201cwhich character set do I use?\u201d\n\nAt first glance, it might seem to many that Internationalization is the act of making Web sites available to international audiences. And while that is in fact true, this isn\u2019t done by broad-stroking techniques and technologies. Instead, it involves a far more narrow understanding of geographical, cultural and linguistic differences in specific areas of the world. This is referred to as localization and is the act of making a Web site make sense in the context of the region, culture and language(s) the people using the site are most familiar with.\n\nInternationalization itself includes the following technical tasks:\n\n\n\tEnsuring no barrier exists to the localization of sites. Of critical importance in the planning stages of a site for Internationalized audiences, the role of the developer is to ensure that no barrier exists. This means being able to perform such tasks as enabling Unicode and making sure legacy character encodings are properly handled.\n\tPreparing markup and CSS with Internationalization in mind. The earlier in the site development process this occurs, the better. Issues such as ensuring that you can support bidirectional text, identifying language, and using CSS to support non-Latin typographic features.\n\tEnabling code to support local, regional, language or culturally related references. Examples in this category would include time/date formats, localization of calendars, numbering systems, sorting of lists and managing international forms of addresses.\n\tEmpowering the user. Sites must be architected so the user can easily choose or implement the localized alternative most appropriate to them.\n\n\nLocalization\n\nAccording to the W3C, Localization is the:\n\n\n\t\u2026adaptation of a product, application or document content to meet the language, cultural and other requirements of a specific target market (a \u201clocale\u201d).\n\n\nSo here\u2019s where we get down to thinking about the more sociological and anthropological concerns. Some of the primary localization issues are:\n\n\n\tNumeric formats. Different languages and cultures use numbering systems unlike ours. So, any time we need to use numbers, such as in an ordered list, we have to have a means of representing the accurate numbering system for the locale in question.\n\tMoney, honey! That\u2019s right. I\u2019ve got a pocketful of ugly U.S. dollars (why is U.S. money so unimaginative?). But I also have a drawer full of Japanese Yen, Australian Dollars, and Great British Pounds. Currency, how it\u2019s calculated and how it\u2019s represented is always a consideration when dealing with localization.\n\tUsing symbols, icons and colors properly. Using certain symbols or icons on sites where they might offend or confuse is certainly not in the best interest of a site that wants to sell or promote a product, service or information type. Moreover, the colors we use are surprisingly persuasive \u2013 or detrimental. Think about colors that represent death, for example. In many parts of Asia, white is the color of death. In most of the Western world, black represents death. For Catholic Europe, shades of purple (especially lavender) have represented Christ on the cross and mourning since at least Victorian times. When Walt Disney World Europe launched an ad campaign using a lot of purple and very glitzy imagery, millions of dollars were lost as a result of this seeming subtle issue. Instead of experiencing joy and celebration at the ads, the European audience, particularly the French, found the marketing to be overly American, aggressive, depressing and basically unappealing. Along with this and other cultural blunders, Disney Europe has become a well-known case study for businesses wishing to become international. By failing to understand localization differences, and how powerful color and imagery act on the human psyche, designers and developers are put to more of a disadvantage when attempting to communicate with a given culture.\n\tChoosing appropriate references to objects and ideas. What seems perfectly natural in one culture in terms of visual objects and ideas can get confused in another environment. One of my favorite cases of this has to do with Gerber baby food. In the U.S., the baby food is marketed using a cute baby on the package. Most people in the U.S. culturally do not make an immediate association that what is being represented on the label is what is inside the container. However, when Gerber expanded to Africa, where many people don\u2019t read, and where visual associations are less abstract, people made the inference that a baby on the cover of a jar of food represented what is in fact in the jar. You can imagine how confused and even angry people became. Using such approaches as a marketing ploy in the wrong locale can and will render the marketing a failure.\n\n\nAs you can see, the act of localization is one that can have profound impact on the success of a business or organization as it seeks to become available to more and more people across the globe.\n\nRethinking Design in the Context of Culture\n\nWhile well-educated designers and those individuals working specifically for companies that do a lot of localization understand these nuances, most of us don\u2019t get exposed to these ideas. Yet, we begin to see how necessary it becomes to have an awareness of not just the technical aspects of Internationalization, but the socio-cultural ones within localization.\n\nWhat\u2019s more, the bulk of information we have when it comes to designing sites typically comes from studies and work done on sites built in English and promoted to Western culture at large. We\u2019re making a critical mistake by not including diverse languages and cultural issues within our usability and information architecture studies.\n\nConsider the following design from the BBC:\n\n\n\nIn this case, we\u2019re dealing with English, which is read left to right. We are also dealing with U.K. cultural norms. Notice the following:\n\n\n\tLocation of of navigation\n\tUse of the color red\n\tUse of diverse symbols\n\tMix of symbols, icons and photos\n\tLocation of Search\n\n\nNow look at this design, which is the Arabic version of the BBC News, read right to left, and dealing with cultural norms within the Arabic-speaking world.\n\n\n\nNotice the following:\n\n\n\tLocation of of navigation (location switches to the right)\n\tUse of the color blue (blue is considered the \u201csafest\u201d global color)\n\tNo use of symbols and icons whatsoever\n\tLimitation of imagery to photos\n\tIn most cases, the photos show people, not objects\n\tLocation of Search\n\n\nAdmittedly, some choices here are more obvious than others in terms of why they were made. But one thing that stands out is that the placement of search is the same for both versions. Is this the result of a specific localization decision, or based on what we believe about usability at large? This is exactly the kind of question that designers working on localization have to seek answers to, instead of relying on popular best practices and belief systems that exist for English-only Web sites.\n\nIt\u2019s a Wide World Web After All\n\nFrom this brief article on Internationalization, it becomes apparent that the art and science of creating sites for global audiences requires a lot more preparation and planning than one might think at first glance. Developers and designers not working to address these issues specifically due to time or awareness will do well to at least understand the basic process of making sites more culturally savvy, and better prepared for any future global expansion.\n\nOne thing is certain: We not only are on a dramatic learning curve for designing and developing Web sites as it is, the need to localize sites is going to become more and more a part of the day to day work. Understanding aspects of what makes a site international and local will not only help you expand your skill set and make you more marketable, but it will also expand your understanding of the world and the people within it, how they relate to and use the Web, and how you can help make their experience the best one possible.", "year": "2005", "author": "Molly Holzschlag", "author_slug": "mollyholzschlag", "published": "2005-12-09T00:00:00+00:00", "url": "https://24ways.org/2005/putting-the-world-into-world-wide-web/", "topic": "ux"} {"rowid": 322, "title": "Introduction to Scriptaculous Effects", "contents": "Gather around kids, because this year, much like in that James Bond movie with Denise Richards, Christmas is coming early\u2026 in the shape of scrumptuous smooth javascript driven effects at your every whim.\n\nNow what I\u2019m going to do, is take things down a notch. Which is to say, you don\u2019t need to know much beyond how to open a text file and edit it to follow this article. Personally, I for instance can\u2019t code to save my life.\n\nWell, strictly speaking, that\u2019s not entirely true. If my life was on the line, and the code needed was really simple and I wasn\u2019t under any time constraints, then yeah maybe I could hack my way out of it\n\nBut my point is this: I\u2019m not a programmer in the traditional sense of the word. In fact, what I do best, is scrounge code off of other people, take it apart and then put it back together with duct tape, chewing gum and dumb blind luck.\n\nNo, don\u2019t run! That happens to be a good thing in this case. You see, we\u2019re going to be implementing some really snazzy effects (which are considerably more relevant than most people are willing to admit) on your site, and we\u2019re going to do it with the aid of Thomas Fuchs\u2019 amazing Script.aculo.us library. And it will be like stealing candy from a child.\n\nWhat Are We Doing?\n\nI\u2019m going to show you the very basics of implementing the Script.aculo.us javascript library\u2019s Combination Effects. These allow you to fade elements on your site in or out, slide them up and down and so on.\n\nWhy Use Effects at All?\n\nBefore get started though, let me just take a moment to explain how I came to see smooth transitions as something more than smoke and mirror-like effects included for with little more motive than to dazzle and make parents go \u2018uuh, snazzy\u2019.\n\nEarlier this year, I had the good fortune of meeting the kind, gentle and quite knowledgable Matt Webb at a conference here in Copenhagen where we were both speaking (though I will be the first to admit my little talk on Open Source Design was vastly inferior to Matt\u2019s talk). Matt held a talk called Fixing Broken Windows (based on the Broken Windows theory), which really made an impression on me, and which I have since then referred back to several times.\n\nYou can listen to it yourself, as it\u2019s available from Archive.org. Though since Matt\u2019s session uses many visual examples, you\u2019ll have to rely on your imagination for some of the examples he runs through during it. Also, I think it looses audio for a few seconds every once in a while.\n\nAnyway, one of the things Matt talked a lot about, was how our eyes are wired to react to movement. The world doesn\u2019t flickr. It doesn\u2019t disappear or suddenly change and force us to look for the change. Things move smoothly in the real world. They do not pop up.\n\nHow it Works\n\nOnce the necessary files have been included, you trigger an effect by pointing it at the ID of an element. Simple as that.\n\nImplementing the Effects\n\nSo now you know why I believe these effects have a place in your site, and that\u2019s half the battle. Because you see, actually getting these effects up and running, is deceptively simple.\n\nFirst, go and download the latest version of the library (as of this writing, it\u2019s version 1.5 rc5). Unzip itand open it up.\n\nNow we\u2019re going to bypass the instructions in the readme file. Script.aculo.us can do a bunch of quite advanced things, but all we really want from it is its effects. And by sidestepping the rest of the features, we can shave off roughly 80KB of unnecessary javascript, which is well worth it if you ask me.\n\nAs with Drew\u2019s article on Easy Ajax with Prototype, script.aculo.us also uses the Prototype framework by Sam Stephenson. But contrary to Drew\u2019s article, you don\u2019t have to download Prototype, as a version comes bundled with script.aculo.us (though feel free to upgrade to the latest version if you so please).\n\nSo in the unzipped folder, containing the script.aculo.us files and folder, go into \u2018lib\u2019 and grab the \u2018prototype.js\u2019 file. Move it to whereever you want to store the javascript files. Then fetch the \u2018effects.js\u2019 file from the \u2018src\u2019 folder and put it in the same place.\n\nTo make things even easier for you to get this up and running, I have prepared a small javascript snippet which does some checking to see what you\u2019re trying to do. The script.aculo.us effects are all either \u2018turn this off\u2019 or \u2018turn this on\u2019. What this snippet does, is check to see what state the target currently has (is it on or off?) and then use the necessary effect.\n\nYou can either skip to the end and download the example code, or copy and paste this code into a file manually (I\u2019ll refer to that file as combo.js):\n\nEffect.OpenUp = function(element) {\n element = $(element);\n new Effect.BlindDown(element, arguments[1] || {});\n }\n\n Effect.CloseDown = function(element) {\n element = $(element);\n new Effect.BlindUp(element, arguments[1] || {});\n }\n\n Effect.Combo = function(element) {\n element = $(element);\n if(element.style.display == 'none') { \n new Effect.OpenUp(element, arguments[1] || {}); \n }else { \n new Effect.CloseDown(element, arguments[1] || {}); \n }\n }\n\nCurrently, this code uses the BlindUp and BlindDown code, which I personally like, but there\u2019s nothing wrong with you changing the effect-type into one of the other effects available.\n\nNow, include the three files in the header of your code, like so:\n\n\n\n\n\nNow insert the element you want to use the effect on, like so:\n\n
Lorem ipsum dolor sit amet.
\n\nThe above element will start out invisible, and when triggered will be revealed. If you want it to start visible, simply remove the style parameter.\n\nAnd now for the trigger \n\nClick Here\n\nAnd that, is pretty much it. Clicking the link should unfold the DIV targeted by the effect, in this case \u2018content\u2019.\n\nEffect Options\n\nNow, it gets a bit long-haired though. The documentation for script.aculo.us is next to non-existing, and because of that you\u2019ll have to do some digging yourself to appreciate the full potentialof these effects.\n\nFirst of all, what kind of effects are available? Well you can go to the demo page and check them out, or you can open the \u2018effects.js\u2019 file and have a look around, something I recommend doing regardlessly, to gain an overview of what exactly you\u2019re dealing with.\n\nIf you dissect it for long enough, you can even distill some of the options available for the various effects. In the case of the BlindUp and BlindDown effect, which we\u2019re using in our example (as triggered from combo.js), one of the things that would be interesting to play with would be the duration of the effect. If it\u2019s too long, it will feel slow and unresponsive. Too fast and it will be imperceptible.\n\nYou set the options like so:\n\nClick Here\n\nThe change from the previous link being the inclusion of , {duration: .2}. In this case, I have lowered the duration to 0.2 second, to really make it feel snappy.\n\nYou can also go all-out and turn on all the bells and whistles of the Blind effect like so (slowed down to a duration of three seconds so you can see what\u2019s going on):\n\nClick Here\n\nConclusion\n\nAnd that\u2019s pretty much it. The rest is a matter of getting to know the rest of the effects and their options as well as finding out just when and where to use them. Remember the ancient Chinese saying: Less is more.\n\nDownload Example\n\nI have prepared a very basic example, which you can download and use as a reference point.", "year": "2005", "author": "Michael Heilemann", "author_slug": "michaelheilemann", "published": "2005-12-12T00:00:00+00:00", "url": "https://24ways.org/2005/introduction-to-scriptaculous-effects/", "topic": "code"} {"rowid": 319, "title": "Avoiding CSS Hacks for Internet Explorer", "contents": "Back in October, IEBlog issued a call to action, asking developers to clean up their CSS hacks for IE7 testing. Needless to say, a lot of hubbub ensued\u2026 both on IEBlog and elsewhere. My contribution to all of the noise was to suggest that developers review their code and use good CSS hacks. But what makes a good hack?\n\nTantek \u00c7elik, the Godfather of CSS hacks, gave us the answer by explaining how CSS hacks should be designed. In short, they should (1) be valid, (2) target only old/frozen/abandoned user-agents/browsers, and (3) be ugly. Tantek also went on to explain that using a feature of CSS is not a hack.\n\nNow, I\u2019m not a frequent user of CSS hacks, but Tantek\u2019s post made sense to me. In particular, I felt it gave developers direction on how we should be coding to accommodate that sometimes troublesome browser, Internet Explorer. But what I\u2019ve found, through my work with other developers, is that there is still much confusion over the use of CSS hacks and IE. Using examples from the code I\u2019ve seen recently, allow me to demonstrate how to clean up some IE-specific CSS hacks.\n\nThe two hacks that I\u2019ve found most often in the code I\u2019ve seen and worked with are the star html bug and the underscore hack. We know these are both IE-specific by checking Kevin Smith\u2019s CSS Filters chart. Let\u2019s look at each of these hacks and see how we can replace them with the same CSS feature-based solution.\n\nThe star html bug\n\nThis hack violates Tantek\u2019s second rule as it targets current (and future) UAs. I\u2019ve seen this both as a stand alone rule, as well as an override to some other rule in a style sheet. Here are some code samples:\n\n* html div#header {margin-top:-3px;}\n.promo h3 {min-height:21px;}\n* html .promo h3 {height:21px;}\n\nThe underscore hack\n\nThis hack violates Tantek\u2019s first two rules: it\u2019s invalid (according to the W3C CSS Validator) and it targets current UAs. Here\u2019s an example:\n\nol {padding:0; _padding-left:5px;}\n\nUsing child selectors\n\nWe can use the child selector to replace both the star html bug and underscore hack. Here\u2019s how:\n\n Write rules with selectors that would be successfully applied to all browsers. This may mean starting with no declarations in your rule!\n\ndiv#header {}\n.promo h3 {}\nol {padding:0;}\n\n \nTo these rules, add the IE-specific declarations.\n\ndiv#header {margin-top:-3px;}\n.promo h3 {height:21px;}\nol {padding:0 0 0 5px;}\n\n \nAfter each rule, add a second rule. The selector of the second rule must use a child selector. In this new rule, correct any IE-specific declarations previously made.\n\ndiv#header {margin-top:-3px;}\nbody > div#header {margin-top:0;}\n\n.promo h3 {height:21px;}\n.promo > h3 {height:auto; min-height:21px;}\n\nol {padding:0 0 0 5px;}\nhtml > body ol {padding:0;}\n\n \n\nVoil\u00e0 \u2013 no more hacks! There are a few caveats to this that I won\u2019t go into\u2026 but assuming you\u2019re operating in strict mode and barring any really complicated stuff you\u2019re doing in your code, your CSS will still render perfectly across browsers. And while this may make your CSS slightly heftier in size, it should future-proof it for IE7 (or so I hope). Happy holidays!", "year": "2005", "author": "Kimberly Blessing", "author_slug": "kimberlyblessing", "published": "2005-12-17T00:00:00+00:00", "url": "https://24ways.org/2005/avoiding-css-hacks-for-internet-explorer/", "topic": "code"} {"rowid": 321, "title": "Tables with Style", "contents": "It might not seem like it but styling tabular data can be a lot of fun. From a semantic point of view, there are plenty of elements to tie some style into. You have cells, rows, row groups and, of course, the table element itself. Adding CSS to a paragraph just isn\u2019t as exciting.\n\nWhere do I start?\n\nFirst, if you have some tabular data (you know, like a spreadsheet with rows and columns) that you\u2019d like to spiffy up, pop it into a table \u2014 it\u2019s rightful place!\n\nTo add more semantics to your table \u2014 and coincidentally to add more hooks for CSS \u2014 break up your table into row groups. There are three types of row groups: the header (thead), the body (tbody) and the footer (tfoot). You can only have one header and one footer but you can have as many table bodies as is appropriate.\n\nSample table example\n\nInspiration\n\nTable Striping\n\nTo improve scanning information within a table, a common technique is to style alternating rows. Also known as zebra tables. Whether you apply it using a class on every other row or turn to JavaScript to accomplish the task, a handy-dandy trick is to use a semi-transparent PNG as your background image. This is especially useful over patterned backgrounds. \n\ntbody tr.odd td {\n background:transparent url(background.png) repeat top left;\n }\n\n * html tbody tr.odd td {\n background:#C00;\n filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(\n src='background.png', sizingMethod='scale');\n }\n\nWe turn off the default background and apply our PNG hack to have this work in Internet Explorer. \n\nStyling Columns\n\nDid you know you could style a column? That\u2019s right. You can add special column (col) or column group (colgroup) elements. With that you can add border or background styles to the column.\n\n\n \n \n \n ...\n\nCheck out the example.\n\nFun with Backgrounds\n\nPop in a tiled background to give your table some character! Internet Explorer\u2019s PNG hack unfortunately only works well when applied to a cell.\n\nTo figure out which background will appear over another, just remember the hierarchy:\n\n (bottom) Table \u2192 Column \u2192 Row Group \u2192 Row \u2192 Cell (top)\n\nThe Future is Bright\n\nOnce browser-makers start implementing CSS3, we\u2019ll have more power at our disposal. Just with :first-child and :last-child, you can pull off a scalable version of our previous table with rounded corners and all \u2014 unfortunately, only Firefox manages to pull this one off successfully. And the selector the masses are clamouring for, nth-child, will make zebra tables easy as eggnog.", "year": "2005", "author": "Jonathan Snook", "author_slug": "jonathansnook", "published": "2005-12-19T00:00:00+00:00", "url": "https://24ways.org/2005/tables-with-style/", "topic": "code"} {"rowid": 324, "title": "Debugging CSS with the DOM Inspector", "contents": "An Inspector Calls\n\nThe larger your site and your CSS becomes, the more likely that you will run into bizarre, inexplicable problems. Why does that heading have all that extra padding? Why is my text the wrong colour? Why does my navigation have a large moose dressed as Noel Coward on top of all the links? \n\nPerhaps you work in a collaborative environment, where developers and other designers are adding code? In which case, the likelihood of CSS strangeness is higher.\n\nYou need to debug. You need Firefox\u2019s wise-guy know-it-all, the DOM Inspector. \n\nThe DOM Inspector knows where everything is in your layout, and more importantly, what causes it to look the way it does. So without further ado, load up any css based site in your copy of Firefox (or Flock for that matter), and launch the DOM Inspector from the Tools menu.\n\nThe inspector uses two main panels \u2013 the left to show the DOM tree of the page, and the right to show you detail:\n\n\n\nThe Inspector will look at whatever site is in the front-most window or tab, but you can also use it without another window. Type in a URL at the top (A), press \u2018Inspect\u2019 (B) and a third panel appears at the bottom, with the browser view. I find this layout handier than looking at a window behind the DOM Inspector.\n\nStep 1 \u2013 find your node!\n\nEach element on your page \u2013 be it a HTML tag or a piece of text, is called a \u2018node\u2019 of the DOM tree. These nodes are all listed in the left hand panel, with any ID or CLASS attribute values next to them. When you first look at a page, you won\u2019t see all those yet. Nested HTML elements (such as a link inside a paragraph) have a reveal triangle next to their name, clicking this takes you one level further down. \n\nThis can be fine for finding the node you want to look at, but there are easier ways. Say you have a complex rounded box technique that involves 6 nested DIVs? You\u2019d soon get tired of clicking all those triangles to find the element you want to inspect. Click the top left icon \u00a9 \u2013 \u201cFind a node to inspect by clicking on it\u201d and then select the area you want to inspect. Boom! All that drilling down the DOM tree has been done for you! Huzzah!\n\nIf you\u2019re looking for an element that you know has an ID (such as