[{"rowid": 75, "title": "A Harder-Working Class", "contents": "Class is only becoming more important. Focusing on its original definition as an attribute for grouping (or classifying) as well as linking HTML to CSS, recent front-end development practices are emphasizing class as a vessel for structured, modularized style packages. These patterns reduce the need for repetitive declarations that can seriously bloat file sizes, and instil human-readable understanding of how the interface, layout, and aesthetics are constructed.\n\nIn the next handful of paragraphs, we will look at how these emerging practices \u2013 such as object-oriented CSS and SMACSS \u2013 are pushing the relevance of class. We will also explore how HTML and CSS architecture can be further simplified, performance can be boosted, and CSS utility sharpened by combining class with the attribute selector.\n\nA primer on attribute selectors\n\nWhile attribute selectors were introduced in the CSS 2 spec, they are still considered rather exotic. These well-established and well-supported features give us vastly improved flexibility in targeting elements in CSS, and offer us opportunities for smarter markup. With an attribute selector, you can directly style an element based on any of its unique \u2013 or uniquely shared \u2013 attributes, without the need for an ID or extra classes. Unlike pseudo-classes, pseudo-elements, and other exciting features of CSS3, attribute selectors do not require any browser-specific syntax or prefix, and are even supported in Internet Explorer 7. \n\nFor example, say we want to target all anchor tags on a page that link to our homepage. Where otherwise we might need to manually identify and add classes to the HTML for these specific links, we could simply write:\n\n[href=index.html] {  }\n\nThis selector reads: target every element that has an href attribute of \u201cindex.html\u201d. \n\nAttribute selectors are more faceted, though, as they also give us some very simple regular expression-like logic that helps further narrow (or widen) a selector\u2019s scope. In our previous example, what if we wanted to also give indicative styles to any anchor tag linking to an external site? With no way to know what the exact href value would be for every external link, we need to use an expression to match a common aspect of those links. In this case, we know that all external links need to start with \u201chttp\u201d, so we can use that as a hook:\n\n[href^=http] {  }\n\nThe selector here reads: target every element that has an href attribute that begins with \u201chttp\u201d (which will also include \u201chttps\u201d). The ^= means \u201cstarts with\u201d. There are a few other simple expressions that give us a lot of flexibility in targeting elements, and I have found that a deep understanding of these and other selector types to be very useful.\n\nThe class-attribute selector\n\nBy matching classes with the attribute selector, CSS can be pushed to accomplish some exciting new feats. What I call a class-attribute selector combines the advantages of classes with attribute selectors by targeting the class attribute, rather than a specific class. Instead of selecting .urgent, you could select [class*=urgent]. The latter may seem like a more verbose way of accomplishing the former, but each would actually match two subtly different groups of elements.\n\nEric Meyer first explored the possibility of using classes with attribute selectors over a decade ago. While his interest in this technique mostly explored the different facets of the syntax, I have found that using class-attribute selectors can have distinct advantages over either using an attribute selector or a straightforward class selector.\n\nFirst, let\u2019s explore some of the subtleties of why we would target class before other attributes:\n\n\n\tClasses are ubiquitous. They have been supported since the HTML 4 spec was released in 1999. Newer attributes, such as the custom data attribute, have only recently begun to be adopted by browsers.\n\tClasses have multiple ways of being targeted. You can use the class selector or attribute selector (.classname or [class=classname]), allowing more flexible specificity than resorting to an ID or !important.\n\tClasses are already widely used, so adding more classes will usually require less markup than adding more attributes.\n\tClasses were designed to abstractly group and specify elements, making them the most appropriate attribute for styling using object-oriented methods (as we will learn in a moment).\n\n\nAlso, as Meyer pointed out, we can use the class-attribute selector to be more strict about class declarations. Of these two elements:\n\n<h2 class=\"very urgent\">\n\n<h2 class=\"urgent\">\n\n\u2026only the second h2 would be selected by [class=urgent], while .urgent would select both. The use of = matches any element with the exact class value of \u201curgent\u201d. Eric explores these nuances further in his series on attribute selectors, but perhaps more dramatic is the added power that class-attribute selectors can bring to our CSS.\n\nMore object-oriented, more scalable and modular\n\nNicole Sullivan has been pushing abstracted, object-oriented thinking in CSS development for years now. She has shared stacks of knowledge on how behemoth sites have seen impressive gains in maintenance overhead and CSS file sizes by leaning heavier on classes derived from common patterns. Jonathan Snook also speaks, writes and is genuinely passionate about improving our markup by using more stratified and modular class name conventions. With SMACSS, he shows this to be highly useful across sites \u2013 both complex and simple \u2013 that exhibit repeated design patterns. Sullivan and Snook both push the use of class for styling over other attributes, and many front-end developers are fast advocating such thinking as best practice.\n\nWith class-attribute selectors, we can further abstract our CSS, pushing its scalability. In his chapter on modules, Snook gives the example of a .pod class that might represent a certain set of styles. A .pod style set might be used in varying contexts, leading to CSS that might normally look like this:\n\n.pod {  }\nform .pod {  }\naside .pod {  }\n\nAccording to Snook, we can make these styles more portable by targeting more verbose classes, rather than context:\n\n.pod {  }\n.pod-form {  }\n.pod-sidebar {  }\n\n\u2026resulting in the following HTML:\n\n<div class=\"pod\">\n<div class=\"pod pod-form\">\n<div class=\"pod pod-sidebar\">\n\nThis divorces the <div>\u2019s styles from its context, making it applicable to any situation in which it is needed. The markup is clean and portable, and the classes are imbued with meaning as to what module they belong to. \n\nUsing class-attribute selectors, we can simplify this further:\n\n[class*=pod] {  }\n.pod-form {  }\n.pod-sidebar {  }\n\nThe *= tells the browser to look for any element with a class attribute containing \u201cpod\u201d, so it matches \u201cpod\u201d, \u201cpod-form\u201d, \u201cpod-sidebar\u201d, etc. This allows only one class per element, resulting in simpler HTML:\n\n<div class=\"pod\">\n<div class=\"pod-form\">\n<div class=\"pod-sidebar\">\n\nWe could further abstract the concept of \u201cform\u201d and \u201csidebar\u201d adjustments if we knew that each of those alterations would always need the same treatment.\n\n/* Modules */\n[class*=pod] {  }\n[class*=btn] {  }\n\n/* Alterations */\n[class*=-form] {  }\n[class*=-sidebar] {  }\n\nIn this case, all elements with classes appended \u201c-form\u201d or \u201c-sidebar\u201d would be altered in the same manner, allowing the markup to stay simple:\n\n<form>\n  <h2 class=\"pod-form\">\n  <a class=\"btn-form\" href=\"#\">\n\n<aside>\n  <h2 class=\"pod-sidebar\">\n  <a class=\"btn-sidebar\" href=\"#\">\n\n50+ shades of specificity\n\nClasses are just powerful enough to override element selectors and default styling, but still leave room to be trumped by IDs and !important styles. This makes them more suitable for object-oriented patterns and helps avoid messy specificity issues that can not only be a pain for developers to maintain, but can also affect a site\u2019s performance. As Sullivan notes, \u201cIn almost every case, classes work well and have fewer unintended consequences than either IDs or element selectors\u201d. Proper use of specificity and cascade is crucial in building straightforward, efficient CSS.\n\nOne interesting aspect of attribute selectors is that they can be compounded for increasing levels of specificity. Attribute selectors are assigned a specificity level of ten, the same as class selectors, but both class and attribute selectors can be chained together, giving them more and more specificity with each link. Some examples:\n\n.box {  } \n/* Specificity of 10 */\n\n.box.promo {  } \n/* Specificity of 20 */\n\n[class*=box] {  } \n/* Specificity of 10 */\n\n[class*=box][class*=promo] {  } \n/* Specificity of 20 */\n\nYou can chain both types together, too:\n\n.box[class*=promo] {  } \n/* Specificity of 20 */\n\nI was amused to find, though, that you can chain the exact same class and attribute selectors for infinite levels of specificity\n\n.box {  } \n/* Specificity of 10 */\n\n.box.box {  } \n/* Specificity of 20 */\n\n.box.box.box {  } \n/* Specificity of 30 */\n\n[class*=box] {  }\n/* Specificity of 10 */\n\n[class*=box][class*=box] {  }\n/* Specificity of 20 */\n\n[class*=box][class*=box][class*=box] {  }\n/* Specificity of 30 */\n\n.box[class*=box].box[class*=box] {  } \n/* Specificity of 40 */\n\nTo override .box styles for promo, we wouldn\u2019t need to add an ID, change the order of .promo and .box in the CSS, or resort to an !important style. Granted, any issue that might need this fine level of specificity tweaking could probably be better solved with clever cascades, but having options never hurts.\n\nSmarter CSS\n\nOne of the most powerful aspects of the class-attribute selector is its ability to expand the simple logic found in CSS. When developing Gridset (an online tool for building grids and outputting them as CSS), I realized that with the right class name conventions, class-attribute selectors would allow the CSS to be smart enough to automatically adjust for column offsets without the need for extra classes. This imbued the CSS output with logic that other frameworks lacked, and makes a developer\u2019s job much easier. \n\nSay you need an element that spans column five (c5) to column six (c6) on your grid, and is preceded by an element spanning column one (c1) to column three (c3). The CSS can anticipate such a scenario:\n\n.c1-c3 + .c5-c6 {\n  margin-left: 25%; /* \u2026or the width of column four plus two gutter widths */\n}\n\n\u2026but to accommodate all of the margin offsets that could span that same gap, we would need to write a rather protracted list for just a six column grid:\n\n.c1-c3 + .c5-c6,\n.c1-c3 + .c5,\n.c2-c3 + .c5-c6,\n.c2-c3 + .c5,\n.c3 + .c5-c6,\n.c3 + .c5 {\n  margin-left: 25%; \n}\n\nNow imagine how the verbosity compounds when we repeat this type of declaration for every possible margin in a grid. The more columns added to the grid, the longer this selector list would get, too, making the CSS harder for the developer to maintain and slowing the load time. Using class-attribute selectors, though, this can be much simpler:\n\n[class*=c3] + [class*=c5] {\n  margin-left: 25%;\n}\n\nI\u2019ve detailed how we extract as much logic as possible from as little CSS as needed on the Gridset blog.\n\nMore flexible selectors\n\nIn a recent project, I was working with Drupal-generated classes to change styles for certain special pages on a site. Without being able to change the code base, I was left trying to find some specific aspect of the generated HTML to target. I noticed that every special page was given a prefixed class, unique to the page, resulting in CSS like this:\n\n.specialpage-about,\n.specialpage-contact,\n.specialpage-info,\n\u2026\n\n\u2026and the list kept growing with each new special page. Such bloat would lead to problems down the line, and add development overhead to editorial decisions, which was a situation we were trying to avoid. I was easily able to fix this, though, with a concise class-attribute selector:\n\n[class*=specialpage-]\n\nThe CSS was now flexible enough to accommodate both the editorial needs of the client, and the development restrictions of the CMS.\n\nSelector performance\n\nAs Snook tells us in his chapter on Selector Performance, selectors are read by the browser from right to left, matching every element that adheres to each rule (or part of the selector). The more specific we can make the right-most rules \u2013 and every other part of your selectors \u2013 the more performant your CSS will be. So this selector:\n\n.home-page .promo .main-header\n\n\u2026would be more performant than:\n\n.home-page div header\n\n\u2026because there are likely many more header and div elements on the page, but not so many elements with those specific classes.\n\nNow, the class-attribute selector could be more general than a class selector, but not by much. I ran numerous tests based on the work of Steve Souders (and a few others) to test a class-attribute selector against a normal class selector. Given that Javascript will freeze during style rendering, I created a script that will add, then remove, a stylesheet on a page 5000 times, and measure only the time that elapses during the rendering freeze. The script runs four tests, essentially: one where a class selector and class-attribute Selector match a single element, and one they match multiple elements on the page.\n\nAfter running the test over 100 times and averaging the results, I have not seen a significant difference in rendering times. (As of this writing, the class-attribute selector has been 0.398% slower on average.) View the results here.\n\nGiven the sheer amount of bytes potentially saved by reducing selector lists, though, I am confident class-attribute selectors could shorten load times on larger sites and, at the very least, save precious development time.\n\nConclusion\n\nWith its flexibility and broad remit, class has at times been derided as too lenient, allowing CMSes and lazy developers to fill its values with presentational hacks or verbose gibberish. There have even been calls for an early retirement. Class continues, though, to be one of our most crucial tools.\n\nFront-end developers are rightfully eager to expand production abilities through innovations such as Sass or LESS, but this should not preclude us from honing the tools we already know as well. Every technique demonstrated in this article was achievable over a decade ago and most of the same thinking could be applied to IDs, rels, or any other attribute (though the reasons listed above give class an edge). The recent advent of methods such as object-oriented CSS and SMACSS shows there is still much room left to expand what simple HTML and CSS can accomplish. Progress may not always be found in the innovation of our tools, but through sharpening our understanding of them.", "year": "2012", "author": "Nathan Ford", "author_slug": "nathanford", "published": "2012-12-15T00:00:00+00:00", "url": "https://24ways.org/2012/a-harder-working-class/", "topic": "code"}, {"rowid": 76, "title": "Giving CSS Animations and Transitions Their Place", "contents": "CSS animations and transitions may not sit squarely in the realm of the behaviour layer, but they\u2019re stepping up into this area that used to be pure JavaScript territory. Heck, CSS might even perform better than its JavaScript equivalents in some cases. That\u2019s pretty serious! With CSS\u2019s new tricks blurring the lines between presentation and behaviour, it can start to feel bloated and messy in our CSS files. It\u2019s an uncomfortable feeling.\n\nHere are a pair of methods I\u2019ve found to be pretty helpful in keeping the potential bloat and wire-crossing under control when CSS has its hands in both presentation and behaviour.\n\nSame eggs, more baskets\n\nStructuring your CSS to have separate files for layout, typography, grids, and so on is a fairly common approach these days. But which one do you put your transitions and animations in? The initial answer, as always, is \u201cit depends\u201d.\n\nSmall effects here and there will likely sit just fine with your other styles. When you move into more involved effects that require multiple animations and some logic support from JavaScript, it\u2019s probably time to choose none of the above, and create a separate CSS file just for them.\n\nPutting all your animations in one file is a huge help for code organization. Even if you opt for a name less literal than animations.css, you\u2019ll know exactly where to go for anything CSS animation related. That saves time and effort when it comes to editing and maintenance. Keeping track of which animations are still currently used is easier when they\u2019re all grouped together as well. And as an added bonus, you won\u2019t have to look at all those horribly unattractive and repetitive prefixed @-keyframe rules unless you actually need to.\n\nAn animations.css file might look something like the snippet below. It defines each animation\u2019s keyframes and defines a class for each variation of that animation you\u2019ll be using. Depending on the situation, you may also want to include transitions here in a similar way. (I\u2019ve found defining transitions as their own class, or mixin, to be a huge help in past projects for me.)\n\n// defining the animation\n@keyframes catFall {\n from { background-position: center 0;}\n to {background-position: center 1000px;}\n}\n@-webkit-keyframes catFall {\n from { background-position: center 0;}\n to {background-position: center 1000px;}\n}\n@-moz-keyframes catFall {\n from { background-position: center 0;}\n to {background-position: center 1000px;}\n}\n@-ms-keyframes catFall {\n from { background-position: center 0;}\n to {background-position: center 1000px;}\n}\n\n\u2026\n\n// class that assigns the animation\n\n.catsBackground {\n height: 100%;\n background: transparent url(../endlessKittens.png) 0 0 repeat-y;\n animation: catFall 1s linear infinite;\n -webkit-animation: catFall 1s linear infinite;\n -moz-animation: catFall 1s linear infinite;\n -ms-animation: catFall 1s linear infinite;\n}\n\nIf we don\u2019t need it, why load it?\n\nHaving all those CSS animations and transitions in one file gives us the added flexibility to load them only when we want to. Loading a whole lot of things that will never be used might seem like a bit of a waste.\n\nWhile CSS has us impressed with its motion chops, it falls flat when it comes to the logic and fine-grained control. JavaScript, on the other hand, is pretty good at both those things. Chances are the content of your animations.css file isn\u2019t acting alone. You\u2019ll likely be adding and removing classes via JavaScript to manage your CSS animations at the very least. If your CSS animations are so entwined with JavaScript, why not let them hang out with the rest of the behaviour layer and only come out to play when JavaScript is supported?\n\nDynamically linking your animations.css file like this means it will be completely ignored if JavaScript is off or not supported. No JavaScript? No additional behaviour, not even the parts handled by CSS.\n\n<script>\ndocument.write('<link rel=\"stylesheet\" type=\"text/css\" href=\"animations.css\">');\n</script>\n\nThis technique comes up in progressive enhancement techniques as well, but it can help here to keep your presentation and behaviour nicely separated when more than one language is involved. The aim in both cases is to avoid loading files we won\u2019t be using.\n\nIf you happen to be doing something a bit fancier \u2013 like 3-D transforms or critical animations that require more nuanced fallbacks \u2013 you might need something like modernizr to step in to determine support more specifically. But the general idea is the same.\n\nSumming it all up\n\nUsing a couple of simple techniques like these, we get to pick where to best draw the line between behaviour and presentation based on the situation at hand, not just on what language we\u2019re using. The power of when to separate and how to reassemble the individual pieces can be even greater if you use preprocessors as part of your process. We\u2019ve got a lot of options! The important part is to make forward-thinking choices to save your future self, and even your current self, unnecessary headaches.", "year": "2012", "author": "Val Head", "author_slug": "valhead", "published": "2012-12-08T00:00:00+00:00", "url": "https://24ways.org/2012/giving-css-animations-and-transitions-their-place/", "topic": "code"}, {"rowid": 79, "title": "Responsive Images: What We Thought We Needed", "contents": "If you were to read a web designer\u2019s Christmas wish list, it would likely include a solution for displaying images responsively. For those concerned about users downloading unnecessary image data, or serving images that look blurry on high resolution displays, finding a solution has become a frustrating quest.\n\nHaving experimented with complex and sometimes devilish hacks, consensus is forming around defining new standards that could solve this problem. Two approaches have emerged.\n\nThe <picture> element markup pattern was proposed by Mat Marquis and is now being developed by the Responsive Images Community Group. By providing a means of declaring multiple sources, authors could use media queries to control which version of an image is displayed and under what conditions:\n\n<picture width=\"500\" height=\"500\">\n  <source media=\"(min-width: 45em)\" src=\"large.jpg\">\n  <source media=\"(min-width: 18em)\" src=\"med.jpg\">\n  <source src=\"small.jpg\">\n  <img src=\"small.jpg\" alt=\"\">\n  <p>Accessible text</p>\n</picture>\n\nA second proposal put forward by Apple, the srcset attribute, uses a more concise syntax intended for use with the <img> element, although it could be compatible with the <picture> element too. This would allow authors to provide a set of images, but with the decision on which to use left to the browser:\n\n<img src=\"fallback.jpg\" alt=\"\" srcset=\"small.jpg 640w 1x, small-hd.jpg 640w 2x, med.jpg 1x, med-hd.jpg 2x \">\n\nEnter Scrooge\n\n\n\tMen\u2019s courses will foreshadow certain ends, to which, if persevered in, they must lead.\nEbenezer Scrooge\n\n\nGiven the complexity of this issue, there\u2019s a heated debate about which is the best option. Yet code belies a certain truth. That both feature verbose and opaque syntax, I\u2019m not sure either should find its way into the browser \u2013 especially as alternative approaches have yet to be fully explored.\n\nSo, as if to dampen the festive cheer, here are five reasons why I believe both proposals are largely redundant.\n\n1. We need better formats, not more markup\n\nAs we move away from designs defined with fixed pixel values, bitmap images look increasingly unsuitable. While simple images and iconography can use scalable vector formats like SVG, for detailed photographic imagery, raster formats like GIF, PNG and JPEG remain the only suitable option.\n\nThere is scope within current formats to account for varying bandwidth but this requires cooperation from browser vendors. Newer formats like JPEG2000 and WebP generate higher quality images with smaller file sizes, but aren\u2019t widely supported.\n\nWhile it\u2019s tempting to try to solve this issue by inventing new markup, the crux of it remains at the file level.\n\nDaan Jobsis\u2019s experimentation with image compression strengthens this argument. He discovered that by increasing the dimensions of a JPEG image while simultaneously reducing its quality, a smaller files could be produced, with the resulting image looking just as good on both standard and high-resolution displays.\n\nThis may be a hack in lieu of a more permanent solution, but it\u2019s applied in the right place. Easy to accomplish with existing tools and without compatibility issues, it has few downsides. Further experimentation in this area should be encouraged, with standardisation efforts more helpful if focused on developing new image formats or, preferably, extending existing ones.\n\n2. Art direction doesn\u2019t belong in markup\n\nA desired benefit of the <picture> markup pattern is to allow for greater art direction. For example, rather than scaling down images on smaller displays to the point that their content is hard to discern, we could present closer crops instead:\n\n\n\nThis can be achieved with CSS of course, although with a download penalty for those parts of an image not shown. This point may be negligible, however, since in the context of adaptable layouts, these hidden areas may end up being revealed anyway.\n\nArt direction concerns design, not content. If we wish to maintain a separation of concerns, including presentation within our markup seems misguided.\n\n3. The size of a display has little relation to the size of an image\n\nBy using media queries, the <picture> element allows authors to choose which characteristics of the screen or viewport to query for different images to be displayed.\n\nIn developing sites at Clearleft, we have noticed that the viewport is essentially arbitrary, with the size of an image\u2019s containing element more important. For example, look at how this grid of images may adapt at different viewport widths:\n\n\n\nAs we build more modular systems, components need to be adaptable in and of themselves. There is a case to be made for developing more contextual methods of querying, rather than those based on attributes of the display.\n\n4. We haven\u2019t lived with the problem long enough\n\nA key strength of the web is that the underlying platform can be continually iterated. This can also be problematic if snap judgements are made about what constitutes an improvement.\n\nThe early history of the web is littered with such examples, be it the perceived need for blinking text or inline typographic styling. To build a platform for the future, additions to it should be carefully considered. And if we want more consistent support across browsers, burdening vendors with an ever increasing list of features seems counterproductive.\n\nOnly once the need for a new feature is sufficiently proven, should we look to standardise it. Before we could declare hover effects, rounded corners and typographic styling in CSS, we used JavaScript as a polyfill. Sure, doing so was painful, but use cases were fully explored, and the CSS specification better reflected the needs of authors.\n\n5. Images and the web aesthetic\n\nThe srcset proposal has emerged from a company that markets its phones as being able to browse the real \u2013 yet squashed down, tapped and zoomable \u2013 web. Perhaps Apple should make its own website responsive before suggesting how the rest of us should do so.\n\nConverserly, while the <picture> proposal has the backing of a few respected developers and designers, it was born out of the work Mat Marquis and Filament Group did for the Boston Globe. As the first large-scale responsive design, this was a landmark project that ignited the responsive web design movement and proved its worth. But it was the first.\n\nIts design shares a vernacular to that of contemporary newspaper websites, with a columnar, image-laden and densely packed layout. Compared to more recent examples \u2013 Quartz, The Next Web and the New York Times Skimmer \u2013 it feels out of step with the future direction of news sites. In seeking out a truer aesthetic for the web in which software interfaces have greater influence, we might discover that the need for responsive images isn\u2019t as great as originally thought.\n\n\n\nBuilding for the future\n\nWith responsive design, we\u2019ve accepted the idea that a fully fluid layout, rather than a set of fixed layouts, is best suited to the web\u2019s unpredictable nature. Current responsive image proposals are antithetical to this approach.\n\nWe need solutions that lack complexity, are device-agnostic and work within existing workflows. Any proposal that requires different versions of the same image to be created, is likely to have to acquiesce under the pressure of reality.\n\nWhile it\u2019s easy to get distracted about the size and quality of an image, and how we might choose to serve it, often the simplest solution is not to include it at all. After years of gluttonous design practice, in which fast connections and expansive display sizes were an accepted norm, we have got use to filling pages with needless images and countless items of page furniture.\n\nTo design more adaptable experiences, the presence of every element needs to be questioned, for its existence requires additional data to be downloaded or futher complexity within a design system. Conditional loading techniques mean that the inclusion of images is no longer a binary choice, but can instead appear in a progressively enhanced manner.\n\nSo here is my proposal. Instead of spending the next year worrying about responsive images, let\u2019s embrace the constraints of the medium, and seek out new solutions that can work within them.", "year": "2012", "author": "Paul Lloyd", "author_slug": "paulrobertlloyd", "published": "2012-12-11T00:00:00+00:00", "url": "https://24ways.org/2012/responsive-images-what-we-thought-we-needed/", "topic": "code"}, {"rowid": 80, "title": "HTML5 Video Bumpers", "contents": "Video is a bigger part of the web experience than ever before. With native browser support for HTML5 video elements freeing us from the tyranny of plugins, and the availability of faster internet connections to the workplace, home and mobile networks, it\u2019s now pretty straightforward to publish video in a way that can be consumed in all sorts of ways on all sorts of different web devices.\n\nI recently worked on a project where the client had shot some dedicated video shorts to publish on their site. They also had some five-second motion graphics produced to top and tail the videos with context and branding. This pretty common requirement is a great idea on the web, where a user might land at your video having followed a link and be viewing a page without much context.\n\nKnown as bumpers, these short introduction clips help brand a video and make it look a lot more professional.\n\n\n\nAdding bumpers to a video\n\nThe simplest way to add bumpers to a video would be to edit them on to the start and end of the video file itself. Cooking the bumpers into the video file is easy, but should you ever want to update them it can become a real headache. If the branding needs updating, for example, you\u2019d need to re-edit and re-encode all your videos. Not a fun task.\n\nWhat if the bumpers could be added dynamically? That would enable you to use the same bumper for multiple videos (decreasing download time for users who might watch more than one) and to update the bumpers whenever you wanted. You could change them seasonally, update them for special promotions, run different advertising slots, perform multivariate testing, or even target different bumpers to different users.\n\nThe trade-off, of course, is that if you dynamically add your bumpers, there\u2019s a chance that a user in a given circumstance might not see the bumper. For example, if the main video feature was uploaded to YouTube, you\u2019d have no way to control the playback. As always, you need to weigh up the pros and cons and make your choice.\n\nHTML5 bumpers\n\nIf you wanted to dynamically add bumpers to your HTML5 video, how would you go about it? That was the question I found myself needing to answer for this particular client project.\n\nMy initial thought was to treat it just like an image slideshow. If I were building a slideshow that moved between images, I\u2019d use CSS absolute positioning with z-index to stack the images up on top of each other in a pile, with the first image on top. To transition to the second image, I\u2019d use JavaScript to fade the top image out, revealing the second image beneath it.\n\n\n\nNow that video is just a native object in the DOM, just like an image, why not do the same? Stack the videos up with the opening bumper on top, listen for the video\u2019s onended event, and fade it out to reveal the main feature behind. Good idea, right?\n\nWrong\n\nRemember that this is the web. It\u2019s never going to be that easy. The problem here is that many non-desktop devices use native, dedicated video players. Think about watching a video on a mobile phone \u2013 when you play the video, the phone often goes full-screen in its native player, leaving the web page behind. There\u2019s no opportunity to fade or switch z-index, as the video isn\u2019t being viewed in the page. Your page is left powerless. Powerless!\n\n\n\nSo what can we do? What can we control?\n\nThose of us with particularly long memories might recall a time before CSS, when we\u2019d have to use JavaScript to perform image rollovers. As CSS background images weren\u2019t a practical reality, we would use lots of <img> elements, and perform a rollover by modifying the src attribute of the image. \n\nTurns out, this old trick of modifying the source can help us out with video, too. In most cases, modifying the src attribute of a <video> element, or perhaps more likely the src attribute of a source element, will swap from one video to another.\n\nSwappin\u2019 it\n\nLet\u2019s take a deliberately simple example of a super-basic video tag:\n\n<video src=\"mycat.webm\" controls>no fallback coz i is lame, innit.</video>\n\nWe could very simply write a script to find all video tags and give them a new src to show our bumper.\n\n<script>\n\tvar videos, i, l;\n\tvideos = document.getElementsByTagName('video');\n\tfor(i=0, l=videos.length; i<l; i++) {\n\t\tvideos[i].setAttribute('src', 'bumper-in.webm');\n\t}\n</script>\n\nView the example in a browser with WebM support. You\u2019ll see that the video is swapped out for the opening bumper. Great!\n\nBeefing it up\n\nOf course, we can\u2019t just publish video in one format. In practical use, you need a <video> element with multiple <source> elements containing your different source formats.\n\n<video controls>\n    <source src=\"mycat.mp4\" type=\"video/mp4\" />\n    <source src=\"mycat.webm\" type=\"video/webm\" />\n    <source src=\"mycat.ogv\" type=\"video/ogg\" />\n</video>\n\nThis time, our script needs to loop through the sources, not the videos. We\u2019ll use a regular expression replacement to swap out the file name while maintaining the correct file extension.\n\n<script>\n    var sources, i, l, orig;\n    sources = document.getElementsByTagName('source');\n    for(i=0, l=sources.length; i<l; i++) {\n        orig = sources[i].getAttribute('src');\n        sources[i].setAttribute('src', orig.replace(/(w+).(w+)/, 'bumper-in.$2'));\n        // reload the video\n        sources[i].parentNode.load();\n    }\n</script>\n\nThe difference this time is that when changing the src of a <source> we need to call the .load() method on the video to get it to acknowledge the change.\n\nSee the code in action, this time in a wider range of browsers.\n\nBut, my video!\n\nI guess we should get the original video playing again. Keeping the same markup, we need to modify the script to do two things:\n\n\n\tStore the original src in a data- attribute so we can access it later\n\tAdd an event listener so we can detect the end of the bumper playing, and load the original video back in\n\n\nAs we need to loop through the videos this time to add the event listener, I\u2019ve moved the .load() call into that loop. It\u2019s a bit more efficient to call it only once after modifying all the video\u2019s sources.\n\n<script>\nvar videos, sources, i, l, orig;\nsources = document.getElementsByTagName('source');\nfor(i=0, l=sources.length; i<l; i++) {\n    orig = sources[i].getAttribute('src');\n    sources[i].setAttribute('data-orig', orig);\n    sources[i].setAttribute('src', orig.replace(/(w+).(w+)/, 'bumper-in.$2'));\n}\nvideos = document.getElementsByTagName('video');\nfor(i=0, l=videos.length; i<l; i++) {\n    videos[i].load();\n    videos[i].addEventListener('ended', function(){\n        sources = this.getElementsByTagName('source');\n        for(i=0, l=sources.length; i<l; i++) {\n            orig = sources[i].getAttribute('data-orig');\n            if (orig) {\n                sources[i].setAttribute('src', orig);\n            }\n            sources[i].setAttribute('data-orig','');\n        }\n        this.load();\n        this.play();\n    });\n}\n</script>\n\nAgain, view the example to see the bumper play, followed by our spectacular main feature. (That\u2019s my cat, Widget. His interests include sleeping and internet marketing.)\n\nTidying things up\n\nThe final thing to do is add our closing bumper after the main video has played. This involves the following changes:\n\n\n\tWe need to keep track of whether the src has been changed, so we only play the video if it\u2019s changed. I\u2019ve added the modified variable to track this, and it stops us getting into a situation where the video just loops forever.\n\tAdd an else to the event listener, for when the orig is false (so the main feature has been playing) to load in the end bumper. We also check that we\u2019re not already playing the end bumper. Because looping.\n\n\n<script>\nvar videos, sources, i, l, orig, current, modified;\nsources = document.getElementsByTagName('source');\nfor(i=0, l=sources.length; i<l; i++) {\n   orig = sources[i].getAttribute('src');\n   sources[i].setAttribute('data-orig', orig);\n   sources[i].setAttribute('src', orig.replace(/(w+).(w+)/, 'bumper-in.$2'));\n}\nvideos = document.getElementsByTagName('video');\nfor(i=0, l=videos.length; i<l; i++) {\n   videos[i].load();\n   modified = false;\n   videos[i].addEventListener('ended', function(){\n      sources = this.getElementsByTagName('source');\n      for(i=0, l=sources.length; i<l; i++) {\n         orig = sources[i].getAttribute('data-orig');\n         if (orig) {\n            sources[i].setAttribute('src', orig);\n            modified = true;\n         }else{\n            current = sources[i].getAttribute('src');\n            if (current.indexOf('bumper-out')==-1) {\n               sources[i].setAttribute('src', current.replace(/([w]+).(w+)/, 'bumper-out.$2'));\n               modified = true;\n            }else{\n               this.pause();\n               modified = false;\n            }\n         }\n         sources[i].setAttribute('data-orig','');\n      }\n      if (modified) {\n         this.load();\n         this.play();\n      }\n   });\n}\n</script>\n\nYo ho ho, that\u2019s a lot of JavaScript. See it in action \u2013 you should get a bumper, the cat video, and an end bumper.\n\nOf course, this code works fine for demonstrating the principle, but it\u2019s very procedural. Nothing wrong with that, but to do something similar in production, you\u2019d probably want to make the code more modular to ease maintainability. Besides, you may want to use a framework, rather than basic JavaScript. \n\nThe end credits\n\nOne really important principle here is that of progressive enhancement. If the browser doesn\u2019t support JavaScript, the user won\u2019t see your bumper, but they will get the main video. If the browser supports JavaScript but doesn\u2019t allow you to modify the src (as was the case with older versions of iOS), the user won\u2019t see your bumper, but they will get the main video.\n\nIf a search engine or social media bot grabs your page and looks for content, they won\u2019t see your bumper, but they will get the main video \u2013 which is absolutely what you want.\n\nThis means that if the bumper is absolutely crucial, you may still need to cook it into the video. However, for many applications, running it dynamically can work quite well.\n\nAs always, it comes down to three things:\n\n\n\tMeasure your audience: know how people access your site\n\tTest the solution: make sure it works for your audience\n\tPlan for failure: it\u2019s the web and that\u2019s how things work \u2018round these parts\n\n\nBut most of all play around with it, have fun and build something awesome.", "year": "2012", "author": "Drew McLellan", "author_slug": "drewmclellan", "published": "2012-12-01T00:00:00+00:00", "url": "https://24ways.org/2012/html5-video-bumpers/", "topic": "code"}, {"rowid": 83, "title": "Cut Copy Paste", "contents": "Long before I got into this design thing, I was heavily into making my own music inspired by the likes of Coldcut and Steinski. I would scour local second-hand record shops in search of obscure beats, loops and bits of dialogue in the hope of finding that killer sample I could then splice together with other things to make a huge hit that everyone would love. While it did eventually lead to a record contract and getting to release a few 12\u2033 singles, ultimately I knew I\u2019d have to look for something else to pay the bills.\n\nI may not make my own records any more, but the approach I took back then \u2013 finding (even stealing) things, cutting and pasting them into interesting combinations \u2013 is still at the centre of how I work, only these days it\u2019s pretty much bits of code rather than bits of vinyl. Over the years I\u2019ve stored these little bits of code (some I\u2019ve found, some I\u2019ve created myself) in Evernote, ready to be dialled up whenever I need them. \n\nSo when Drew got in touch and asked if I\u2019d like to do something for this year\u2019s 24 ways I thought it might be kind of cool to share with you a few of these snippets that I find really useful. Think of these as a kind of coding mix tape; but remember \u2013 don\u2019t just copy as is: play around, combine and remix them into other wonderful things. \n\nSome of this stuff is dirty; some of it will make hardcore programmers feel ill. For those people, remember this \u2013 while you were complaining about the syntax, I made something.\n\nCreate unique colours\n\nLet\u2019s start right away with something I stole. Well, actually it was given away at the time by Matt Biddulph who was then at Dopplr before Nokia destroyed it. Imagine you have thousands of words and you want to assign each one a unique colour. Well, Matt came up with a crazily simple but effective way to do that using an MD5 hash. Just encode said word using an MD5 hash, then take the first six characters of the string you get back to create a hexadecimal colour representation. \n\nI can\u2019t guarantee that it will be a harmonious colour palette, but it\u2019s still really useful. The thing I love the most about this technique is the left-field thinking of using an encryption system to create colours! Here\u2019s an example using JavaScript:\n\n// requires the MD5 library available at http://pajhome.org.uk/crypt/md5\n\n  function MD5Hex(str){\n    result = MD5.hex(str).substring(0, 6);\n    return result;\n  }\n\nMake something breathe using a sine wave\n\nI never paid attention in school, especially during double maths. As a matter of fact, the only time I received corporal punishment \u2013 several strokes of the ruler \u2013 was in maths class. Anyway, if they had shown me then how beautiful mathematics actually is, I might have paid more attention. Here\u2019s a little example of how a sine wave can be used to make something appear to breathe. \n\nI recently used this on an Arduino project where an LED ring surrounding a button would gently breathe. Because of that it felt much more inviting. I love mathematics.\n\nfor(int i = 0; i<360; i++){    \n  float rad = DEG_TO_RAD * i;\n  int sinOut = constrain((sin(rad) * 128) + 128, 0, 255);\n  analogWrite(LED, sinOut);\n  delay(10);   \n}\n\nSnap position to grid\n\nThis is so elegant I love it, and it was shown to me by Gary Burgess, or Boom Boom as myself and others like to call him. It snaps a position, in this case the X-position, to a grid. Just define your grid size (say, twenty pixels) and you\u2019re good.\n\nsnappedXpos = floor( xPos / gridSize) * gridSize;\n\nCalculate the distance between two objects\n\nFor me, interaction design is about the relationship between two objects: you and another object; you and another person; or simply one object to another. How close these two things are to each other can be a handy thing to know, allowing you to react to that information within your design. Here\u2019s how to calculate the distance between two objects in a 2-D plane:\n\ndeltaX = round(p2.x-p1.x);\ndeltaY = round(p2.y-p1.y);\ndiff = round(sqrt((deltaX*deltaX)+(deltaY*deltaY)));\n\nFind the X- and Y-position between two objects\n\nWhat if you have two objects and you want to place something in-between them? A little bit of interruption and disruption can be a good thing. This small piece of code will allow you to place an object in-between two other objects:\n\n// set the position: 0.5 = half-way\t\n\nfloat position = 0.5;\nfloat x = x1 + (x2 - x1) *position;  \nfloat y = y1 + (y2 - y1) *position;  \n\nDistribute objects equally around a circle \t\n\nMore fun with maths, this time adding cosine to our friend sine. Let\u2019s say you want to create a circular navigation of arbitrary elements (yeah, Jakob, you heard), or you want to place images around a circle. Well, this piece of code will do just that. You can adjust the size of the circle by changing the distance variable and alter the number of objects with the numberOfObjects variable. Example below is for use in Processing.\n\n// Example for Processing available for free download at processing.org\n\nvoid setup() {\n\n  size(800,800);\n  int numberOfObjects = 12;\n  int distance = 100;\n  float inc = (TWO_PI)/numberOfObjects;\n  float x,y;\n  float a = 0;\n\n  for (int i=0; i < numberOfObjects; i++) {\n    x = (width/2) + sin(a)*distance;\n    y = (height/2) + cos(a)*distance;\n    ellipse(x,y,10,10);\n    a += inc;\n\n  }\n}\n\nUse modulus to make a grid\n\nThe modulus operator, represented by %, returns the remainder of a division. Fallen into a coma yet? Hold on a minute \u2013 this seemingly simple function is very powerful in lots of ways. At a simple level, you can use it to determine if a number is odd or even, great for creating alternate row colours in a table for instance:\n\nboolean checkForEven(numberToCheck) {\n  if (numberToCheck % 2 == 0) \n    return true;\n  } else {\n    return false; \n  }\n}\n\nThat\u2019s all well and good, but here\u2019s a use of modulus that might very well blow your mind. Construct a grid with only a few lines of code. Again the example is in Processing but can easily be ported to any other language.\n\nvoid setup() {\n\nsize(600,600);\nint numItems = 120;\nint numOfColumns = 12;\nint xSpacing = 40;\nint ySpacing = 40;\nint totalWidth = xSpacing*numOfColumns;\n\nfor (int i=0; i < numItems; i++) {\n\nellipse(floor((i*xSpacing)%totalWidth),floor((i*xSpacing)/totalWidth)*ySpacing,10,10);\n\n}\n}\n\nNot all the bits of code I keep around are for actual graphical output. I also have things that are very utilitarian, but which I still consider part of the design process. Here\u2019s a couple of things that I\u2019ve found really handy lately in my design workflow. They may be a little specific, but I hope they demonstrate that it\u2019s not about working harder, it\u2019s about working smarter. \n\nMerge CSV files into one file\n\nRecently, I\u2019ve had to work with huge \u2013 about 1GB \u2013 CSV text files that I then needed to combine into one master CSV file so I could then process the data. Opening up each text file and then copying and pasting just seemed really dumb, not to mention slow, so I thought there must be a better way. After some Googling I found this command line script that would combine .txt files into one file and add a new line after each:  \n\nawk 1 *.txt > finalfile.txt\n\nBut that wasn\u2019t what I was ideally after. I wanted to merge the CSV files, keeping the first row of the first file (the column headings) and then ignore the first row of subsequent files. Sure enough I found the answer after some Googling and it worked like a charm. Apologies to the original author but I can\u2019t remember where I found it, but you, sir or madam, are awesome. Save this as a shell script:\n\nFIRST=\n\nfor FILE in *.csv\n  do\n    exec 5<\"$FILE\" # Open file\n    read LINE <&5 # Read first line\n      [ -z \"$FIRST\" ] && echo \"$LINE\" # Print it only from first file\n      FIRST=\"no\"\n\n      cat <&5 # Print the rest directly to standard output\n      exec 5<&- # Close file\n      # Redirect stdout for this section into file.out \n\ndone > file.out\n\nCreate a symbolic link to another file or folder\n\nOftentimes, I\u2019ll find myself hunting through a load of directories to load a file to be processed, like a CSV file. Use a symbolic link (in the Terminal) to place a link on your desktop or wherever is most convenient and it\u2019ll save you loads of time. Especially great if you\u2019re going through a Java file dialogue box in Processing or something that doesn\u2019t allow the normal Mac dialog box or aliases.\n\ncd /DirectoryYouWantShortcutToLiveIn\nln -s /Directory/You/Want/ShortcutTo/ TheShortcut\n\nYou can do it, in the mix\n\nI hope you\u2019ve found some of the above useful and that they\u2019ve inspired a few ideas here and there. Feel free to tell me better ways of doing things or offer up any other handy pieces of code. Most of all though, collect, remix and combine the things you discover to make lovely new things.", "year": "2012", "author": "Brendan Dawes", "author_slug": "brendandawes", "published": "2012-12-17T00:00:00+00:00", "url": "https://24ways.org/2012/cut-copy-paste/", "topic": "code"}, {"rowid": 86, "title": "Flashless Animation", "contents": "Animation in a Flashless world\n\nWhen I splashed down in web design four years ago, the first thing I wanted to do was animate a cartoon in the browser. I\u2019d been drawing comics for years, and I\u2019ve wanted to see them come to life for nearly as long. Flash animation was still riding high, but I didn\u2019t want to learn Flash. I wanted to learn JavaScript!\n\nSadly, animating with JavaScript was limiting and resource-intensive. My initial foray into an infinitely looping background did more to burn a hole in my CPU than amaze my friends (although it still looks pretty cool). And there was still no simple way to incorporate audio. The browser technology just wasn\u2019t there.\n\nThings are different now. CSS3 transitions and animations can do most of the heavy lifting and HTML5 audio can serve up the music and audio clips. You can do a lot without leaning on JavaScript at all, and when you lean on JavaScript, you can do so much more!\n\nIn this project, I\u2019m going to show you how to animate a simple walk cycle with looping audio. I hope this will inspire you to do something really cool and impress your friends. I\u2019d love to see what you come up with, so please send your creations my way at rachelnabors.com!\n\nNote: Because every browser wants to use its own prefixes with CSS3 animations, and I have neither the time nor the space to write all of them out, I will use the W3C standard syntaxes; that is, going prefix-less. You can implement them out of the box with something like Prefixfree, or you can add prefixes on your own. If you take the latter route, I recommend using Sass and Compass so you can focus on your animations, not copying and pasting.\n\nThe walk cycle\n\nWalk cycles are the \u201cHello world\u201d of animation. One of the first projects of animation students is to spend hours drawing dozens of frames to complete a simple loopable animation of a character walking.\n\nMost animators don\u2019t have to draw every frame themselves, though. They draw a few key frames and send those on to production animators to work on the between frames (or tween frames). This is meticulous, grueling work requiring an eye for detail and natural movement. This is also why so much production animation gets shipped overseas where labor is cheaper.\n\nLuckily, we don\u2019t have to worry about our frame count because we can set our own frames-per-second rate on the fly in CSS3. Since we\u2019re trying to impress friends, not animation directors, the inconsistency shouldn\u2019t be a problem. (Unless your friend is an animation director.)\n\nThis is a simple walk cycle I made of my comic character Tuna for my CSS animation talk at CSS Dev Conference this year:\n\n\n\nThe magic lies here:\n\nanimation: walk-cycle 1s steps(12) infinite;\n\nBreaking those properties down:\n\nanimation: <name> <duration> <timing-function> <iteration-count>;\n\nwalk-cycle is a simple @keyframes block that moves the background sprite on .tuna around:\n\n@keyframes walk-cycle {  \n    0% {background-position: 0 0; }\n    100% {background-position: 0 -2391px;}\n}\n\nThe background sprite has exactly twelve images of Tuna that complete a full walk cycle. We\u2019re setting it to cycle through the entire sprite every second, infinitely. So why isn\u2019t the background image scrolling down the .tuna container? It\u2019s all down to the timing function steps(). Using steps() let us tell the CSS to make jumps instead of the smooth transitions you\u2019d get from something like linear. Chris Mills at dev.opera wrote in his excellent intro to CSS3 animation :\n\n\n\tInstead of giving a smooth animation throughout, [steps()] causes the animation to jump between a set number of steps placed equally along the duration. For example, steps(10) would make the animation jump along in ten equal steps. There\u2019s also an optional second parameter that takes a value of start or end. steps(10, start) would specify that the change in property value should happen at the start of each step, while steps(10, end) means the change would come at the end.\n\n\n(Seriously, go read his full article. I\u2019m not going to touch on half the stuff he does because I cannot improve on the basics any more than he already has.)\n\nThe background\n\nA cat walking in a void is hardly an impressive animation and certainly your buddy one cube over could do it if he chopped up some of those cat GIFs he keeps using in group chat. So let\u2019s add a parallax background! Yes, yes, all web designers signed a peace treaty to not abuse parallax anymore, but this is its true calling\u2014treaty be damned.\n\n\n\nAnd to think we used to need JavaScript to do this! It\u2019s still pretty CPU intensive but much less complicated. We start by splitting up the page into different layers, .foreground, .midground, and .background. We put .tuna in the .midground.\n\n.background has multiple background images, all set to repeat horizontally:\n\nbackground-image:\n    url(background_mountain5.png),\n    url(background_mountain4.png),\n    url(background_mountain3.png),\n    url(background_mountain2.png),\n    url(background_mountain1.png);\nbackground-repeat: repeat-x;\n\nWith parallax, things in the foreground move faster than those in the background. Next time you\u2019re driving, notice how the things closer to you move out of your field of vision faster than something in the distance, like a mountain or a large building. We can imitate that here by making the background images on top (in the foreground, closer to us) wider than those on the bottom of the stack (in the distance).\n\nThe different lengths let us use one animation to move all the background images at different rates in the same interval of time:   \n\nanimation: parallax_bg linear 40s infinite;\n\nThe shorter images have less distance to cover in the same amount of time as the longer images, so they move slower.\n\n\n\nLet\u2019s have a look at the background\u2019s animation:\n\n@keyframes parallax_bg {  \n  0% {\n    background-position: -2400px 100%, -2000px 100%, -1800px 100%, -1600px 100%, -1200px 100%;\n  }\n  100% {\n    background-position: 0 100%, 0 100%, 0 100%, 0 100%, 0 100%;\n  }\n}\n\nAt 0%, all the background images are positioned at the negative value of their own widths. Then they start moving toward background-position: 0 100%. If we wanted to move them in the reverse direction, we\u2019d remove the negative values at 0% (so they would start at 2400px 100%, 2000px 100%, etc.). Try changing the values in the codepen above or changing background-repeat to none to see how the images play together.\n\n.foreground and .midground operate on the same principles, only they use single background images.\n\nThe music\n\nAfter finishing the first draft of my original walk cycle, I made a GIF with it and posted it on YTMND with some music from the movie Paprika, specifically the track \u201cThe Girl in Byakkoya.\u201d After showing it to some colleagues in my community, it became clear that this was a winning combination sure to drive away dresscode blues. So let\u2019s use HTML5 to get a clip of that music looping in there!\n\nWarning, there is sound. Please adjust your volume or apply headphones as needed.\n\n\n\nWe\u2019re using HTML5 audio\u2019s loop and autoplay abilities to automatically play and loop a sound file on page load:\n\n<audio loop autoplay>\n  <source src=\"http://music.com/clip.mp3\" />\n</audio>\n\nUnfortunately, you may notice there is a small pause between loops. HTML5 audio, thou art half-baked still. Let\u2019s hope one day the Web Audio API will be able to help us out, but until things improve, we\u2019ll have to hack our way around these shortcomings.\n\nTurns out there\u2019s a handy little script called seamlessLoop.js which we can use to patch this. Mind you, if we were really getting crazy with the Cheese Whiz, we\u2019d want to get out big guns like sound.js. But that\u2019d be overkill for a mere loop (and explaining the Web Audio API might bore, rather than impress your friends)!\n\nInstalling seamlessLoop.js will get rid of the pause, and now our walk cycle is complete.\n\n(I\u2019ve done some very rough sniffing to see if the browser can play MP3 files. If not, we fall back to using .ogg formatted clips (Opera and Firefox users, you\u2019re welcome).)\n\nReally impress your friends by adding a run cycle\n\nSo we have music, we have a walk cycle, we have parallax. It will be a snap to bring them all together and have a simple, endless animation. But let\u2019s go one step further and knock the socks off our viewers by adding a run cycle.\n\nThe run cycle\n\nTacking a run cycle on to our walk cycle will require a third animation sequence: a transitional animation of Tuna switching from walking to running. I have added all these to the sprite:\n\n\n\nLet\u2019s work on getting that transition down. We\u2019re going to use multiple animations on the same .tuna div, but we\u2019re going to kick them off at different intervals using animation-delay\u2014no JavaScript required! Isn\u2019t that magical?\n\n\n\nIt requires a wee bit of math (not much, it doesn\u2019t hurt) to line them up. We want to:\n\n\n\tLoop the walk animation twice\n\tPlay the transitional cycle once (it has a finite beginning and end perfectly drawn to pick up between the last frame of the walk cycle and the first frame of the run cycle\u2014no looping this baby)\n\tRUN FOREVER.\n\n\nUsing the pattern animation: <name> <duration> <timing-function> <delay> <iteration-count>, here\u2019s what that looks like:\n\nanimation:\n    walk-cycle 1s steps(12) 2,\n    walk-to-run .75s steps(12) 2s 1,\n    run-cycle .75s steps(13) 2.75s infinite;\n\nI played with the times to get make the movement more realistic. You may notice that the running animation looks smoother than the walking animation. That\u2019s because it has 13 keyframes running over .75 second instead of 12 running in one second. Remember, professional animation studios use super-high frame counts. This little animation isn\u2019t even up to PBS\u2019s standards!\n\nThe music: extended play with HTML5 audio sprites\n\nMy favorite part in the The Girl in Byakkoya is when the calm opening builds and transitions into a bouncy motif. I want to start with Tuna walking during the opening, and then loop the running and bounciness together for infinity.\n\n\n\tThe intro lasts for 24 seconds, so we set our 1 second walk cycle to run for 24 repetitions: \nwalk-cycle 1s steps(12) 24\n\tWe delay walk-to-run by 24 seconds so it runs for .75 seconds before\u2026\n\tWe play run-cycle at 24.75 seconds and loop it infinitely\n\n\nFor the music, we need to think of it as two parts: the intro and the bouncy loop. We can do this quite nicely with audio sprites: using one HTML5 audio element and using JavaScript to change the play head location, like skipping tracks with a CD player. Although this technique will result in a small gap in music shifts, I think it\u2019s worth using here to give you some ideas.\n\n// Get the audio element\nvar byakkoya = document.querySelector('audio');\n// create function to play and loop audio\nfunction song(a){\n    //start playing at 0\n    a.currentTime = 0;\n    a.play();\n    //when we hit 64 seconds...\n    setTimeout(function(){\n        // skip back to 24.5 seconds and keep playing...\n        a.currentTime = 24.55;\n        // then loop back when we hit 64 again, or every 59.5 seconds.\n        setInterval(function(){\n            a.currentTime = 24.55;\n        },39450);\n    },64000);\n}\n\nThe load screen\n\nI\u2019ve put it off as long as I can, but now that the music and the CSS are both running on their own separate clocks, it\u2019s imperative that both images and music be fully downloaded and ready to run when we kick this thing off. So we need a load screen (also, it\u2019s nice to give people a heads-up that you\u2019re about to blast them with music, no matter how wonderful that music may be).\n\nSince the two timers are so closely linked, we\u2019d best not run the animations until we run the music:\n\n* { animation-play-state: paused; }\n\nanimation-play-state can be set to paused or running, and it\u2019s the most useful thing you will learn today.\n\nFirst we use an event listener to see when the browser thinks we can play through from the beginning to end of the music without pause for buffering:\n\nbyakkoya.addEventListener(\"canplaythrough\", function () { });\n\n(More on HTML5 audio\u2019s media events at HTML5doctor.com)\n\nInside our event listener, I use a bit of jQuery to add class of .playable to the body when we\u2019re ready to enable the play button:\n\n$(\"body\").addClass(\"playable\");\n    $(\"#play-me\").html(\"Play me.\").click(function(){\n      song(byakkoya);\n      $(\"body\").addClass(\"playing\");\n    });\n\nThat .playing class is special because it turns on the animations at the same time we start playing the song:\n\n.playing * { animation-play-state: running; }\n\nThe background\n\nWe\u2019re almost done here! When we add the background, it needs to speed up at the same time that Tuna starts running. The music picks up speed around 24.75 seconds in, and so we\u2019re going to use animation-delay on those backgrounds, too.\n\nThis will require some math. If you try to simply shorten the animation\u2019s duration at the 24.75s mark, the backgrounds will, mid-scroll, jump back to their initial background positions to start the new animation! Argh! So let\u2019s make a new @keyframe and calculate where the background position would be just before we speed up the animation.\n\nHere\u2019s the formula:\n\nnew 0% value = delay \u00f7 old duration \u00d7 length of image\n\nnew 100% value = new 0% value + length of image\n\nHere\u2019s the formula put to work on a smaller scale:\n\n\n\nVoil\u00e0! The finished animation!\n\n\n\nI\u2019ve always wanted to bring my illustrations to life. Then I woke up one morning and realized that I had all the tools to do so in my browser and in my head. Now I have fallen in love with Flashless animation.\n\nI\u2019m sure there will be detractors who say HTML wasn\u2019t meant for this and it\u2019s a gross abuse of the DOM! But I say that these explorations help us expand what we expect from devices and software and challenge us in good ways as artists and programmers. The browser might not be the most appropriate place for animation, but is certainly a fun place to start.\n\nThere is so much you can do with the spec implemented today, and so much of the territory is still unexplored. I have not yet begun to show you everything. In eight months I expect this demo will represent the norm, not the bleeding edge. I look forward to seeing the wonderful things you create.\n\n(Also, someone, please, do something about that gappy HTML5 audio looping. It\u2019s a crying shame!)", "year": "2012", "author": "Rachel Nabors", "author_slug": "rachelnabors", "published": "2012-12-06T00:00:00+00:00", "url": "https://24ways.org/2012/flashless-animation/", "topic": "code"}, {"rowid": 89, "title": "Direction, Distance and Destinations", "contents": "With all these new smartphones in the hands of lost and confused owners, we need a better way to represent distances and directions to destinations. The immediate examples that jump to mind are augmented reality apps which let you see another world through your phone\u2019s camera. While this is interesting, there is a simpler way: letting people know how far away they are and if they are getting warmer or colder. \n\nIn the app world, you can easily tap into the phone\u2019s array of sensors such as the GPS and compass, but what people rarely know is that you can do the same with HTML. The native versus web app debate will never subside, but at least we can show you how to replicate some of the functionality progressively in HTML and JavaScript.\n\nIn this tutorial, we\u2019ll walk through how to create a simple webpage listing distances and directions of a few popular locations around the world. We\u2019ll use JavaScript to access the device\u2019s geolocation API and also attempt to access the compass to get a heading. Both of these APIs are documented, to be included in the W3C geolocation API specification, and can be used on both desktop and mobile devices today.\n\nTo get started, we need a list of a few locations around the world. I have chosen the highest mountain peak on each continent so you can see a diverse set of distances and directions. \n\n\n\t\t\n\t\t\tMountain \n\t\t\t\u00b0Latitude \n\t\t\t\u00b0Longitude \n\t\t\n\t\t\n\t\t\tKilimanjaro\n\t\t\t-3.075833\n\t\t\t37.353333\n\t\t\n\t\t\n\t\t\tVinson Massif\n\t\t\t-78.525483\n\t\t\t-85.617147\n\t\t\n\t\t\n\t\t\tPuncak Jaya\n\t\t\t-4.078889\n\t\t\t137.158333\n\t\t\n\t\t\n\t\t\tEverest\n\t\t\t27.988056\n\t\t\t86.925278\n\t\t\n\t\t\n\t\t\tElbrus\n\t\t\t43.355\n\t\t\t42.439167\n\t\t\n\t\t\n\t\t\tMount McKinley\n\t\t\t63.0695\n\t\t\t-151.0074\n\t\t\n\t\t\n\t\t\tAconcagua\n\t\t\t-32.653431\n\t\t\t-70.011083\n\t\t\n\n\nSource: Wikipedia \n\nWe can put those into an HTML list to be styled and accessed by JavaScript to create some distance and directions calculations.\n\nThe next thing we need to do is check to see if the browser and operating system have geolocation support. To do this we test to see if the function is available or not using a single JavaScript if statement.\n\n<script>\n// If this is true, then the method is supported and we can try to access the location\nif (navigator.geolocation) {\n\tnavigator.geolocation.getCurrentPosition(geo_success, geo_error);\n}\n</script>\n\nThe if statement will be false if geolocation support is not present, and then it is up to you to do something else instead as a fallback. For this example, we\u2019ll do nothing since our page should work as is and only get progressively better if more functionality is available. \n\nThe if statement will be true if there is support and therefore will continue inside the curly brackets to try to get the location. This should prompt the reader to accept or deny the request to get their location. If they say no, the second function callback is processed, in this case a function called geo_error; whereas if the location is available, it fires the geo_success function callback.\n\nThe function geo_error(){ } isn\u2019t that exciting. You can handle this in any way you see fit. The success function is more interesting. We get a position object passed into the function which contains a series of exciting attributes, namely the latitude and longitude of the device\u2019s current location.\n\nfunction geo_success(position){\n\tgLat = position.coords.latitude;\n\tgLon = position.coords.longitude;\n}\n\nNow, in the variables gLat and gLon we have the user\u2019s approximate geographical position. We can use this information to start to calculate some distances between where they are and all the destinations.\n\nAt the time of writing, you can also get position.coords.heading, but on Windows and iOS devices this returned NULL. In the future, if and when this is supported, this is also where you can easily grab the compass information.\n\nInside the geo_success function, we want to loop through the HTML to get all of the mountain peaks\u2019 latitudes and longitudes and compute the distance.\n\n...\n$('.geo').each(function(){\n\t// Get the lat/lon from the HTML\n\ttLat = $(this).find('.lat').html()\n\ttLon = $(this).find('.lon').html()\n\n\t// compute the distances between the current location and this points location\n\tdist = distance(tLat,tLon,gLat,gLon);\n\n\t// set the return values into something useful\n\td = parseInt(dist[0]*10)/10;\n\ta = parseFloat(dist[1]);\n\n\t// display the value in the HTML and style the arrow\n\t$(this).find('.distance').html(d+' km away');\n\t$(this).find('.direction').css('-webkit-transform','rotate(-' + a + 'deg)');\n\n\t// store the arc for later use if compass is available\n\t$(this).attr('data-arc',a);\n}\n\nIn the variable d we have the distance between the current location and the location of the mountain peak based on the Haversine Formula. The variable a is the arc, which has a value from 0 to 359.99. This will be useful later if we have compass support. Given these two values we have a distance and a heading to style the HTML.\n\nThe next thing we want to do is check to see if the device has a compass and then get access to the the current heading. As we\u2019ll see, there are several ways to do this, some of which work on certain devices but not others. The W3C geolocation spec says that, along with the coordinates, there are several other attributes: accuracy; altitude; and heading. Heading is the direction to true north, which is different than magnetic north! WebKit and Windows return NULL for the heading value, but WebKit has an experimental method to fetch the heading. If you get into accessing these sensors, you\u2019ll have to try to catch a few of these methods to finally get a value. Assuming you do, we can move on to the more interesting display opportunities.\n\nIn an ideal world, this would succeed and set a variable we\u2019ll call compassHeading to get a value between 0 and 359.99 degrees. Now we know which direction north is, we also know the direction relative to north of the path to our destination, so we can can subtract the two values to get an arrow to display on the screen. But we\u2019re not finished yet: we also need to get the device\u2019s orientation (landscape or portrait) and subtract the correct amount from the angle for the arrow. Once we have a value, we can use CSS to rotate the arrow the correct number of degrees.\n\n-webkit-transform: rotate(-180deg)\n\nNot all devices support a standard way to access compass information, so in the meantime we need to use a work around. On iOS, you can use the experimental event method e.webkitCompassHeading. We want the compass to update in real time as the device is moved around, so we\u2019ll put this inside an event listener.\n\nwindow.addEventListener('deviceorientation', function(e) {\n\t// Loop through all the locations on the page\n\t$('.geo').each(function(){\n\t\t// get the arc value from north we computed and stored earlier\n\t\tdestination_arc = parseInt($(this).attr('data-arc'))\n\t\tcompassHeading = e.webkitCompassHeading + window.orientation + destination_arc;\n\t\t// find the arrow element and rotate it accordingly\n\t\t$(this).find('.direction').css('-webkit-transform','rotate(-' + compassHeading + 'deg)');\t\t\n\t}\n}\n\nAs the device is rotated, the compass arrow will constantly be updated. If you want to see an example, you can have a look at this page which shows the distances to all the peaks on each continent.\n\nWith progressive enhancement, we slowly layer on additional functionality as we go. The reader will first see the list of locations with a latitude and longitude. If the device is capable and permissions allow, it will then compute the distance. If a compass is available, with the correct permissions it will then add the final layer which is direction.\n\nYou should consider this code a stub for your projects. If you are making a hyperlocal webpage with restaurant locations, for example, then consider adding these features. Knowing not only how far away a place is, but also the direction can be hugely important, and since the compass is always active, it acts as a guide to the location. \n\nFuture developments\n\nImprovements to this could include setting a timer and recalling the navigator.geolocation.getCurrentPosition() function and updating the distances. I chose very distant mountains so kilometres made sense, but you can divide again by 1,000 to convert to metres if you are dealing with much nearer places. Walking or driving would change the distances so the ability to refresh would be important. \n\nIt is outside the scope of this article, but if you manage to get this HTML to work offline, then you can make a nice web app which sits on your devices\u2019 homescreens and works even without an internet connection. This could be ideal for travellers in an unknown city looking for your destination. Just with offline storage, base64 encoding and data URIs, it is possible to embed plenty of design and functionality into a small offline webpage.\n\nNow you know how to use JavaScript to look up a destination\u2019s location and figure out the distance and direction \u2013 never get lost again.", "year": "2012", "author": "Brian Suda", "author_slug": "briansuda", "published": "2012-12-19T00:00:00+00:00", "url": "https://24ways.org/2012/direction-distance-and-destinations/", "topic": "code"}, {"rowid": 91, "title": "Infinite Canvas: Moving Beyond the Page", "contents": "Remember Web 2.0? I do. In fact, that phrase neatly bifurcates my life on the internet. Pre-2.0, I was occupied by chatting on AOL and eventually by learning HTML so I could build sites on Geocities. Around 2002, however, I saw a WYSIWYG demo in Dreamweaver. The instructor was dragging boxes and images around a canvas. With a few clicks he was able to build a dynamic, single-page interface. Coming from the world of tables and inline HTML styles, I was stunned.\n\nAs I entered college the next year, the web was blossoming: broadband, Wi-Fi, mobile (proud PDA owner, right here), CSS, Ajax, Bloglines, Gmail and, soon, Google Maps. I was a technology fanatic and a hobbyist web developer. For me, the web had long been informational. It was now rapidly becoming something else, something more: sophisticated, presentational, actionable.\n\nIn 2003 we watched as the internet changed. The predominant theme of those early Web 2.0 years was the withering of Internet Explorer 6 and the triumph of web standards. Upon cresting that mountain, we looked around and collectively breathed the rarefied air of pristine HMTL and CSS, uncontaminated by toxic hacks and forks \u2013 only to immediately begin hurtling down the other side at what is, frankly, terrifying speed.\n\nTen years later, we are still riding that rocket. Our days (and nights) are spent cramming for exams on CSS3 and RWD and Sass and RESS. We are the proud, frazzled owners of tiny pocket computers that annihilate the best laptops we could have imagined, and the architects of websites that are no longer restricted to big screens nor even segregated by device. We dragoon our sites into working any time, anywhere. At this point, we can hardly ask the spec developers to slow down to allow us to catch our breath, nor should we. It is, without a doubt, a most wonderful time to be a web developer.\n\nBut despite the newfound luxury of rounded corners, gradients, embeddable fonts, low-level graphics APIs, and, glory be, shadows, the canyon between HTML and native appears to be as wide as ever. The improvements in HTML and CSS have, for the most part, been conveniences rather than fundamental shifts. What I\u2019d like to do now, if you\u2019ll allow me, is outline just a few of the remaining gaps that continue to separate web sites and applications from their native companions.\n\nWhat I\u2019d like for Christmas\n\nThere is one irritant which is the grandfather of them all, the one from which all others flow and have their being, and it is, simply, the page refresh. That\u2019s right, the foundational principle of the web is our single greatest foe. To paraphrase a patron saint of designers everywhere, if you see a page refresh, we blew it.\n\nThe page refresh brings with it, of course, many noble and lovely benefits: addressability, for one; and pagination, for another. (See also caching, resource loading, and probably half a dozen others.) Still, those concerns can be answered (and arguably answered more compellingly) by replacing the weary page with the young and hearty document. Flash may be dead, but it has many lessons yet to bequeath.\n\nPreparing a single document when the site loads allows us to engage the visitor in a smooth and engrossing experience. We have long known this, of course. Twitter was not the first to attempt, via JavaScript, to envelop the user in a single-page application, nor the first to abandon it. Our shared task is to move those technologies down the stack, to make them more primitive, so that the next Twitter can be built with the most basic combination of HTML and CSS rather than relying on complicated, slow, and unreliable scripted solutions.\n\nSo, let\u2019s take a look at what we can do, right now, that we might have a better idea of where our current tools fall short.\n\nA print magazine in HTML clothing\n\nLike many others, I suspect, one of my earliest experiences with publishing was laying out newsletters and newspapers on a computer for print. If you\u2019ve ever used InDesign or Quark or even Microsoft Publisher, you\u2019ll remember reflowing content from page to page. The advent of the internet signaled, in many ways, the abandonment of that model. Articles were no longer constrained by the physical limitations of paper. In shedding our chains, however, it is arguable that we\u2019ve lost something useful. We had a self-contained and complete package, a closed loop. It was a thing that could be handled and finished, and doing so provided a sense of accomplishment that our modern, infinitely scrolling, ever-fractal web of content has stolen.\n\nFor our purposes today, we will treat 24 ways as the online equivalent of that newspaper or magazine. A single year\u2019s worth of articles could easily be considered an issue. Right now, navigating between articles means clicking on the article you\u2019d like to view and being taken to that specific address via a page reload. If Drew wanted to, it wouldn\u2019t be difficult to update the page in place (via JavaScript) and change the address (again via JavaScript with the History API) to reflect the new content found at the new location. But what if Drew wanted to do that without  JavaScript? And what if he wanted the site to not merely load the content but actually whisk you along the page in a compelling and delightful way, \u00e0 la the Mag+ demo we all saw a few years ago when the iPad was first introduced? Uh, no.\n\nWe\u2019re all familiar with websites that have attempted to go beyond the page by weaving many chunks of content together into a large document and for good reason. There is tremendous appeal in opening and exploring the canvas beyond the edges of our screens.\n\nIn one rather straightforward example from last year, Mozilla contacted Full Stop to build a website promoting Aza Raskin\u2019s proposal for a set of Creative Commons-style privacy icons. Like a lot of the sites we build (including our own), the amount of information we were presenting was minimal. In these instances, we encourage our clients to consider including everything on a single page. The result was a horizontally driven site that was, if not whimsical, at least clever and attractive to the intended audience. An experience that is taken for granted when using device-native technology is utterly, maddeningly impossible to replicate on the web without jumping through JavaScript hoops.\n\nIn another, more complex example, we again had the pleasure of working with Aza earlier this year, this time on a redesign of the Massive Health website. Our assignment was to design and build a site that communicated Massive\u2019s commitment to modern personal health. The site had to be visually and interactively stunning while maintaining a usable and clear interface for the casual visitor. Our solution was to extend the infinite company logo into a ribbon that carried the visitor through the site narrative. It also meant we\u2019d be asking the browser to accommodate something it was never designed to handle: a non-linear design. (Be sure to play around. There\u2019s a lot going on under the hood. We were also this close to a ZUI, if WebKit didn\u2019t freak out when pages were scaled beyond 10\u00d7.) Despite the apparent and deliberate design simplicity, the techniques necessary to implement it are anything but. From updating the URL to moving the visitor from section to section, we\u2019re firmly in JavaScript territory. And that\u2019s a shame.\n\nWhat can we do?\n\nWe might not be able to specify these layouts in HTML and CSS just yet, but that doesn\u2019t mean we can\u2019t learn a few new tricks while we wait. Let\u2019s see how close we can come to recreating the privacy icons design, the Massive design, or the Mag+ design without resorting to JavaScript.\n\nA horizontally paginated site\n\nThe first thing we\u2019re going to need is the concept of a page within our HTML document. Using plain old HTML and CSS, we can stack a series of <div>s sideways (with a little assist from our new friend, the viewport-width unit, not that he was strictly necessary). All we need to know is how many pages we have. (And, boy, wouldn\u2019t it be nice to be able to know that without having to predetermine it or use JavaScript?)\n\n.window {\noverflow: hidden;\n  width: 100%;\n}\n.pages {\n  width: 200vw;\n}\n.page {\n  float: left;\n  overflow: hidden;\n  width: 100vw;\n}\n\nIf you look carefully, you\u2019ll see that the conceit we\u2019ll use in the rest of the demos is in place. Despite the document containing multiple pages, only one is visible at any given time. This allows us to keep the user focused on the task (or content) at hand.\n\nBy the way, you\u2019ll need to use a modern, WebKit-based browser for these demos. I recommend downloading the WebKit nightly builds, Chrome Canary, or being comfortable with setting flags in Chrome.\n\nA horizontally paginated site, with transitions\n\nAh, here\u2019s the rub. We have functional navigation, but precious few cues for the user. It\u2019s not much good shoving the visitor around various parts of the document if they don\u2019t get the pleasant whooshing experience of the journey. You might be thinking, what about that new CSS selector, target-something\u2026? Well, my friend, you\u2019re on the right track. Let\u2019s test it. We\u2019re going to need to use a bit of sleight of hand. While we\u2019d like to simply offset the containing element by the number of pages we\u2019re moving (like we did on Massive), CSS alone can\u2019t give us that information, and that means we\u2019re going to need to fake it by expanding and collapsing pages as you navigate. Here are the bits we\u2019re going to need:\n\n.page {\n  -webkit-transition: width 1s; // Naturally you're going to want to include all the relevant prefixes here\n  float: left;\n  left: 0;\n  overflow: hidden;\n  position: relative;\n  width: 100vw;\n}\n.page:not(:target) {\n  width: 0;\n}\n\nAh, but we\u2019re not fooling anyone with that trick. As soon as you move beyond a single page, the visitor\u2019s disbelief comes tumbling down when the linear page transitions are unaffected by the distance the pages are allegedly traveling. And you may have already noticed an even more fatal flaw: I secretly linked you to the first page rather than the unadorned URL. If you visit the same page with no URL fragment, you get a blank screen. Sure, we could force a redirect with some server-side trickery, but that feels like cheating. Perhaps if we had the CSS4 subject selector we could apply styles to the parent based on the child being targeted by the URL. We might also need a few more abilities, like determining the total number of pages and having relative sibling selectors (e.g. nth-sibling), but we\u2019d sure be a lot closer.\n\nA horizontally paginated site, with transitions \u2013 no cheating\n\nWell, what other cards can we play? How about the checkbox hack? Sure, it\u2019s a garish trick, but it might be the best we can do today. Check it out. \n\nlabel {\n  cursor: pointer;\n}\ninput {\n display: none;\n}\ninput:not(:checked) + .page {\n  max-height: 100vh;\n  width: 0;\n}\n\nFinally, we can see the first page thanks to the state we are able to set on the appropriate radio button. Of course, now we don\u2019t have URLs, so maybe this isn\u2019t a winning plan after all. While our HTML and CSS toolkit may feel primitive at the moment, we certainly don\u2019t want to sacrifice the addressability of the web. If there\u2019s one bedrock principle, that\u2019s it.\n\nA horizontally paginated site, with transitions \u2013 no cheating and a gorgeous homepage\n\nGorgeous may not be the right word, but our little magazine is finally shaping up. Thanks to the CSS regions spec, we\u2019ve got an exciting new power, the ability to begin an article in one place and bend it to our will. (Remember, your everyday browser isn\u2019t going to work for these demos. Try the WebKit nightly build to see what we\u2019re talking about.) As with the rest of the examples, we\u2019re clearly abusing these features. Off-canvas layouts (you can thank Luke Wroblewski for the name) are simply not considered to be normal patterns\u2026 yet.\n\nHere\u2019s a quick look at what\u2019s going on:\n\n.excerpt-container {\n  float: left;\n  padding: 2em;\n  position: relative;\n  width: 100%;\n}\n.excerpt {\n  height: 16em;\n}\n.excerpt_name_article-1,\n.page-1 .article-flow-region {\n  -webkit-flow-from: article-1;\n}\n.article-content_for_article-1 {\n  -webkit-flow-into: article-1;\n}\n\nThe regions pattern is comprised of at least three components: a beginning; an ending; and a source. Using CSS, we\u2019re able to define specific elements that should be available for the content to flow through. If magazine-style layouts are something you\u2019re interested in learning more about (and you should be), be sure to check out the great work Adobe has been doing.\n\nLooking forward, and backward\n\nAs designers, builders, and consumers of the web, we share a desire to see the usability and enjoyability of websites continue to rise. We are incredibly lucky to be working in a time when a three-month-old website can be laughably outdated. Our goal ought to be to improve upon both the weaknesses and the strengths of the web platform. We seek not only smoother transitions and larger canvases, but fine-grained addressability. Our URLs should point directly and unambiguously to specific content elements, be they pages, sections, paragraphs or words. Moreover, off-screen design patterns are essential to accommodating and empowering the multitude of devices we use to access the web. We should express the desire that interpage links take advantage of the CSS transitions which have been put to such good effect in every other aspect of our designs. Transitions aren\u2019t just nice to have, they\u2019re table stakes in the highly competitive world of native applications. \n\nThe tools and technologies we have right now allow us to create smart, beautiful, useful webpages. With a little help, we can begin removing the seams and sutures that bind the web to an earlier, less sophisticated generation.", "year": "2012", "author": "Nathan Peretic", "author_slug": "nathanperetic", "published": "2012-12-21T00:00:00+00:00", "url": "https://24ways.org/2012/infinite-canvas-moving-beyond-the-page/", "topic": "code"}, {"rowid": 92, "title": "Redesigning the Media Query", "contents": "Responsive web design is showing us that designing content is more important than designing containers. But if you\u2019ve given RWD a serious try, you know that shifting your focus from the container is surprisingly hard to do. There are many factors and\ninstincts working against you, and one culprit is a perpetrator you\u2019d least suspect.\n\nThe media query is the ringmaster of responsive design. It lets us establish the rules of the game and gives us what we need most: control. However, like some kind of evil double agent, the media query is actually working against you.\n\nIts very nature diverts your attention away from content and forces you to focus on the container.\n\nThe very act of choosing a media query value means choosing a screen size.\n\nLook at the history of the media query\u2014it\u2019s always been about the container. Values like screen, print, handheld and tv don\u2019t have anything to do with content. The modern media query lets us choose screen dimensions, which is great because it makes RWD possible. But it\u2019s still the act of choosing something that is completely unpredictable.\n\nContent should dictate our breakpoints, not the container. In order to get our focus back to the only thing that matters, we need a reengineered media query\u2014one that frees us from thinking about screen dimensions. A media query that works for your content, not the window. Fortunately, Sass 3.2 is ready and willing to take on this challenge.\n\nThinking in Columns\n\nFluid grids never clicked for me. I feel so disoriented and confused by their squishiness. Responsive design demands their use though, right?\n\nI was ready to surrender until I found a grid that turned my world upright again. The Frameless Grid by Joni Korpi demonstrates that column and gutter sizes can stay fixed. As the screen size changes, you simply add or remove columns to accommodate. This made sense to me and armed with this concept I was able to give Sass the first component it needs to rewrite the media query: fixed column and gutter size variables.\n\n$grid-column: 60px;\n$grid-gutter: 20px;\n\nWe\u2019re going to want some resolution independence too, so let\u2019s create a function that converts those nasty pixel values into ems.\n\n@function em($px, $base: $base-font-size) {\n\t@return ($px / $base) * 1em;\n}\n\nWe now have the components needed to figure out the width of multiple columns in ems. Let\u2019s put them together in a function that will take any number of columns and return the fixed width value of their size.\n\n@function fixed($col) {\n\t@return $col * em($grid-column + $grid-gutter)\n}\n\nWith the math in place we can now write a mixin that takes a column count as a parameter, then generates the perfect media query necessary to fit that number of columns on the screen. We can also build in some left and right margin for our layout by adding an additional gutter value (remembering that we already have one gutter built into our fixed function).\n\n@mixin breakpoint($min) {\n\t@media (min-width: fixed($min) + em($grid-gutter)) {\n\t\t@content\n\t}\n}\n\nAnd, just like that, we\u2019ve rewritten the media query. Instead of picking a minimum screen size for our layout, we can simply determine the number of columns needed. Let\u2019s add a wrapper class so that we can center our content on the screen.\n\n@mixin breakpoint($min) {\n    @media (min-width: fixed($min) + em($grid-gutter)) {\n\t.wrapper {\n\t\twidth: fixed($min) - em($grid-gutter);\n\t\tmargin-left: auto; margin-right: auto;\n\t}\n\t@content\n    }\n}\n\nDesigning content with a column count gives us nice, easy, whole numbers to work with. Sizing content, sidebars or widgets is now as simple as specifying a single-digit number.\n\n@include breakpoint(8) {\n\t.main { width: fixed(5); }\n\t.sidebar { width: fixed(3); }\n}\n\nThose four lines of Sass just created a responsive layout for us. When the screen is big enough to fit eight columns, it will trigger a fixed width layout. And give widths to our main content and sidebar. The following is the outputted CSS\u2026\n\n@media (min-width: 41.25em) {\n  .wrapper {\n    width: 38.75em;\n    margin-left: auto; margin-right: auto;\n  }\n  .main { width: 25em; }\n  .sidebar { width: 15em; }\n}\n\nDemo\n\nI\u2019ve created a Codepen demo that demonstrates what we\u2019ve covered so far. I\u2019ve added to the demo some grid classes based on Griddle by Nicolas Gallagher to create a floatless layout. I\u2019ve also added a CSS gradient overlay to help you visualize columns. Try changing the column variable sizes or the breakpoint includes to see how the layout reacts to different screen sizes.\n\nResponsive Images\n\nResponsive images are a serious problem, but I\u2019m excited to see the community talk so passionately about a solution. Now, there are some excellent stopgaps while we wait for something official, but these solutions require you to mirror your breakpoints in JavaScript or HTML. This poses a serious problem for my Sass-generated media queries, because I have no idea what the real values of my breakpoints are anymore. For responsive images to work, JavaScript needs to recognize which media query is active so that proper images can be loaded for that layout.\n\nWhat I need is a way to label my breakpoints. Fortunately, people much smarter than I have figured this out. Jeremy Keith devised a labeling method by using CSS-generated content as the storage method for breakpoint labels. We can use this technique in our breakpoint mixin by passing a label as another argument.\n\n@include breakpoint(8, 'desktop') { /* styles */ }\n\nSass can take that label and use it when writing the corresponding media query. We just need to slightly modify our breakpoint mixin.\n\n@mixin breakpoint($min, $label) {\n    @media (min-width: fixed($min) + em($grid-gutter)) {\n\n        // label our mq with CSS generated content\n\tbody::before { content: $label; display: none; }\n\n\t.wrapper {\n\t\twidth: fixed($min) - em($grid-gutter);\n\t\tmargin-left: auto; margin-right: auto;\n\t}\n\t@content\n    }\n}\n\nThis allows us to label our breakpoints with a user-friendly string. Now that our media queries are defined and labeled, we just need JavaScript to step in and read which label is active.\n\n// get css generated label for active media query\nvar label = getComputedStyle(document.body, '::before')['content'];\n\nJavaScript now knows which layout is active by reading the label in the current media query\u2014we just need to match that label to an image. I prefer to store references to different image sizes as data attributes on my image tag.\n\n<img class=\"responsive-image\" data-mobile=\"mobile.jpg\" data-desktop=\"desktop.jpg\" />\n<noscript><img src=\"desktop.jpg\" /></noscript>\n\nThese data attributes have names that match the labels set in my CSS. So while there is some duplication going on, setting a keyword like \u2018tablet\u2019 in two places is much easier than hardcoding media query values. With matching labels in CSS and HTML our script can marry the two and load the right sized image for our layout.\n\n// get css generated label for active media query\nvar label = getComputedStyle(document.body, '::before')['content'];\n\n// select image\nvar $image = $('.responsive-image');\n\n// create source from data attribute\n$image.attr('src', $image.data(label));\n\nDemo\n\nWith some slight additions to our previous Codepen demo you can see this responsive image technique in action. While the above JavaScript will work it is not nearly robust enough for production so the demo uses a jQuery plugin that can accomodate multiple images, reloading on screen resize and fallbacks if something doesn\u2019t match up.\n\nCreating a Framework\n\nThis media query mixin and responsive image JavaScript are the center piece of a front end framework I use to develop websites. It\u2019s a fluid, mobile first foundation that uses the breakpoint mixin to structure fixed width layouts for tablet and desktop. Significant effort was focused on making this framework completely cross-browser. For example, one of the problems with using media queries is that essential desktop structure code ends up being hidden from legacy Internet Explorer. Respond.js is an excellent polyfill, but if you\u2019re comfortable serving a single desktop layout to older IE, we don\u2019t need JavaScript. We simply need to capture layout code outside of a media query and sandbox it under an IE only class name.\n\n// set IE fallback layout to 8 columns\n$ie-support = 8;\n\n// inside of our breakpoint mixin (but outside the media query)\n@if ($ie-support and $min <= $ie-support) {\n\t.lt-ie9 { @content; }\n}\n\nPerspective Regained\n\nThinking in columns means you are thinking about content layout. How big of a screen do you need for 12 columns? Who cares? Having Sass write media queries means you can use intuitive numbers for content layout. A fixed grid means more layout control and less edge cases to test than a fluid grid. Using CSS labels for activating responsive images means you don\u2019t have to duplicate breakpoints across separations of concern. \n\nIt\u2019s a harmonious blend of approaches that gives us something we need\u2014responsive design that feels intuitive. And design that, from the very outset, focuses on what matters most. Just like our kindergarten teachers taught us: It\u2019s what\u2019s inside that counts.", "year": "2012", "author": "Les James", "author_slug": "lesjames", "published": "2012-12-13T00:00:00+00:00", "url": "https://24ways.org/2012/redesigning-the-media-query/", "topic": "code"}, {"rowid": 95, "title": "Giving Content Priority with CSS3 Grid Layout", "contents": "Browser support for many of the modules that are part of CSS3 have enabled us to use CSS for many of the things we used to have to use images for. The rise of mobile browsers and the concept of responsive web design has given us a whole new way of looking at design for the web. However, when it comes to layout, we haven\u2019t moved very far at all. We have talked for years about separating our content and source order from the presentation of that content, yet most of us have had to make decisions on source order in order to get a certain visual layout. \n\nOwing to some interesting specifications making their way through the W3C process at the moment, though, there is hope of change on the horizon. In this article I\u2019m going to look at one CSS module, the CSS3 grid layout module, that enables us to define a grid and place elements on to it. This article comprises a practical demonstration of the basics of grid layout, and also a discussion of one way in which we can start thinking of content in a more adaptive way.\n\nBefore we get started, it is important to note that, at the time of writing, these examples work only in Internet Explorer 10. CSS3 grid layout is a module created by Microsoft, and implemented using the -ms prefix in IE10. My examples will all use the -ms prefix, and not include other prefixes simply because this is such an early stage specification, and by the time there are implementations in other browsers there may be inconsistencies. The implementation I describe today may well change, but is also there for your feedback.\n\nIf you don\u2019t have access to IE10, then one way to view and test these examples is by signing up for an account with Browserstack \u2013 the free trial would give you time to have a look. I have also included screenshots of all relevant stages in creating the examples.\n\nWhat is CSS3 grid layout?\n\nCSS3 grid layout aims to let developers divide up a design into a grid and place content on to that grid. Rather than trying to fabricate a grid from floats, you can declare an actual grid on a container element and then use that to position the elements inside. Most importantly, the source order of those elements does not matter. \n\nDeclaring a grid\n\nWe declare a grid using a new value for the display property: display: grid. As we are using the IE10 implementation here, we need to prefix that value: display: -ms-grid;.\n\nOnce we have declared our grid, we set up the columns and rows using the grid-columns and grid-rows properties.\n\n.wrapper {\n    display: -ms-grid;\n    -ms-grid-columns: 200px 20px auto 20px 200px;\n    -ms-grid-rows: auto 1fr;\n}\n\nIn the above example, I have declared a grid on the .wrapper element. I have used the grid-columns property to create a grid with a 200 pixel-wide column, a 20 pixel gutter, a flexible width auto column that will stretch to fill the available space, another 20 pixel-wide gutter and a final 200 pixel sidebar: a flexible width layout with two fixed width sidebars. Using the grid-rows property I have created two rows: the first is set to auto so it will stretch to fill whatever I put into it; the second row is set to 1fr, a new value used in grids that means one fraction unit. In this case, one fraction unit of the available space, effectively whatever space is left.\n\nPositioning items on the grid\n\nNow I have a simple grid, I can pop items on to it. If I have a <div> with a class of .main that I want to place into the second row, and the flexible column set to auto I would use the following CSS:\n\n.content {\n    -ms-grid-column: 3;\n    -ms-grid-row: 2;\n    -ms-grid-row-span: 1;\n}\n\nIf you are old-school, you may already have realised that we are essentially creating an HTML table-like layout structure using CSS. I found the concept of a table the most helpful way to think about the grid layout module when trying to work out how to place elements.\n\nCreating grid systems\n\nAs soon as I started to play with CSS3 grid layout, I wanted to see if I could use it to replicate a flexible grid system like this fluid 16-column 960 grid system.\n\nI started out by defining a grid on my wrapper element, using fractions to make this grid fluid.\n\n.wrapper {\t \n    width: 90%;\n    margin: 0 auto 0 auto;\n    display: -ms-grid;\n    -ms-grid-columns: 1fr (4.25fr 1fr)[16];\n    -ms-grid-rows: (auto 20px)[24];\n}\n\nLike the 960 grid system I was using as an example, my grid starts with a gutter, followed by the first actual column, plus another gutter repeated sixteen times. What this means is that if I want to span two columns, as far as the grid layout module is concerned that is actually three columns: two wide columns, plus one gutter. So this needs to be accounted for when positioning items.\n\nI created a CSS class for each positioning option: column position; rows position; and column span. For example:\n\n.grid1 {-ms-grid-column: 2;} /* applying this class positions an item in the first column (the gutter is column 1) */\n.grid2 {-ms-grid-column: 4;} /* 2nd column - gutter|column 1|gutter */\n.grid3 {-ms-grid-column: 6;} /* 3rd column - gutter|column 1|gutter|column2|gutter */\n\n.row1 {-ms-grid-row:1;}\n.row2 {-ms-grid-row:3;}\n.row3 {-ms-grid-row:5;}\n\n.colspan1 {-ms-grid-column-span:1;}\n.colspan2 {-ms-grid-column-span:3;}\n.colspan3 {-ms-grid-column-span:5;}\n\nI could then add multiple classes to each element to set the position on on the grid.\n\n\n\nThis then gives me a replica of the fluid grid using CSS3 grid layout. To see this working fire up IE10 and view Example 1.\n\nThis works, but\u2026\n\nThis worked, but isn\u2019t ideal. I considered not showing this stage of my experiment \u2013 however, I think it clearly shows how the grid layout module works and is a useful starting point. That said, it\u2019s not an approach I would take in production. First, we have to add classes to our markup that tie an element to a position on the grid. This might not be too much of a problem if we are always going to maintain the sixteen-column grid, though, as I will show you that the real power of the grid layout module appears once you start to redefine the grid, using different grids based on media queries. If you drop to a six-column layout for small screens, positioning items into column 16 makes no sense any more.\n\nCalculating grid position using LESS\n\nAs we\u2019ve seen, if you want to use a grid with main columns and gutters, you have to take into account the spacing between columns as well as the actual columns. This means we have to do some calculating every time we place an item on the grid. In my example above I got around this by creating a CSS class for each position, allowing me to think in sixteen rather than thirty-two columns. But by using a CSS preprocessor, I can avoid using all the classes yet still think in main columns.\n\nI\u2019m using LESS for my example. My simple grid framework consists of one simple mixin.\n\n.position(@column,@row,@colspan,@rowspan) {\n    -ms-grid-column: @column*2;\n    -ms-grid-row: @row*2-1;\n    -ms-grid-column-span: @colspan*2-1;\n    -ms-grid-row-span: @rowspan*2-1;\n}\n\nMy mixin takes four parameters: column; row; colspan; and rowspan. So if I wanted to place an item on column four, row three, spanning two columns and one row, I would write the following CSS:\n\n.box {\n    .position(4,3,2,1);\n}\n\nThe mixin would return:\n\n.box {\n    -ms-grid-column: 8;\n    -ms-grid-row: 5;\n    -ms-grid-column-span: 3;\n    -ms-grid-row-span: 1;\n}\n\nThis saves me some typing and some maths. I could also add other prefixed values into my mixin as other browsers started to add support.\n\nWe can see this in action creating a new grid. Instead of adding multiple classes to each element, I can add one class; that class uses the mixin to create the position. I have also played around with row spans using my mixin and you can see we end up with a quite complicated arrangement of boxes. Have a look at example two in IE10. I\u2019ve used the JavaScript LESS parser so that you can view the actual LESS that I use. Note that I have needed to escape the -ms prefixed properties with ~\"\" to get LESS to accept them.\n\n\n\nThis is looking better. I don\u2019t have direct positioning information on each element in the markup, just a class name \u2013 I\u2019ve used grid(x), but it could be something far more semantic. We can now take the example a step further and redefine the grid based on screen width.\n\nMedia queries and the grid\n\nThis example uses exactly the same markup as the previous example. However, we are now using media queries to detect screen width and redefine the grid using a different number of columns depending on that width.\n\nI start out with a six-column grid, defining that on .wrapper, then setting where the different items sit on this grid:\n\n.wrapper {\t \n    width: 90%;\n    margin: 0 auto 0 auto;\n    display: ~\"-ms-grid\"; /* escaped for the LESS parser */\n    -ms-grid-columns: ~\"1fr (4.25fr 1fr)[6]\"; /* escaped for the LESS parser */\n    -ms-grid-rows: ~\"(auto 20px)[40]\"; /* escaped for the LESS parser */\n}\n.grid1 { .position(1,1,1,1); } \n.grid2 { .position(2,1,1,1); } \n/* ... see example for all declarations ... */\n\n\n\nUsing media queries, I redefine the grid to nine columns when we hit a minimum width of 700 pixels.\n\n@media only screen and (min-width: 700px) {\n.wrapper {\n    -ms-grid-columns: ~\"1fr (4.25fr 1fr)[9]\";\n    -ms-grid-rows: ~\"(auto 20px)[50]\";\n}\n.grid1 { .position(1,1,1,1); } \n.grid2 { .position(2,1,1,1); } \n/* ... */\n}\n\n\n\nFinally, we redefine the grid for 960 pixels, back to the sixteen-column grid we started out with.\n\n@media only screen and (min-width:  940px) {\n.wrapper {\t \n    -ms-grid-columns:~\" 1fr (4.25fr 1fr)[16]\";\n    -ms-grid-rows:~\" (auto 20px)[24]\";\n}\n.grid1 { .position(1,1,1,1); } \n.grid2 { .position(2,1,1,1); } \n/* ... */\n}\n\nIf you view example three in Internet Explorer 10 you can see how the items reflow to fit the window size. You can also see, looking at the final set of blocks, that source order doesn\u2019t matter. You can pick up a block from anywhere and place it in any position on the grid.\n\nLaying out a simple website\n\nSo far, like a toddler on Christmas Day, we\u2019ve been playing with boxes rather than thinking about what might be in them. So let\u2019s take a quick look at a more realistic layout, in order to see why the CSS3 grid layout module can be really useful. At this time of year, I am very excited to get out of storage my collection of odd nativity sets, prompting my family to suggest I might want to open a museum. Should I ever do so, I\u2019ll need a website, and here is an example layout.\n\n\n\nAs I am using CSS3 grid layout, I can order my source in a logical manner. In this example my document is as follows, though these elements could be in any order I please:\n\n<div class=\"wrapper\">\n  <div class=\"welcome\">\n  ...\n  </div>\n  <article class=\"main\">\n  ...\n  </article>\n  <div class=\"info\">\n  ...\n  </div>\n  <div class=\"ads\">\n  ...\n  </div>\n</div>\n\nFor wide viewports I can use grid layout to create a sidebar, with the important information about opening times on the top righ,t with the ads displayed below it. This creates the layout shown in the screenshot above.\n\n@media only screen and (min-width:  940px) {\n  .wrapper {\t \n    -ms-grid-columns:~\" 1fr (4.25fr 1fr)[16]\";\n    -ms-grid-rows:~\" (auto 20px)[24]\";\n  }\n  .welcome {\n    .position(1,1,12,1);\n    padding: 0 5% 0 0;\n  }\n  .info {\n    .position(13,1,4,1);\n    border: 0;\n    padding:0;\n   }\n  .main {\n    .position(1,2,12,1);\n    padding: 0 5% 0 0;\n  }  \n  .ads {\n    .position(13,2,4,1);\n    display: block;\n    margin-left: 0;\n  }\n}\n\nIn a floated layout, a sidebar like this often ends up being placed under the main content at smaller screen widths. For my situation this is less than ideal. I want the important information about opening times to end up above the main article, and to push the ads below it. With grid layout I can easily achieve this at the smallest width .info ends up in row two and .ads in row five with the article between.\n\n.wrapper {\t \n  display: ~\"-ms-grid\";\n  -ms-grid-columns: ~\"1fr (4.25fr 1fr)[4]\";\n  -ms-grid-rows: ~\"(auto 20px)[40]\";\n}\n.welcome {\n    .position(1,1,4,1);\n}\n.info {\n    .position(1,2,4,1);\n    border: 4px solid #fff;\n    padding: 10px;\n}\n.content {\n    .position(1,3,4,5);\n}\n.main {\n    .position(1,3,4,1);\n}\n.ads {\n    .position(1,4,4,1);\n}\n\n\n\nFinally, as an extra tweak I add in a breakpoint at 600 pixels and nest a second grid on the ads area, arranging those three images into a row when they sit below the article at a screen width wider than the very narrow mobile width but still too narrow to support a sidebar. \n\n@media only screen and (min-width:  600px) {\n  .ads {\n    display: ~\"-ms-grid\";\n    -ms-grid-columns: ~\"20px 1fr 20px 1fr 20px 1fr\";\n    -ms-grid-rows: ~\"1fr\";\n    margin-left: -20px;\n  }\n  .ad:nth-child(1) {\n    .position(1,1,1,1);\n  }\n  .ad:nth-child(2) {\n    .position(2,1,1,1);\n  }\n  .ad:nth-child(3) {\n    .position(3,1,1,1);\n  }\n}\n\nView example four in Internet Explorer 10.\n\n\n\nThis is a very simple example to show how we can use CSS grid layout without needing to add a lot of classes to our document. It also demonstrates how we can mainpulate the content depending on the context in which the user is viewing it.\n\nLayout, source order and the idea of content priority\n\nCSS3 grid layout isn\u2019t the only module that starts to move us away from the issue of visual layout being linked to source order. However, with good support in Internet Explorer 10, it is a nice way to start looking at how this might work. If you look at the grid layout module as something to be used in conjunction with the flexible box layout module and the very interesting CSS regions and exclusions specifications, we have, tantalizingly on the horizon, a powerful set of tools for layout.\n\nI am particularly keen on the potential separation of source order from layout as it dovetails rather neatly into something I spend a lot of time thinking about. As a CMS developer, working on larger scale projects as well as our CMS product Perch, I am interested in how we better enable content editors to create content for the web. In particular, I search for better ways to help them create adaptive content; content that will work in a variety of contexts rather than being tied to one representation of that content.\n\nIf the concept of adaptive content is new to you, then Karen McGrane\u2019s presentation Adapting Ourselves to Adaptive Content is the place to start. Karen talks about needing to think of content as chunks, that might be used in many different places, displayed differently depending on context.\n\nI absolutely agree with Karen\u2019s approach to content. We have always attempted to move content editors away from thinking about creating a page and previewing it on the desktop. However at some point content does need to be published as a page, or a collection of content if you prefer, and bits of that content have priority. Particularly in a small screen context, content gets linearized, we can only show so much at a time, and we need to make sure important content rises to the top. In the case of my example, I wanted to ensure that the address information was clearly visible without scrolling around too much. Dropping it with the entire sidebar to the bottom of the page would not have been so helpful, though neither would moving the whole sidebar to the top of the screen so a visitor had to scroll past advertising to get to the article.\n\nIf our layout is linked to our source order, then enabling the content editor to make decisions about priority is really hard. Only a system that can do some regeneration of the source order on the server-side \u2013 perhaps by way of multiple templates \u2013 can allow those kinds of decisions to be made. For larger systems this might be a possibility; for smaller ones, or when using an off-the-shelf CMS, it is less likely to be. Fortunately, any system that allows some form of custom field type can be used to pop a class on to an element, and with CSS grid layout that is all that is needed to be able to target that element and drop it into the right place when the content is viewed, be that on a desktop or a mobile device.\n\nThis approach can move us away from forcing editors to think visually. At the moment, I might have to explain to an editor that if a certain piece of content needs to come first when viewed on a mobile device, it needs to be placed in the sidebar area, tying it to a particular layout and design. I have to do this because we have to enforce fairly strict rules around source order to make the mechanics of the responsive design work. If I can instead advise an editor to flag important content as high priority in the CMS, then I can make decisions elsewhere as to how that is displayed, and we can maintain the visual hierarchy across all the different ways content might be rendered.\n\nWhy frustrate ourselves with specifications we can\u2019t yet use in production?\n\nThe CSS3 grid layout specification is listed under the Exploring section of the list of current work of the CSS Working Group. While discussing a module at this stage might seem a bit pointless if we can\u2019t use it in production work, there is a very real reason for doing so. If those of us who will ultimately be developing sites with these tools find out about them early enough, then we can start to give our feedback to the people responsible for the specification. There is information on the same page about how to get involved with the disussions.\n\nSo, if you have a bit of time this holiday season, why not have a play with the CSS3 grid layout module? I have outlined here some of my thoughts on how grid layout and other modules that separate layout from source order can be used in the work that I do. Likewise, wherever in the stack you work, playing with and thinking about new specifications means you can think about how you would use them to enhance your work. Spot a problem? Think that a change to the specification would improve things for a specific use case? Then you have something you could post to www-style to add to the discussion around this module.\n\nAll the examples are on CodePen so feel free to play around and fork them.", "year": "2012", "author": "Rachel Andrew", "author_slug": "rachelandrew", "published": "2012-12-18T00:00:00+00:00", "url": "https://24ways.org/2012/css3-grid-layout/", "topic": "code"}]