{"rowid": 170, "title": "A Pet Project is For Life, Not Just for Christmas", "contents": "I\u2019m excited: as December rolls on, I\u2019m winding down from client work and indulging in a big pet project I\u2019ve been dreaming up for quite some time, with the aim of releasing it early next year. I\u2019ve always been a bit of a sucker for pet projects and currently have a few in the works: the big one, two collaborations with friends, and my continuing (and completely un-web-related) attempt at music. But when I think about the other designers and developers out there whose work I admire, one thing becomes obvious: they\u2019ve all got pet projects! Look around the web and you\u2019ll see that anyone worth their salt has some sort of side project on the go. If you don\u2019t have yours yet, now\u2019s the time!\n\nHave a pet project to collaborate with your friends\n\nIt\u2019s not uncommon to find me staring at my screen, looking at beautiful websites my friends have made, grinning inanely because I feel so honoured to know such talented individuals. But one thing really frustrates me: I hardly ever get to work with these people! Sure, there are times when it\u2019s possible to do so, but due to various project situations, it\u2019s a rarity.\n\nSo, in order to work with my friends, I\u2019ve found the best way is to instigate the collaboration outside of client work; in other words, have a pet project together! Free from the hard realities of budgets, time restraints, and client demands, you and your friends can come up with something purely for your own pleasures. If you\u2019ve been looking for an excuse to work with other designers or developers whose work you love, the pet project is that excuse. They don\u2019t necessarily have to be friends, either: if the respect is mutual, it can be a great way of breaking the ice and getting to know someone. \n\n Figure 1: A forthcoming secret love-child from myself and Tim Van Damme\n\nHave a pet project to escape from your day job\n\nWe all like to moan about our clients and bosses, don\u2019t we? But if leaving your job or firing your evil client just isn\u2019t an option, why not escape from all that and pour your creative energies into something you genuinely enjoy? \n\nIt\u2019s not just about reacting to negativity, either: a pet project is a great way to give yourself a bit of variety. As web designers, our day-to-day work forces us to work within a set of web-related contraints and sometimes it can be demoralising to spend so many hours fixing IE bugs. The perfect antidote? Go and do some print design! If it\u2019s not possible in your day job or client work, the pet project is the perfect place to exercise your other creative muscles. Yes, print design (or your chosen alternative) has its own constraints, but if they\u2019re different to those you experience on a daily basis, it\u2019ll be a welcome relief and you\u2019ll return to your regular work feeling refreshed.\n\n Figure 2: Ligature, Loop & Stem, from Scott Boms & Luke Dorny\n\nHave a pet project to fulfill your own needs\n\nMany pet projects come into being because the designers and/or developers behind them are looking for a tool to accomplish a task and find that it doesn\u2019t exist, thus prompting them to create their own solution. In fact, the very app I\u2019m using to write this article \u2014 Ommwriter, from Herraiz Soto & Co \u2014 was originally a tool they\u2019d created for their internal staff, before releasing it to the public so that it could be enjoyed by others.\n\nJust last week, Tina Roth Eisenberg launched Teux Deux, a pet project she\u2019d designed to meet her own requirements for a to-do list, having found that no existing apps fulfilled her needs. Oh, and it was a collaboration with her studio mate Cameron. Remember what I was saying about working with your friends?\n\n Figure 3: Teux Deux, the GTD pet project that launched just last week\n\nHave a pet project to help people out\n\nOmmwriter and Teux Deux are free for anyone to use. Let\u2019s just think about that for a moment: the creators have invested their time and effort in the project, and then given it away to be used by others. That\u2019s very cool and something we\u2019re used to seeing a lot of in the web community (how lucky we are)! People love free stuff and giving away the fruits of your labour will earn you major kudos. Of course, there\u2019s nothing wrong with making some money, either \u2014 more on that in a second.\n\n Figure 4: Dan Rubin\u2018s extremely helpful Make Photoshop Faster\n\nHave a pet project to raise your profile\n\nSo, giving away free stuff earns you kudos. And kudos usually helps you raise your profile in the industry. We all like a bit of shameless fame, don\u2019t we? But seriously, if you want to become well known, make something cool. It could be free (to buy you the love and respect of the community) or it could be purchasable (if you\u2019ve made something that\u2019s cool enough to deserve hard-earned cash), but ultimately it needs to be something that people will love. \n\n Figure 5: Type designer Jos Buivenga has shot to fame thanks to his beautiful typefaces and \u2018freemium\u2019 business model\n\nIf you\u2019re a developer with no design skills, team up with a good designer so that the design community appreciate its aesthetic. If you\u2019re a designer with no development skills, team up with a good developer so that it works. Oh, and not that I\u2019d recommend you ever do this for selfish reasons, but collaborating with someone you admire \u2014 whose work is well-respected by the community \u2014 will also help raise your profile.\n\nHave a pet project to make money\n\nIn spite of our best hippy-esque intentions to give away free stuff to the masses, there\u2019s also nothing wrong with making a bit of money from your pet project. In fact, if your project involves you having to make a considerable financial investment, it\u2019s probably a good idea to try and recoup those costs in some way.\n\n Figure 6: The success of Shaun Inman\u2018s various pet projects \u2014 Mint, Fever, Horror Vacui, etc. \u2014 have allowed him to give up client work entirely.\n\nA very common way to do that in both the online and offline worlds is to get some sort of advertising. For a slightly different approach, try contacting a company who are relevant to your audience and ask them if they\u2019d be interesting in sponsoring your project, which would usually just mean having their brand associated with yours in some way. This is still a form of advertising but tends to allow for a more tasteful implementation, so it\u2019s worth pursuing. \n\nAdvertising is a great way to cover your own costs and keep things free for your audience, but when costs are considerably higher (like if you\u2019re producing a magazine with high production values, for instance), there\u2019s nothing wrong with charging people for your product. But, as I mentioned above, you\u2019ve got to be positive that it\u2019s worth paying for!\n\nHave a pet project just for fun\n\nSometimes there\u2019s a very good reason for having a pet project \u2014 and sometimes even a viable business reason \u2014 but actually you don\u2019t need any reason at all. Wanting to have fun is just as worthy a motivation, and if you\u2019re not going to have fun doing it, then what\u2019s the point? Assuming that almost all pet projects are designed, developed, written, printed, marketed and supported in our free time, why not do something enjoyable?\n\n Figure 7: Jessica Hische\u2018s beautiful Daily Drop Cap\n\nIn conclusion\n\nThe fact that you\u2019re reading 24 ways shows that you have a passion for the web, and that\u2019s something I\u2019m happy to see in abundance throughout our community. Passion is a term that\u2019s thrown about all over the place, but it really is evident in the work that people do. It\u2019s perhaps most evident, however, in the pet projects that people create. Don\u2019t forget that the very site you\u2019re reading this article on is\u2026 a pet project.\n\nIf you\u2019ve yet to do so, make it a new year\u2019s resolution for 2010 to have your own pet project so that you can collaborate with your friends, escape from your day job, fulfil your own needs, help people out, raise your profile, make money, and \u2014 above all \u2014 have fun.", "year": "2009", "author": "Elliot Jay Stocks", "author_slug": "elliotjaystocks", "published": "2009-12-18T00:00:00+00:00", "url": "https://24ways.org/2009/a-pet-project-is-for-life-not-just-for-christmas/", "topic": "business"} {"rowid": 179, "title": "Have a Field Day with HTML5 Forms", "contents": "Forms are usually seen as that obnoxious thing we have to markup and style. I respectfully disagree: forms (on a par with tables) are the most exciting thing we have to work with.\n\nHere we\u2019re going to take a look at how to style a beautiful HTML5 form using some advanced CSS and latest CSS3 techniques. I promise you will want to style your own forms after you\u2019ve read this article.\n\nHere\u2019s what we\u2019ll be creating:\n\n The form. (Icons from Chalkwork Payments)\n\nMeaningful markup\n\nWe\u2019re going to style a simple payment form. There are three main sections on this form:\n\n\n\tThe person\u2019s details\n\tThe address details\n\tThe credit card details\n\n\nWe are also going to use some of HTML5\u2019s new input types and attributes to create more meaningful fields and use less unnecessary classes and ids:\n\n\n\temail, for the email field\n\ttel, for the telephone field\n\tnumber, for the credit card number and security code\n\trequired, for required fields\n\tplaceholder, for the hints within some of the fields\n\tautofocus, to put focus on the first input field when the page loads\n\n\nThere are a million more new input types and form attributes on HTML5, and you should definitely take a look at what\u2019s new on the W3C website. Hopefully this will give you a good idea of how much more fun form markup can be.\n\nA good foundation\n\nEach section of the form will be contained within its own fieldset. In the case of the radio buttons for choosing the card type, we will enclose those options in another nested fieldset.\n\nWe will also be using an ordered list to group each label / input pair. This will provide us with a (kind of) semantic styling hook and it will also make the form easier to read when viewing with no CSS applied:\n\n The unstyled form\n\nSo here\u2019s the markup we are going to be working with:\n\n
\n\nMaking things look nice\n\nFirst things first, so let\u2019s start by adding some defaults to our form by resetting the margins and paddings of the elements and adding a default font to the page:\n\nhtml, body, h1, form, fieldset, legend, ol, li {\n\tmargin: 0;\n\tpadding: 0;\n}\nbody {\n\tbackground: #ffffff;\n\tcolor: #111111;\n\tfont-family: Georgia, \"Times New Roman\", Times, serif;\n\tpadding: 20px;\n}\n\nNext we are going to style the form element that is wrapping our fields:\n\nform#payment {\n\tbackground: #9cbc2c;\n\t-moz-border-radius: 5px;\n\t-webkit-border-radius: 5px;\n\tborder-radius: 5px;\n\tpadding: 20px;\n\twidth: 400px;\n}\n\nWe will also remove the border from the fieldset and apply some bottom margin to it. Using the :last-of-type pseudo-class, we remove the bottom margin of the last fieldset \u2014 there is no need for it:\n\nform#payment fieldset {\n\tborder: none;\n\tmargin-bottom: 10px;\n}\nform#payment fieldset:last-of-type {\n\tmargin-bottom: 0;\n}\n\nNext we\u2019ll make the legends big and bold, and we will also apply a light-green text-shadow, to add that little extra special detail:\n\nform#payment legend {\n\tcolor: #384313;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\tpadding-bottom: 10px;\n\ttext-shadow: 0 1px 1px #c0d576;\n}\n\nOur legends are looking great, but how about adding a clear indication of how many steps our form has? Instead of adding that manually to every legend, we can use automatically generated counters.\n\nTo add a counter to an element, we have to use either the :before or :after pseudo-elements to add content via CSS. We will follow these steps:\n\n\n\tcreate a counter using the counter-reset property on the form element\n\tcall the counter with the content property (using the same name we\u2019ve created before)\n\twith the counter-incremet property, indicate that for each element that matches our selector, that counter will be increased by 1\n\n\nform#payment > fieldset > legend:before {\n\tcontent: \"Step \" counter(fieldsets) \": \";\n\tcounter-increment: fieldsets;\n}\n\nFinally, we need to change the style of the legend that is part of the radio buttons group, to make it look like a label:\n\nform#payment fieldset fieldset legend {\n\tcolor: #111111;\n\tfont-size: 13px;\n\tfont-weight: normal;\n\tpadding-bottom: 0;\n}\n\nStyling the lists\n\nFor our list elements, we\u2019ll just add some nice rounded corners and semi-transparent border and background. Because we are using RGBa colors, we should provide a fallback for browsers that don\u2019t support them (that comes before the RBGa color). For the nested lists, we will remove these properties because they would be overlapping:\n\nform#payment ol li {\n\tbackground: #b9cf6a;\n\tbackground: rgba(255,255,255,.3);\n\tborder-color: #e3ebc3;\n\tborder-color: rgba(255,255,255,.6);\n\tborder-style: solid;\n\tborder-width: 2px;\n\t-moz-border-radius: 5px;\n\t-webkit-border-radius: 5px;\n\tborder-radius: 5px;\n\tline-height: 30px;\n\tlist-style: none;\n\tpadding: 5px 10px;\n\tmargin-bottom: 2px;\n}\nform#payment ol ol li {\n\tbackground: none;\n\tborder: none;\n\tfloat: left;\n}\n\nForm controls\n\nNow we only need to style our labels, inputs and the button element.\n\nAll our labels will look the same, with the exception of the one for the radio elements. We will float them to the left and give them a width.\n\nFor the credit card type labels, we will add an icon as the background, and override some of the properties that aren\u2019t necessary. We will be using the attribute selector to specify the background image for each label \u2014 in this case, we use the for attribute of each label.\n\nTo add an extra user-friendly detail, we\u2019ll add a cursor: pointer to the radio button labels on the :hover state, so the user knows that he can simply click them to select that option.\n\nform#payment label {\n\tfloat: left;\n\tfont-size: 13px;\n\twidth: 110px;\n}\nform#payment fieldset fieldset label {\n\tbackground:none no-repeat left 50%;\n\tline-height: 20px;\n\tpadding: 0 0 0 30px;\n\twidth: auto;\n}\nform#payment label[for=visa] {\n\tbackground-image: url(visa.gif);\n}\nform#payment label[for=amex] {\n\tbackground-image: url(amex.gif);\n}\nform#payment label[for=mastercard] {\n\tbackground-image: url(mastercard.gif);\n}\nform#payment fieldset fieldset label:hover {\n\tcursor: pointer;\n}\n\nAlmost there! Now onto the input elements. Here we want to match all inputs, except for the radio ones, and the textarea. For that we will use the negation pseudo-class (:not()). With it we can target all input elements except for the ones with type of radio.\n\nWe will also make sure to add some :focus styles and add the appropriate styling for the radio inputs:\n\nform#payment input:not([type=radio]),\nform#payment textarea {\n\tbackground: #ffffff;\n\tborder: none;\n\t-moz-border-radius: 3px;\n\t-webkit-border-radius: 3px;\n\t-khtml-border-radius: 3px;\n\tborder-radius: 3px;\n\tfont: italic 13px Georgia, \"Times New Roman\", Times, serif;\n\toutline: none;\n\tpadding: 5px;\n\twidth: 200px;\n}\nform#payment input:not([type=submit]):focus,\nform#payment textarea:focus {\n\tbackground: #eaeaea;\n}\nform#payment input[type=radio] {\n\tfloat: left;\n\tmargin-right: 5px;\n}\n\nAnd finally we come to our submit button. To it, we will just add some nice typography and text-shadow, align it to the center of the form and give it some background colors for its different states:\n\nform#payment button {\n\tbackground: #384313;\n\tborder: none;\n\t-moz-border-radius: 20px;\n\t-webkit-border-radius: 20px;\n\t-khtml-border-radius: 20px;\n\tborder-radius: 20px;\n\tcolor: #ffffff;\n\tdisplay: block;\n\tfont: 18px Georgia, \"Times New Roman\", Times, serif;\n\tletter-spacing: 1px;\n\tmargin: auto;\n\tpadding: 7px 25px;\n\ttext-shadow: 0 1px 1px #000000;\n\ttext-transform: uppercase;\n}\nform#payment button:hover {\n\tbackground: #1e2506;\n\tcursor: pointer;\n}\n\nAnd that\u2019s it! See the completed form.\n\nThis form will not look the same on every browser. Internet Explorer and Opera don\u2019t support border-radius (at least not for now); the new input types are rendered as just normal inputs on some browsers; and some of the most advanced CSS, like the counter, :last-of-type or text-shadow are not supported on some browsers. But that doesn\u2019t mean you can\u2019t use them right now, and simplify your development process. My gift to you!", "year": "2009", "author": "Inayaili de Le\u00f3n Persson", "author_slug": "inayailideleon", "published": "2009-12-03T00:00:00+00:00", "url": "https://24ways.org/2009/have-a-field-day-with-html5-forms/", "topic": "code"} {"rowid": 173, "title": "Real Fonts and Rendering: The New Elephant in the Room", "contents": "My friend, the content strategist Kristina Halvorson, likes to call content \u201cthe elephant in the room\u201d of web design. She means it\u2019s the huge problem that no one on the web development team or client side is willing to acknowledge, face squarely, and plan for. \n\nA typical web project will pass through many helpful phases of research, and numerous beneficial user experience design iterations, while the content\u2014which in most cases is supposed to be the site\u2019s primary focus\u2014gets handled haphazardly at the end. Hence, elephant in the room, and hence also artist Kevin Cornell\u2019s recent use of elephantine imagery to illustrate A List Apart articles on the subject. But I digress.\n\nWithout discounting the primacy of the content problem, we web design folk have now birthed ourselves a second lumbering mammoth, thanks to our interest in \u201creal fonts on the web\u201c (the unfortunate name we\u2019ve chosen for the recent practice of serving web-licensed fonts via CSS\u2019s decade-old @font-face declaration\u2014as if Georgia, Verdana, and Times were somehow unreal). \n\nFor the fact is, even bulletproof and mo\u2019 bulletproofer @font-face CSS syntax aren\u2019t really bulletproof if we care about looks and legibility across browsers and platforms.\n\nHyenas in the Breakfast Nook\n\nThe problem isn\u2019t just that foundries have yet to agree on a standard font format that protects their intellectual property. And that, even when they do, it will be a while before all browsers support that standard\u2014leaving aside the inevitable politics that impede all standardization efforts. Those are problems, but they\u2019re not the elephant. Call them the coyotes in the room, and they\u2019re slowly being tamed.\n\nNor is the problem that workable, scalable business models (of which Typekit\u2018s is the most visible and, so far, the most successful) are still being shaken out and tested. The quality and ease of use of such services, their stability on heavily visited sites (via massively backed-up server clusters), and the fairness and sustainability of their pricing will determine how licensing and serving \u201creal fonts\u201d works in the short and long term for the majority of designer/developers.\n\nNor is our primary problem that developers with no design background may serve ugly or illegible fonts that take forever to load, or fonts that take a long time to download and then display as ordinary system fonts (as happens on, say, about.validator.nu). Ugliness and poor optimization on the web are nothing new. That support for @font-face in Webkit and Mozilla browsers (and for TrueType fonts converted to Embedded OpenType in Internet Explorer) adds deadly weapons to the non-designer\u2019s toolkit is not the technology\u2019s fault. JavaScript and other essential web technologies are equally susceptible to abuse. \n\nBeauty is in the Eye of the Rendering Engine\n\nNo, the real elephant in the room\u2014the thing few web developers and no \u201cweb font\u201d enthusiasts are talking about\u2014has to do with legibility (or lack thereof) and aesthetics (or lack thereof) across browsers and platforms. Put simply, even fonts optimized for web use (which is a whole thing: ask a type designer) will not look good in every browser and OS. That\u2019s because every browser treats hinting differently, as does every OS, and every OS version. \n\nFirefox does its own thing in both Windows and Mac OS, and Microsoft is all over the place because of its need to support multiple generations of Windows and Cleartype and all kinds of hardware simultaneously. Thus \u201creal type\u201d on a single web page can look markedly different, and sometimes very bad, on different computers at the same company. If that web page is your company\u2019s, your opinion of \u201cweb fonts\u201d may suffer, and rightfully. (The advantage of Apple\u2019s closed model, which not everyone likes, is that it allows the company to guarantee the quality and consistency of user experience.) \n\nAs near as my font designer friends and I can make out, Apple\u2019s Webkit in Safari and iPhone ignores hinting and creates its own, which Apple thinks is better, and which many web designers think of as \u201cwhat real type looks like.\u201d The forked version of Webkit in Chrome, Android, and Palm Pre also creates its own hinting, which is close to iPhone\u2019s\u2014close enough that Apple, Palm, and Google could propose it as a standard for use in all browsers and platforms. Whether Firefox would embrace a theoretical Apple and Google standard is open to conjecture, and I somehow have difficulty imagining Microsoft buying in\u2014even though they know the web is more and more mobile, and that means more and more of their customers are viewing web content in some version of Webkit.\n\nThe End of Simple\n\nThere are ways around this ugly type ugliness, but they involve complicated scripting and sniffing\u2014the very nightmares from which web standards and the simplicity of @font-face were supposed to save us. I don\u2019t know that even mighty Typekit has figured out every needed variation yet (although, working with foundries, they probably will). \n\nFor type foundries, the complexity and expense of rethinking classic typefaces to survive in these hostile environments may further delay widespread adoption of web fonts and the resolution of licensing and formatting issues. The complexity may also force designers (even those who prefer to own) to rely on a hosted rental model simply to outsource and stay current with the detection and programming required.\n\nForgive my tears. I stand in a potter\u2019s field of ideas like \u201cKeep it simple,\u201d by a grave whose headstone reads \u201cWrite once, publish everywhere.\u201d", "year": "2009", "author": "Jeffrey Zeldman", "author_slug": "jeffreyzeldman", "published": "2009-12-22T00:00:00+00:00", "url": "https://24ways.org/2009/real-fonts-and-rendering/", "topic": "design"} {"rowid": 169, "title": "Incite A Riot", "contents": "Given its relatively limited scope, HTML can be remarkably expressive. With a bit of lateral thinking, we can mark up content such as tag clouds and progress meters, even when we don\u2019t have explicit HTML elements for those patterns.\n\nSuppose we want to mark up a short conversation:\n\n \n Alice: I think Eve is watching. \n\n Bob: This isn\u2019t a cryptography tutorial \u2026we\u2019re in the wrong example!\n \n\n\nA note in the the HTML 4.01 spec says it\u2019s okay to use a definition list:\n\n\n\tAnother application of DL, for example, is for marking up dialogues, with each DT naming a speaker, and each DD containing his or her words.\n\n\nThat would give us:\n\nThe buck stops here.
\n\nFor longer quotes, the blockquote element might be more appropriate. In a conversation, where the order matters, I think an ordered list would make a good containing element for this pattern:\n\nI think Eve is watching.
This isn't a cryptography tutorial ...we're in the wrong example!
Name | \n\t\t\tCards sent | \n\t\t\tCards received | \n\t\t\tCards written but not sent | \n\t\t
---|---|---|---|
Ann | \n\t\t\t40 | \n\t\t\t28 | \n\t\t\t4 | \n\t\t
Joe | \n\t\t\t2 | \n\t\t\t27 | \n\t\t\t29 | \n\t\t
Paul | \n\t\t\t5 | \n\t\t\t35 | \n\t\t\t2 | \n\t\t
Louise | \n\t\t\t65 | \n\t\t\t65 | \n\t\t\t0 | \n\t\t
please refer to the examples sent for reference\" \n\t\t\t\t} \n\t\t\t} \n\t\t} \n\t]\n}\n\nThe first four lines are just a little bit of meta data so we remember what this test was all about when we look at it again in the future, or indeed if it ever breaks. The tests are the really cool parts and firstly you\u2019ll notice that it\u2019s an array \u2013 we\u2019re only going to show one example test here but there is no reason why you can\u2019t place in as many as you want. I\u2019ll explain what each of the lines in the example test means:\n\n\n\tname \u2013 short test name, I use this in pass/fail messaging later\n\tdescription \u2013 meta data for future reference\n\tselector \u2013 the root HTML element from which your HTML will be searched\n\tmessage \u2013 what the app will alert if the initial selector isn\u2019t found\n\tcheck_for \u2013 a wrapper to hold inner tests \u2013 those run if the initial selector does match\n\t\n\t\tcontains \u2013 the type of check, we\u2019re checking that the selector contains specified elements\n\t\t\n\t\t\telements \u2013 the HTML elements we are searching for\n\t\t\tmessage \u2013 a message for when these don\u2019t match (VAR is substituted when it\u2019s appended to the page with the name of any elements that don\u2019t exist)\n\t\t\n\t\t\n\t\t\n\nIt\u2019s very important to pass the function valid JSON (JSONLint is a great tool for this) otherwise you might get a console showing no tests have even been run. \n\nThe JavaScript that makes this helpful\n\nAgain, this code should never hit a production server so I\u2019ve kept it external. This also means that the only thing that\u2019s needed to be done by the implementation team when they are ready to build is that they delete this code.\n\n\n\n\n\u201cView the full JavaScript:/examples/self-testing-pages-with-javascript/js/tests/test_suite.js\n\nThe init function appends the test console to the page and inserts the CSS file required to style it (you don\u2019t need to use pictures of me when tests pass and fail though I see no reason why you shouldn\u2019t), goes and grabs the JSON file referenced and parses it. The methods to pass (tests_pass) and fail (haz_fail) the test I hope are pretty self-explanatory as is the one which creates the test summary once everything has been run (create_summary).\n\nThe two interesting functions are init_tests and confirm_html.\n\ninit_tests\n\ninit_tests:function(i,obj) {\n\tvar $master_elm = $(obj.selector);\n\tsleuth.test_page.$logger.append(\"
\");\n\tvar $container = $('#test_' + i);\n\tif (!$master_elm.length) {\n\t\tvar err_sum = obj.message.replace(/VAR/gi, obj.selector);\n\t\tsleuth.test_page.haz_failed(err_sum, $container);\n\t\treturn;\n\t}\n\tif (obj.check_for) {\n\t\t$.each(obj.check_for,function(key, value){\n\t\t\tsleuth.test_page.assign_checks($master_elm, $container, key, value);\n\t\t});\n\t} else {\n\t\tsleuth.test_page.tests_passed($container);\n\t\treturn;\n\t}\n}\n\nThe function gets sent the number of the current iteration (used to create a unique id for its test summary) and the current object that contains the data we\u2019re testing against as parameters.\n\nWe grab a reference to the root element and this is used (pretty much in the example shown right at the start of this article) and its length is checked. If the length is positive we know we can continue to the inner tests (if they exist) but if not we fail the test and don\u2019t go any further. We append the error to the test console for everyone to see.\n\nIf we pass the initial check we send the reference to the root element, message contains and the inner object to a function that in this example sends us on to confirm_html (if we had a more complex test suite it would do a lot more). \n\nconfirm_html\n\nconfirm_html:function(target_selector, error_elm, obj) {\n\tvar missing_elms = [];\n\t$.each(obj.elements, function(i, val) {\n\t\tif (!target_selector.find(val).length) {\n\t\t\tmissing_elms.push(val);\n\t\t}\t\n\t});\n\tif (missing_elms.length) {\n\t\tvar file_list = missing_elms.join('Please wait while we do what we do best.
\n\nLooks semantic enough to me! Here\u2019s the basic HTML I\u2019m using to position the element in the center of the screen, and make the text inside it disappear:\n\n#spinner {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 50%;\n\tmargin: -100px 0 0 -100px;\n\theight: 200px;\n\twidth: 200px;\n\ttext-indent: 250px;\n\twhite-space: nowrap;\n\toverflow: hidden;\n}\n\nCool, but now we don\u2019t see anything. Let\u2019s pull rabbit number one out of the hat: -webkit-mask-image (accompanied by the previously mentioned transparent PNG image):\n\n#spinner {\n\t...\n\t-webkit-mask-image: url(../img/spinner.png);\n}\n\nBy now you should be feeling like a magician already. Oh, wait, we still have a blank screen, looks like we left something in the hat (tip: not rabbit droppings):\n\n#spinner {\n\t...\n\t-webkit-mask-image: url(../img/spinner.png);\n\tbackground-color: #000;\n}\n\nNice! What we\u2019ve done right here is telling the element to clip onto the PNG. It\u2019s a lot like clipping layers in Photoshop. So, spinners, they move, right? Into the hat again, and look what we pull out this time: CSS animations!\n\n#spinner {\n\t...\n\t-webkit-mask-image: url(../img/spinner.png);\n\tbackground-color: #000;\n\t-webkit-animation-name: spinnerRotate;\n\t-webkit-animation-duration: 2s;\n\t-webkit-animation-iteration-count: infinite;\n\t-webkit-animation-timing-function: linear;\n}\n\nSome explanation:\n\n\n\t-webkit-animation-name: Name of the animation we\u2019ll be defining later.\n\t-webkit-animation-duration: The timespan of the animation.\n\t-webkit-animation-iteration-count: Repeat once, a defined number of times or infinitely?\n\t-webkit-animation-timing-function: Linear is the one you\u2019ll be using mostly. Other options are ease-in, ease-out, ease-in-out\u2026\n\n\nLet\u2019s define spinnerRotate:\n\n@-webkit-keyframes spinnerRotate {\n\tfrom {\n\t\t-webkit-transform:rotate(0deg);\n\t}\n\tto {\n\t\t-webkit-transform:rotate(360deg);\n\t}\n}\n\nEn Anglais: Rotate #spinner starting at 0 degrees, ending at 360 degrees, over a timespan of 2 seconds, at a constant speed, and keep repeating this animation forever.\n\nThat\u2019s it! See it in action on the demo page.\n\nNote: these examples only work when you\u2019re using a WebKit-based browser like Safari, Mobile Safari or Google Chrome. I\u2019m confident though that Mozilla and Opera will try their very best catching up with all this new CSS goodness soon.\n\nWhen looking at this example, you see the possibilities are endless. Another advantage is you can change the look of it entirely by only changing a couple of lines of CSS, instead of re-creating and re-downloading the image from some website smelling like web 2.0 gone bad. I made another demo that shows how great it is to be able to change background and foreground colors (even on the fly!).\n\nSo there you have it, a smoothly animated, fully transparent and completely customizable spinner. Cool? I think so. (Ladies?)\n\nBut you can do a lot more with CSS animations than just create pretty spinners. Since I was fooling around with it anyway, I decided to test how far you can push this, space is the final limit, right?\n\nConclusion\n\nCSS has never been more exciting than it is right now. I\u2019m even prepared to say CSS is \u201ccool\u201d again, both for the more experienced front-end developers as for the new designers discovering CSS every day now.\n\nBut\u2026\n\nRemember when Javascript became popular? Remember when Flash became popular? Every time we\u2019re been given new toys, some people aren\u2019t ashamed to use it in a way you can barely call constructive. I\u2019m thinking of Geocities websites, loaded with glowing blocks of text, moving images, bad color usage\u2026 In the wise words of Stan Lee: With great power there must also come great responsibility! A sprinkle of CSS animations is better than a bucket load. Apply with care.", "year": "2009", "author": "Tim Van Damme", "author_slug": "timvandamme", "published": "2009-12-15T00:00:00+00:00", "url": "https://24ways.org/2009/css-animations/", "topic": "code"} {"rowid": 175, "title": "Front-End Code Reusability with CSS and JavaScript", "contents": "Most web standards-based developers are more than familiar with creating their sites with semantic HTML with lots and lots of CSS. With each new page in a design, the CSS tends to grow and grow and more elements and styles are added. But CSS can be used to better effect.\n\nThe idea of object-oriented CSS isn\u2019t new. Nicole Sullivan has written a presentation on the subject and outlines two main concepts: separate structure and visual design; and separate container and content. Jeff Croft talks about Applying OOP Concepts to CSS:\n\n\n\tI can make a class of .box that defines some basic layout structure, and another class of .rounded that provides rounded corners, and classes of .wide and .narrow that define some widths, and then easily create boxes of varying widths and styles by assigning multiple classes to an element, without having to duplicate code in my CSS.\n\n\nThis concept helps reduce CSS file size, allows for great flexibility, rapid building of similar content areas and means greater consistency throughout the entire design. You can also take this concept one step further and apply it to site behaviour with JavaScript.\n\nBuild a versatile slideshow\n\nI will show you how to build multiple slideshows using jQuery, allowing varying levels of functionality which you may find on one site design. The code will be flexible enough to allow you to add previous/next links, image pagination and the ability to change the animation type. More importantly, it will allow you to apply any combination of these features.\n\nImage galleries are simply a list of images, so the obvious choice of marking the content up is to use a