home / 24ways

24ways

Custom SQL query returning 11 rows

Query parameters

rowidtitlecontentsyearauthorauthor_slugpublishedurltopic
217 Beyond Web Mechanics – Creating Meaningful Web Design It was just over three years ago when I embarked on becoming a web designer, and the first opinion piece about the state of web design I came across was a conference talk by Elliot Jay Stocks called ‘Destroy the Web 2.0 Look’. Elliot’s presentation was a call to arms, a plea to web designers the world over to stop the endless reproductions of the so called ‘Web 2.0 look’. Three and a half years on from Elliot’s talk, what has changed? Well, from an aesthetic standpoint, not a whole lot. The Web 2.0 look has evolved, but it’s still with us and much of the web remains filled with cookie cutter websites that bear a striking resemblance to one another. This wouldn’t matter so much if these websites were selling comparable services or products, but they’re not. They look similar, they follow the same web design trends; their aesthetic style sends out a very similar message, yet they’re selling completely different services or products. How can you be communicating effectively with your users when your online book store is visually indistinguishable from an online cosmetic store? This just doesn’t make sense. I don’t want to belittle the current version of the Web 2.0 look for the sake of it. I want to talk about the opportunity we have as web designers to create more meaningful experiences for the people using our websites. Using design wisely gives us the ability to communicate messages, ideas and attitudes that our users will understand and connect with. Being human As human beings we respond emotionally to everything around us – people, objects, posters, packaging or websites. We also respond in different ways to different kinds of aesthetic design and style. We care about style and aesthetics deeply, whether we realise it or not. Aesthetic design has the power to attract or repel. We often make decisions based purely on aesthetics and style – and don’t retailers the world over know it! We connect attitudes and strongly held beliefs to style. Individuals will proudly associate themselves with a certain style or aesthetic because it’s an expression of who they are. You know that old phrase, ‘Don’t judge a book by its cover’? Well, the problem is that people do, so it’s important we get the cover right. Much is made of how to structure web pages, how to create a logical information hierarchy, how to use layout and typography to clearly communicate with your users. It’s important, however, not to mistake clarity of information or legibility with getting your message across. Few users actually read websites word by word: it’s far more likely they’ll just scan the page. If the page is copy-heavy and nothing grabs their attention, they may well just move on. This is why it’s so important to create a visual experience that actually means something to the user. Meaningful design When we view a poster or website, we make split-second assessments and judgements of what is in front of us. Our first impressions of what a website does or who it is aimed at are provoked by the style and aesthetic of the website. For example, with clever use of colour, typography, graphic design and imagery we can communicate to users that an organisation is friendly, edgy, compassionate, fun or environmentally conscious. Using a certain aesthetic we can convey the personality of that organisation, target age ranges, different sexes or cultural groups, communicate brand attributes, and more. We can make our users feel like they’re part of something and, perhaps even more importantly, we can make new users want to be a part of something. And we can achieve all this before the user has read a single word. By establishing a website’s aesthetic and creating a meaningful visual language, a design is no longer just a random collection of pretty gradients that have been plucked out of thin air. There can be a logic behind the design decisions we make. So, before you slap another generic piece of ribbon or an ultra shiny icon into the top-left corner of your website, think about why you are doing it. If you can’t come up with a reason better than “I saw it on another website”, it’s probably a poor application of style. Design and style There are a number of reasons why the web suffers from a lack meaningful design. Firstly, there are too many preconceptions of what a website should look like. It’s too easy for designers to borrow styles from other websites, thereby limiting the range of website designs we see on the web. Secondly, many web designers think of aesthetic design as of secondary importance, which shouldn’t be the case. Designing websites that are accessible and easy to use is, of course, very important but this is the very least a web designer should be delivering. Easy to use websites should come as standard – it’s equally important to create meaningful, compelling and beautiful experiences for everyone who uses our websites. The aesthetics of your site are part of the design, and to ignore this and play down the role of aesthetic design is just a wasted opportunity. No compromise necessary Easy to use, accessible websites and beautiful, meaningful aesthetics are not mutually exclusive. The key is to apply style and aesthetic design appropriately. We need to think about who and what we’re designing for and ask ourselves why we’re applying a certain kind of aesthetic style to our design. If you do this, there’s no reason why effective, functional design should come at the expense of jaw-dropping, meaningful aesthetics. Web designers need to understand the differences between functional design and aesthetic design but, even more importantly, they need to know how to make them work together. It’s combining these elements of design successfully that makes for the best web design in the world. 2010 Mike Kus mikekus 2010-12-05T00:00:00+00:00 https://24ways.org/2010/beyond-web-mechanics-creating-meaningful-web-design/ design
218 Put Yourself in a Corner Some backstory, and a shameful confession For the first couple years of high school I was one of those jerks who made only the minimal required effort in school. Strangely enough, how badly I behaved in a class was always in direct proportion to how skilled I was in the subject matter. In the subjects where I was confident that I could pass without trying too hard, I would give myself added freedom to goof off in class. Because I was a closeted lit-nerd, I was most skilled in English class. I’d devour and annotate required reading over the weekend, I knew my biblical and mythological allusions up and down, and I could give you a postmodern interpretation of a text like nobody’s business. But in class, I’d sit in the back and gossip with my friends, nap, or scribble patterns in the margins of my textbooks. I was nonchalant during discussion, I pretended not to listen during lectures. I secretly knew my stuff, so I did well enough on tests, quizzes, and essays. But I acted like an ass, and wasn’t getting the most I could out of my education. The day of humiliation, but also epiphany One day in Ms. Kaney’s AP English Lit class, I was sitting in the back doodling. An earbud was dangling under my sweater hood, attached to the CD player (remember those?) sitting in my desk. Because of this auditory distraction, the first time Ms. Kaney called my name, I barely noticed. I definitely heard her the second time, when she didn’t call my name so much as roar it. I can still remember her five feet frame stomping across the room and grabbing an empty desk. It screamed across the worn tile as she slammed it next to hers. She said, “This is where you sit now.” My face gets hot just thinking about it. I gathered my things, including the CD player (which was now impossible to conceal), and made my way up to the newly appointed Seat of Shame. There I sat, with my back to the class, eye-to-eye with Ms. Kaney. From my new vantage point I couldn’t see my friends, or the clock, or the window. All I saw were Ms. Kaney’s eyes, peering at me over her reading glasses while I worked. In addition to this punishment, I was told that from now on, not only would I participate in class discussions, but I would serve detention with her once a week until an undetermined point in the future. During these detentions, Ms. Kaney would give me new books to read, outside the curriculum, and added on to my normal homework. They ranged from classics to modern novels, and she read over my notes on each book. We’d discuss them at length after class, and I grew to value not only our private discussions, but the ones in class as well. After a few weeks, there wasn’t even a question of this being punishment. It was heaven, and I was more productive than ever. To the point Please excuse this sentimental story. It’s not just about honoring a teacher who cared enough to change my life, it’s really about sharing a lesson. The most valuable education Ms. Kaney gave me had nothing to do with literature. She taught me that I (and perhaps other people who share my special brand of crazy) need to be put in a corner to flourish. When we have physical and mental constraints applied, we accomplish our best work. For those of you still reading, now seems like a good time to insert a pre-emptive word of mediation. Many of you, maybe all of you, are self-disciplined enough that you don’t require the rigorous restrictions I use to maximize productivity. Also, I know many people who operate best in a stimulating and open environment. I would advise everyone to seek and execute techniques that work best for them. But, for those of you who share my inclination towards daydreams and digressions, perhaps you’ll find something useful in the advice to follow. In which I pretend to be Special Agent Olivia Dunham Now that I’m an adult, and no longer have Ms. Kaney to reign me in, I have to find ways to put myself in the corner. By rejecting distraction and shaping an environment designed for intense focus, I’m able to achieve improved productivity. Lately I’ve been obsessed with the TV show Fringe, a sci-fi series about an FBI agent and her team of genius scientists who save the world (no, YOU’RE a nerd). There’s a scene in the show where the primary character has to delve into her subconscious to do extraordinary things, and she accomplishes this by immersing herself in a sensory deprivation tank. The premise is this: when enclosed in a space devoid of sound, smell, or light, she will enter a new plane of consciousness wherein she can tap into new levels of perception. This might sound a little nuts, but to me this premise has some real-world application. When I am isolated from distraction, and limited to only the task at hand, I’m able to be productive on a whole new level. Since I can’t actually work in an airtight iron enclosure devoid of input, I find practical ways to create an interruption-free environment. Since I work from home, many of my methods for coping with distractions wouldn’t be necessary for my office-bound counterpart. However for some of you 9-to-5-ers, the principles will still apply. Consider your visual input First, I have to limit my scope to the world I can (and need to) affect. In the largest sense, this means closing my curtains to the chaotic scene of traffic, birds, the post office, a convenience store, and generally lovely weather that waits outside my window. When the curtains are drawn and I’m no longer surrounded by this view, my sphere is reduced to my desk, my TV, and my cat. Sometimes this step alone is enough to allow me to focus. But, my visual input can be whittled down further still. For example, the desk where I usually keep my laptop is littered with twelve owl figurines, a globe, four books, a three-pound weight, and various nerdy paraphernalia (hard drives, Wacom tablets, unnecessary bluetooth accessories, and so on). It’s not so much a desk as a dumping ground for wacky flea market finds and impulse technology buys. Therefore, in addition to this Official Desk, I have an adult version of Ms. Kaney’s Seat of Shame. It’s a rusty old student’s desk I picked up at the Salvation Army, almost an exact replica of the model Ms. Kaney dragged across the classroom all those years ago. This tiny reproduction Seat of Shame is literally in a corner, where my only view is a blank wall. When I truly need to focus, this is where I take refuge, with only a notebook and a pencil (and occasionally an iPad). Find out what works for your ears Even from my limited sample size of two people, I know there are lots of different ways to cope with auditory distraction. I prefer silence when focused on independent work, and usually employ some form of a white noise generator. I’ve yet to opt for the fancy ‘real’ white noise machines; instead, I use a desktop fan or our allergy filter machine. This is usually sufficient to block out the sounds of the dishwasher and the cat, which allows me to think only about the task of hand. My boyfriend, the other half of my extensive survey, swears by another method. He calls it The Wall of Sound, and it’s basically an intense blast of raucous music streamed directly into his head. The outcome of his technique is really the same as mine; he’s blocking out unexpected auditory input. If you can handle the grating sounds of noisy music while working, I suggest you give The Wall of Sound a try. Don’t count the minutes When I sat in the original Seat of Shame in lit class, I could no longer see the big classroom clock slowly ticking away the seconds until lunch. Without the marker of time, the class period often flew by. The same is true now when I work; the less aware of time I am, the less it feels like time is passing too quickly or slowly, and the more I can focus on the task (not how long it takes). Nowadays, to assist in my effort to forget the passing of time, I sometimes put a sticky note over the clock on my monitor. If I’m writing, I’ll use an app like WriteRoom, which blocks out everything but a simple text editor. There are situations when it’s not advisable to completely lose track of time. If I’m working on a project with an hourly rate and a tight scope, or if I need to be on time to a meeting or call, I don’t want to lose myself in the expanse of the day. In these cases, I’ll set an alarm that lets me know it’s time to reign myself back in (or on some days, take a shower). Put yourself in a mental corner, too When Ms. Kaney took action and forced me to step up my game, she had the insight to not just change things physically, but to challenge me mentally as well. She assigned me reading material outside the normal coursework, then upped the pressure by requiring detailed reports of the material. While this additional stress was sometimes uncomfortable, it pushed me to work harder than I would have had there been less of a demand. Just as there can be freedom in the limitations of a distraction-free environment, I’d argue there is liberty in added mental constraints as well. Deadlines as a constraint Much has been written about the role of deadlines in the creative process, and they seem to serve different functions in different cases. I find that deadlines usually act as an important constraint and, without them, it would be nearly impossible for me to ever consider a project finished. There are usually limitless ways to improve upon the work I do and, if there’s no imperative for me to be done at a certain point, I will revise ad infinitum. (Hence, the personal site redesign that will never end – Coming Soon, Forever!). But if I have a clear deadline in mind, there’s a point when the obsessive tweaking has to stop. I reach a stage where I have to gather up the nerve to launch the thing. Putting the pro in procrastination Sometimes I’ve found that my tendency to procrastinate can help my productivity. (Ducks, as half the internet throws things at her.) I understand the reasons why procrastination can be harmful, and why it’s usually a good idea to work diligently and evenly towards a goal. I try to divide my projects up in a practical way, and sometimes I even pull it off. But for those tasks where you work aimlessly and no focus comes, or you find that every other to-do item is more appealing, sometimes you’re forced to bring it together at the last moment. And sometimes, this environment of stress is a formula for magic. Often when I’m down to the wire and have no choice but to produce, my mind shifts towards a new level of clarity. There’s no time to endlessly browse for inspiration, or experiment with convoluted solutions that lead nowhere. Obviously a life lived perpetually on the edge of a deadline would be a rather stressful one, so it’s not a state of being I’d advocate for everyone, all the time. But every now and then, the work done when I’m down to the wire is my best. Keep one toe outside your comfort zone When I’m choosing new projects to take on, I often seek out work that involves an element of challenge. Whether it’s a design problem that will require some creative thinking, or a coding project that lends itself to using new technology like HTML5, I find a manageable level of difficulty to be an added bonus. The tension that comes from learning a new skill or rethinking an old standby is a useful constraint, as it keeps the work interesting, and ensures that I continue learning. There you have it Well, I think I’ve spilled most of my crazy secrets for forcing my easily distracted brain to focus. As with everything we web workers do, there are an infinite number of ways to encourage productivity. I hope you’ve found a few of these to be helpful, and please share your personal techniques in the comments. Have a happy and productive new year! 2010 Meagan Fisher meaganfisher 2010-12-20T00:00:00+00:00 https://24ways.org/2010/put-yourself-in-a-corner/ process
221 “Probably, Maybe, No”: The State of HTML5 Audio With the hype around HTML5 and CSS3 exceeding levels not seen since 2005’s Ajax era, it’s worth noting that the excitement comes with good reason: the two specifications render many years of feature hacks redundant by replacing them with native features. For fun, consider how many CSS2-based rounded corners hacks you’ve probably glossed over, looking for a magic solution. These days, with CSS3, the magic is border-radius (and perhaps some vendor prefixes) followed by a coffee break. CSS3’s border-radius, box-shadow, text-shadow and gradients, and HTML5’s <canvas>, <audio> and <video> are some of the most anticipated features we’ll see put to creative (ab)use as adoption of the ‘new shiny’ grows. Developers jumping on the cutting edge are using subsets of these features to little detriment, in most cases. The more popular CSS features are design flourishes that can degrade nicely, but the current audio and video implementations in particular suffer from a number of annoyances. The new shiny: how we got here Sound involves one of the five senses, a key part of daily life for most – and yet it has been strangely absent from HTML and much of the web by default. From a simplistic perspective, it seems odd that HTML did not include support for the full multimedia experience earlier, despite the CD-ROM-based craze of the early 1990s. In truth, standards like HTML can take much longer to bake, but eventually deliver the promise of a lowered barrier to entry, consistent implementations and shiny new features now possible ‘for free’ just about everywhere. <img> was introduced early and naturally to HTML, despite having some opponents at the time. Perhaps <audio> and <video> were avoided, given the added technical complexity of decoding various multi-frame formats, plus the hardware and bandwidth limitations of the era. Perhaps there were quarrels about choosing a standard format or – more simply – maybe these elements just weren’t considered to be applicable to the HTML-based web at the time. In any event, browser plugins from programs like RealPlayer and QuickTime eventually helped to fill the in-page audio/video gap, handling <object> and <embed> markup which pointed to .wav, .avi, .rm or .mov files. Suffice it to say, the experience was inconsistent at best and, on the standards side of the fence right now, so is HTML5 in terms of audio and video. : the theory As far as HTML goes, the code for <audio> is simple and logical. Just as with <img>, a src attribute specifies the file to load. Pretty straightforward – sounds easy, right? <audio src="mysong.ogg" controls> <!-- alternate content for unsupported case --> Download <a href="mysong.ogg">mysong.ogg</a>; </audio> Ah, if only it were that simple. The first problem is that the OGG audio format, while ‘free’, is not supported by some browsers. Conversely, nor is MP3, despite being a de facto standard used in all kinds of desktop software (and hardware). In fact, as of November 2010, no single audio format is commonly supported across all major HTML5-enabled browsers. What you end up writing, then, is something like this: <audio controls> <source src="mysong.mp3" /> <source src="mysong.ogg" /> <!-- alternate content for unsupported case, maybe Flash, etc. --> Download <a href="mysong.ogg">mysong.ogg</a> or <a href="mysong.mp3">mysong.mp3</a> </audio> Keep in mind, this is only a ‘first class’ experience for the HTML5 case; also, for non-supported browsers, you may want to look at another inline player (object/embed, or a JavaScript plus Flash API) to have inline audio. You can imagine the added code complexity in the case of supporting ‘first class’ experiences for older browsers, too. : the caveats With <img>, you typically don’t have to worry about format support – it just works – and that’s part of what makes a standard wonderful. JPEG, PNG, BMP, GIF, even TIFF images all render just fine if for no better reason, perhaps, than being implemented during the ‘wild west’ days of the web. The situation with <audio> today reflects a very different – read: business-aware – environment in 2010. (Further subtext: There’s a lot of [potential] money involved.) Regrettably, this is a collision of free and commercial interests, where the casualty is ultimately the user. Second up in the casualty list is you, the developer, who has to write additional code around this fragmented support. The HTML5 audio API as implemented in JavaScript has one of the most un-computer-like responses I’ve ever seen, and inspired the title of this post. Calling new Audio().canPlayType('audio/mp3'), which queries the system for format support according to a MIME type, is supposed to return one of “probably”, “maybe”, or “no”. Sometimes, you’ll just get a null or empty string, which is also fun. A “maybe” response does not guarantee that a format will be supported; sometimes audio/mp3 gives “maybe,” but then audio/mpeg; codecs="mp3" will give a more-solid “probably” response. This can vary by browser or platform, too, depending on native support – and finally, the user may also be able to install codecs, extending support to include other formats. (Are you excited yet?) Damn you, warring formats! New market and business opportunities go hand-in-hand with technology developments. What we have here is certainly not failure to communicate; rather, we have competing parties shouting loudly in public in attempts to influence mindshare towards a de facto standard for audio and video. Unfortunately, the current situation means that at least two formats are effectively required to serve the majority of users correctly. As it currently stands, we have the free and open source software camp of OGG Vorbis/WebM and its proponents (notably, Mozilla, Google and Opera in terms of browser makers), up against the non-free, proprietary and ‘closed’ camp of MP3 and MPEG4/HE-AAC/H.264 – which is where you’ll find commitments from Apple and Microsoft, among others. Apple is likely in with H.264 for the long haul, given its use of the format for its iTunes music store and video offerings. It is generally held that H.264 is a technically superior format in terms of file size versus quality, but it involves intellectual property and, in many use cases, requires licensing fees. To be fair, there is a business model with H.264 and much has been invested in its development, but this approach is not often the kind that wins over the web. On that front, OGG/WebM may eventually win for being a ‘free’ format that does not involve a licensing scheme. Closed software and tools ideologically clash with the open nature of the web, which exists largely thanks to free and open technology. Because of philosophical and business reasons, support for audio and video is fragmented across browsers adopting HTML5 features. It does not help that a large amount of audio and video currently exists in non-free MP3 and MPEG-4 formats. Adoption of <audio> and <video> may be slowed, since it is more complex than <img> and may feel ‘broken’ to developers when edge cases are encountered. Furthermore, the HTML5 spec does not mandate a single required format. The end result is that, as a developer, you must currently provide at least both MP3 and OGG, for example, to serve most existing HTML5-based user agents. Transitioning to There will be some growing pains as developers start to pick up the new HTML5 shiny, while balancing the needs of current and older agents that don’t support either <audio> or the preferred format you may choose (for example, MP3). In either event, Flash or other plugins can be used as done traditionally within HTML4 documents to embed and play the relevant audio. The SoundManager 2 page player demo in action. Ideally, HTML5 audio should be used whenever possible with Flash as the backup option. A few JavaScript/Flash-based audio player projects exist which balance the two; in attempting to tackle this problem, I develop and maintain SoundManager 2, a JavaScript sound API which transparently uses HTML5 Audio() and, if needed, Flash for playing audio files. The internals can get somewhat ugly, but the transition between HTML4 and HTML5 is going to be just that – and even with HTML5, you will need some form of format fall-back in addition to graceful degradation. It may be safest to fall back to MP3/MP4 formats for inline playback at this time, given wide support via Flash, some HTML5-based browsers and mobile devices. Considering the amount of MP3/MP4 media currently available, it is wiser to try these before falling through to a traditional file download process. Early findings Here is a brief list of behavioural notes, annoyances, bugs, quirks and general weirdness I have found while playing with HTML5-based audio at time of writing (November 2010): Apple iPad/iPhone (iOS 4, iPad 3.2+) Only one sound can be played at a time. If a second sound starts, the first is stopped. No auto-play allowed. Sounds follow the pop-up window security model and can only be started from within a user event handler such as onclick/touch, and so on. Otherwise, playback attempts silently fail. Once started, a sequence of sounds can be created or played via the ‘finish’ event of the previous sound (for example, advancing through a playlist without interaction after first track starts). iPad, iOS 3.2: Occasional ‘infinite loop’ bug seen where audio does not complete and stop at a sound’s logical end – instead, it plays again from the beginning. Might be specific to example file format (HE-AAC) encoded from iTunes. Apple Safari, OS X Snow Leopard 10.6.5 Critical bug: Safari 4 and 5 intermittently fail to load or play HTML5 audio on Snow Leopard due to bug(s) in QuickTime X and/or other underlying frameworks. Known Apple ‘radar’ bug: bugs.webkit.org #32159 (see also, test case.) Amusing side note: Safari on Windows is fine. Apple Safari, Windows Food for thought: if you download “Safari” alone on Windows, you will not get HTML5 audio/video support (tested in WinXP). You need to download “Safari + QuickTime” to get HTML5 audio/video support within Safari. (As far as I’m aware, Chrome, Firefox and Opera either include decoders or use system libraries accordingly. Presumably IE 9 will use OS-level APIs.) General Quirks Seeking and loading, ‘progress’ events, and calculating bytes loaded versus bytes total should not be expected to be linear, as users can arbitrarily seek within a sound. It appears that some support for HTTP ranges exists, which adds a bit of logic to UI code. Browsers seem to vary slightly in their current implementations of these features. The onload event of a sound may be of little relevance, if non-linear loading is involved (see above note re: seeking). Interestingly (perhaps I missed it), the current spec does not seem to specify a panning or left/right channel mix option. The preload attribute values may vary slightly between browsers at this time. Upcoming shiny: HTML5 Audio Data API With access to audio data, you can incorporate waveform and spectrum elements that make your designs react to music. The HTML5 audio spec does a good job covering the basics of playback, but did not initially get into manipulation or generation of audio on-the-fly, something Flash has had for a number of years now. What if JavaScript could create, monitor and change audio dynamically, like a sort of audio <canvas> element? With that kind of capability, many dynamic audio processing features become feasible and, when combined with other media, can make for some impressive demos. What started as a small idea among a small group of audio and programming enthusiasts grew to inspire a W3C audio incubator group, and continued to establish the Mozilla Audio Data API. Contributors wrote a patch for Firefox which was reviewed and revised, and is now slated to be in the public release of Firefox 4. Some background and demos are also detailed in an article from the BBC R&D blog. There are plenty of live demos to see, which give an impression of the new creative ideas this API enables. Many concepts are not new in themselves, but it is exciting to see this sort of thing happening within the native browser context. Mozilla is not alone in this effort; the WebKit folks are also working on a JavaScriptAudioNode interface, which implements similar audio buffering and sample elements. The future? It is my hope that we’ll see a common format emerge in terms of support across the major browsers for both audio and video; otherwise, support will continue to be fragmented and mildly frustrating to develop for, and that can impede growth of the feature. It’s a big call, but if <img> had lacked a common format back in the wild west era, I doubt the web would have grown to where it is today. Complaints and nitpicks aside, HTML5 brings excellent progress on the browser multimedia front, and the first signs of native support are a welcome improvement given all audio and video previously relied on plugins. There is good reason to be excited. While there is room for more, support could certainly be much worse – and as tends to happen with specifications, the implementations targeting them should improve over time. Note: Thanks to Nate Koechley, who suggested the Audio().canPlayType() response be part of the article title. 2010 Scott Schiller scottschiller 2010-12-08T00:00:00+00:00 https://24ways.org/2010/the-state-of-html5-audio/ code
223 Calculating Color Contrast Some websites and services allow you to customize your profile by uploading pictures, changing the background color or other aspects of the design. As a customer, this personalization turns a web app into your little nest where you store your data. As a designer, letting your customers have free rein over the layout and design is a scary prospect. So what happens to all the stock text and images that are designed to work on nice white backgrounds? Even the Mac only lets you choose between two colors for the OS, blue or graphite! Opening up the ability to customize your site’s color scheme can be a recipe for disaster unless you are flexible and understand how to find maximum color contrasts. In this article I will walk you through two simple equations to determine if you should be using white or black text depending on the color of the background. The equations are both easy to implement and produce similar results. It isn’t a matter of which is better, but more the fact that you are using one at all! That way, even with the craziest of Geocities color schemes that your customers choose, at least your text will still be readable. Let’s have a look at a range of various possible colors. Maybe these are pre-made color schemes, corporate colors, or plucked from an image. Now that we have these potential background colors and their hex values, we need to find out whether the corresponding text should be in white or black, based on which has a higher contrast, therefore affording the best readability. This can be done at runtime with JavaScript or in the back-end before the HTML is served up. There are two functions I want to compare. The first, I call ’50%’. It takes the hex value and compares it to the value halfway between pure black and pure white. If the hex value is less than half, meaning it is on the darker side of the spectrum, it returns white as the text color. If the result is greater than half, it’s on the lighter side of the spectrum and returns black as the text value. In PHP: function getContrast50($hexcolor){ return (hexdec($hexcolor) > 0xffffff/2) ? 'black':'white'; } In JavaScript: function getContrast50(hexcolor){ return (parseInt(hexcolor, 16) > 0xffffff/2) ? 'black':'white'; } It doesn’t get much simpler than that! The function converts the six-character hex color into an integer and compares that to one half the integer value of pure white. The function is easy to remember, but is naive when it comes to understanding how we perceive parts of the spectrum. Different wavelengths have greater or lesser impact on the contrast. The second equation is called ‘YIQ’ because it converts the RGB color space into YIQ, which takes into account the different impacts of its constituent parts. Again, the equation returns white or black and it’s also very easy to implement. In PHP: function getContrastYIQ($hexcolor){ $r = hexdec(substr($hexcolor,0,2)); $g = hexdec(substr($hexcolor,2,2)); $b = hexdec(substr($hexcolor,4,2)); $yiq = (($r*299)+($g*587)+($b*114))/1000; return ($yiq >= 128) ? 'black' : 'white'; } In JavaScript: function getContrastYIQ(hexcolor){ var r = parseInt(hexcolor.substr(0,2),16); var g = parseInt(hexcolor.substr(2,2),16); var b = parseInt(hexcolor.substr(4,2),16); var yiq = ((r*299)+(g*587)+(b*114))/1000; return (yiq >= 128) ? 'black' : 'white'; } You’ll notice first that we have broken down the hex value into separate RGB values. This is important because each of these channels is scaled in accordance to its visual impact. Once everything is scaled and normalized, it will be in a range between zero and 255. Much like the previous ’50%’ function, we now need to check if the input is above or below halfway. Depending on where that value is, we’ll return the corresponding highest contrasting color. That’s it: two simple contrast equations which work really well to determine the best readability. If you are interested in learning more, the W3C has a few documents about color contrast and how to determine if there is enough contrast between any two colors. This is important for accessibility to make sure there is enough contrast between your text and link colors and the background. There is also a great article by Kevin Hale on Particletree about his experience with choosing light or dark themes. To round it out, Jonathan Snook created a color contrast picker which allows you to play with RGB sliders to get values for YIQ, contrast and others. That way you can quickly fiddle with the knobs to find the right balance. Comparing results Let’s revisit our color schemes and see which text color is recommended for maximum contrast based on these two equations. If we use the simple ’50%’ contrast function, we can see that it recommends black against all the colors except the dark green and purple on the second row. In general, the equation feels the colors are light and that black is a better choice for the text. The more complex ‘YIQ’ function, with its weighted colors, has slightly different suggestions. White text is still recommended for the very dark colors, but there are some surprises. The red and pink values show white text rather than black. This equation takes into account the weight of the red value and determines that the hue is dark enough for white text to show the most contrast. As you can see, the two contrast algorithms agree most of the time. There are some instances where they conflict, but overall you can use the equation that you prefer. I don’t think it is a major issue if some edge-case colors get one contrast over another, they are still very readable. Now let’s look at some common colors and then see how the two functions compare. You can quickly see that they do pretty well across the whole spectrum. In the first few shades of grey, the white and black contrasts make sense, but as we test other colors in the spectrum, we do get some unexpected deviation. Pure red #FF0000 has a flip-flop. This is due to how the ‘YIQ’ function weights the RGB parts. While you might have a personal preference for one style over another, both are justifiable. In this second round of colors, we go deeper into the spectrum, off the beaten track. Again, most of the time the contrasting algorithms are in sync, but every once in a while they disagree. You can select which you prefer, neither of which is unreadable. Conclusion Contrast in color is important, especially if you cede all control and take a hands-off approach to the design. It is important to select smart defaults by making the contrast between colors as high as possible. This makes it easier for your customers to read, increases accessibility and is generally just easier on the eyes. Sure, there are plenty of other equations out there to determine contrast; what is most important is that you pick one and implement it into your system. So, go ahead and experiment with color in your design. You now know how easy it is to guarantee that your text will be the most readable in any circumstance. 2010 Brian Suda briansuda 2010-12-24T00:00:00+00:00 https://24ways.org/2010/calculating-color-contrast/ code
224 Go Forth and Make Awesomeness We’ve all dreamed of being a superhero: maybe that’s why we’ve ended up on the web—a place where we can do good deeds and celebrate them on a daily basis. Wear your dreams At age four, I wore my Wonder Woman Underoos around my house, my grandparents’ house, our neighbor’s house, and even around the yard. I wanted to be a superhero when I grew up. I was crushed to learn that there is no school for superheroes—no place to earn a degree in how to save the world from looming evil. Instead, I—like everyone else—was destined to go to ordinary school to focus on ABCs and 123s. Even still, I want to save the world. Intend your goodness Random acts of kindness make a difference. Books, films, and advertising campaigns tout random acts of kindness and the positive influence they can have on the world. But why do acts of kindness have to be so random? Why can’t we intend to be kind? A true superhero wakes each morning intending to perform selfless acts for the community. Why can’t we do the same thing? As a child, my mother taught me to plan to do at least three good deeds each day. And even now, years later, I put on my invisible cape looking for ways to do good. Here are some examples: slowing down to allow another driver in before me from the highway on-ramp bringing a co-worker their favorite kind of coffee or tea sharing my umbrella on a rainy day holding a door open for someone with full hands listening intently when someone shares a story complimenting someone on a job well done thanking someone for a job well done leaving a constructive, or even supportive comment on someone’s blog As you can see, these acts are simple. Doing good and being kind is partially about being aware—aware of the words we speak and the actions we take. Like superheroes, we create our own code of conduct to live by. Hopefully, we choose to put the community before ourselves (within reason) and to do our best not to damage it as we move through our lives. Take a bite out of the Apple With some thought, we can weave this type of thinking and action into our business choices. We can take the simple acts of kindness concept and amplify it a bit. With this amplification, we can be a new kind of superhero. In 1997, during a presentation, Steve Jobs stated Apple’s core value in a simple, yet powerful, sentence: We believe that people with passion can change the world for the better. Apple fan or not, those are powerful words. Define your core Every organization must define its core values. Core values help us to frame, recognize, and understand the principles our organization embodies and practices. It doesn’t matter if you’re starting a new organization or you want to define values within an existing organization. Even if you’re a freelancer, defining core values will help guide your decisions and actions. If you can, work as a team to define core values. Gather the people who are your support system—your business partners, your colleagues, and maybe even a trusted client—this is now your core value creation team. Have a brainstorming session with your team. Let ideas flow. Give equal weight to the things people say. You may not hear everything you thought you might hear—that’s OK. You want the session to be free-flowing and honest. Ask yourself and your team questions like: What do you think my/our/your core values are? What do you think my/our/your priorities are? What do you think my/our/your core values should be? What do you think my/our/your priorities should be? How do you think I/we should treat customers, clients, and each other? How do we want others to treat us? What are my/our/your success stories? What has defined these experiences as successful? From this brainstorming session, you will craft your superhero code of conduct. You will decide what you will and will not do. You will determine how you will and will not act. You’re setting the standards that you will live and work by—so don’t take this exercise lightly. Take your time. Use the exercise as a way to open a discussion about values. Find out what you and your team believe in. Set these values and keep them in place. Write them down and share these with your team and with the world. By sharing your core values, you hold yourself more accountable to them. You also send a strong message to the rest of the world about what type of organization you are and what you believe in. Other organizations and people may decide to align or not to align themselves with you because of your core values. This is good. Chances are, you’ll be happier and more profitable if you work with other organizations and people who share similar core values. Photo: Laura Winn During your brainstorming session, list keywords. Don’t edit. Allow things to take their course. Some examples of keywords might be: Ability · Achievement · Adventure · Ambition · Altruism · Awareness · Balance · Caring · Charity · Citizenship · Collaboration · Commitment · Community · Compassion · Consideration · Cooperation · Courage · Courtesy · Creativity · Democracy · Dignity · Diplomacy · Discipline · Diversity · Education · Efficiency · Energy · Equality · Excellence · Excitement · Fairness · Family · Freedom · Fun · Goodness · Gratefulness · Growth · Happiness · Harmony · Helping · Honor · Hope · Humility · Humor · Imagination · Individuality · Innovation · Integrity · Intelligence · Joy · Justice · Kindness · Knowledge · Leadership · Learning · Loyalty · Meaning · Mindfulness · Moderation · Modesty · Nurture · Openness · Organization · Passion · Patience · Peace · Planning · Principles · Productivity · Purpose · Quality · Reliability · Respectfulness · Responsibility · Security · Sensitivity · Service · Sharing · Simplicity · Stability · Tolerance · Transparency · Trust · Truthfulness · Understanding · Unity · Variety · Vision · Wisdom After you have a list of keywords, create your core values statement using the themes from your brainstorming session. There are no rules: while above, Steve Jobs summed up Apple’s core values in one sentence, Zappos has ten core values: Deliver WOW Through Service Embrace and Drive Change Create Fun and A Little Weirdness Be Adventurous, Creative, and Open-Minded Pursue Growth and Learning Build Open and Honest Relationships With Communication Build a Positive Team and Family Spirit Do More With Less Be Passionate and Determined Be Humble To see how Zappos’ employees embrace these core values, watch the video they created and posted on their website. Dog food is yummy Although I find merit in every keyword listed, I’ve distilled my core values to their simplest form: Make awesomeness. Do good. How do you make awesomeness and do good? You need ambition, balance, collaboration, commitment, fun, and you need every keyword listed to support these actions. Again, there are no rules: your core values can be one sentence or a bulleted list. What matters is being true to yourself and creating core values that others can understand. Before I start any project I ask myself: is there a way to make awesomeness and to do good? If the answer is “yes,” I embrace the endeavor because it aligns with my core values. If the answer is “no,” I move on to a project that supports my core values. Unleash your powers Although every organization will craft different core values, I imagine that you want to be a superhero and that you will define “doing good” (or something similar) as one of your core values. Whether you work by yourself or with a team, you can use the web as a tool to help do good. It can be as simple as giving a free hug, or something a little more complex to help others and help your organization meet the bottom line. Some interesting initiatives that use the web to do good are: Yahoo!: How Good Grows Desigual: Happy Hunters Edge Shave Gel: Anti-irritation campaign Knowing your underlying desire to return to your Underoos-and-cape-sporting childhood and knowing that you don’t always have the opportunity to develop an entire initiative to “do good,” remember that as writers, designers, and developers, we can perform superhero acts on a daily basis by making content, design, and development accessible to the greatest number of people. By considering other people’s needs, we are intentionally performing acts of kindness—we’re doing good. There are many ways to write, design, and develop websites—many of which will be discussed in other 24ways.org articles. As we make content, design, and development decisions—as we develop campaigns and initiatives—we need to keep our core values in mind. It’s easy to make a positive difference in the world. Just be the superhero you’ve always wanted to be. Go forth and make awesomeness. If you would like to do good today, support The United Nations Children’s Fund, an organization that works for children’s rights, their survival, development and protection, by purchasing this year’s 24 ways Annual 2010 created by Five Simple Steps. All proceeds go to UNICEF. 2010 Leslie Jensen-Inman lesliejenseninman 2010-12-04T00:00:00+00:00 https://24ways.org/2010/go-forth-and-make-awesomeness/ business
227 A Contentmas Epiphany The twelve days of Christmas fall between 25 December, Christmas Day, and 6 January, the Epiphany of the Kings. Traditionally, these have been holidays and a lot of us still take a good proportion of these days off. Equally, a lot of us have a got a personal site kicking around somewhere that we sigh over and think, “One day I’ll sort you out!” Why not take this downtime to give it a big ol’ refresh? I know, good idea, huh? HEY WAIT! WOAH! NO-ONE’S TOUCHING PHOTOSHOP OR DOING ANY CSS FANCYWORK UNTIL I’M DONE WITH YOU! Be honest, did you immediately think of a sketch or mockup you have tucked away? Or some clever little piece of code you want to fiddle with? Now ask yourself, why would you start designing the container if you haven’t worked out what you need to put inside? Anyway, forget the content strategy lecture; I haven’t given you your gifts yet. I present The Twelve Days of Contentmas! This is a simple little plan to make sure that your personal site, blog or portfolio is not just looking good at the end of these twelve days, but is also a really useful repository of really useful content. WARNING KLAXON: There are twelve parts, one for each day of Christmas, so this is a lengthy article. I’m not expecting anyone to absorb this in one go. Add to Instapaper. There is no TL;DR for this because it’s a multipart process, m’kay? Even so, this plan of mine cuts corners on a proper applied strategy for content. You might find some aspects take longer than the arbitrary day I’ve assigned. And if you apply this to your company-wide intranet, I won’t be held responsible for the mess. That said, I encourage you to play along and sample some of the practical aspects of organising existing content and planning new content because it is, honestly, an inspiring and liberating process. For one thing, you get to review all the stuff you have put out for the world to look at and see what you could do next. This always leaves me full of ideas on how to plug the gaps I’ve found, so I hope you are similarly motivated come day twelve. Let’s get to it then, shall we? On the first day of Contentmas, Relly gave to me: 1. A (partial) content inventory I’m afraid being a site owner isn’t without its chores. With great power comes great responsibility and all that. There are the domain renewing, hosting helpline calls and, of course, keeping on top of all the content that you have published. If you just frowned a little and thought, “Well, there’s articles and images and… stuff”, then I’d like to introduce you to the idea of a content inventory. A content inventory is a list of all your content, in a simple spreadsheet, that allows you to see at a glance what is currently on your site: articles; about me page; contact form, and so on. You add the full URL so that you can click directly to any page listed. You add a brief description of what it is and what tags it has. In fact, I’ll show you. I’ve made a Google Docs template for you. Sorry, it isn’t wrapped. Does it seem like a mammoth task? Don’t feel you have to do this all in one day. But do do it. For one thing, looking back at all the stuff you’ve pushed out into the world gives you a warm fuzzy feeling which keeps the heating bill down. Grab a glass of mulled cider and try going month-by-month through your blog archives, or project-by-project through your portfolio. Do a little bit each day for the next twelve days and you’ll have done something awesome. The best bit is that this exploration of your current content helps you with the next day’s task. Bonus gift: for more on content auditing and inventory, check out Jeff Veen’s article on just this topic, which is also suitable for bigger business sites too. On the second day of Contentmas, Relly gave to me: 2. Website loves Remember when you were a kid, you’d write to Santa with a wish list that would make your parents squirm, because your biggest hope for your stocking would be either impossible or impossibly expensive. Do you ever get the same thing now as a grown-up where you think, “Wouldn’t it be great if I could make a video blog every week”, or “I could podcast once a month about this”, and then you push it to the back of your mind, assuming that you won’t have time or you wouldn’t know what to talk about anyway? True fact: content doesn’t just have to be produced when we are so incensed that we absolutely must blog about a topic. Neither does it have to be a drain to a demanding schedule. You can plan for it. In fact, you’re about to. So, today, get a pen and a notebook. Move away from your computer. My gift to you is to grab a quiet ten minutes between turkey sandwiches and relatives visiting and give your site some of the attention it deserves for 2011. What would you do with your site if you could? I don’t mean what would you do purely visually – although by all means note those things down too – but to your site as a whole. Here are some jumping off points: Would you like to individually illustrate and design some of your articles? What about a monthly exploration of your favourite topic through video or audio? Who would you like to collaborate with? What do you want your site to be like for a user? What tone of voice would you like to use? How could you use imagery and typography to support your content? What would you like to create content about in the new year? It’s okay if you can’t do these things yet. It’s okay to scrub out anything where you think, “Nah, never gonna happen.” But do give some thought to what you might want to do next. The best inspiration for this comes from what you’ve already done, so keep on with that inventory. Bonus gift: a Think Vitamin article on podcasting using Skype, so you can rope in a few friends to join in, too. On the third day of Contentmas, Relly gave to me: 3. Red pens Shock news, just in: the web is not print! One of the hardest things as a writer is to reach the point where you say, “Yeah, okay, that’s it. I’m done” and send off your beloved manuscript or article to print. I’m convinced that if deadlines didn’t exist, nothing would get finished. Why? Well, at the point you hand it over to the publishing presses, you can make no more changes. At best, you can print an erratum or produce an updated second edition at a later date. And writers love to – no, they live to – tweak their creations, so handing them over is quite a struggle. Just one more comma and… Online, we have no such constraints. We can edit, correct, test, tweak, twiddle until we’re blooming sick of it. Our red pens never run out of ink. It is time for you to run a more critical eye over your content, especially the stuff already published. Relish in the opportunity to change stuff on the fly. I am not so concerned by blog articles and such (although feel free to apply this concept to those, too), but mainly by your more concrete content: about pages; contact pages; home page navigation; portfolio pages; 404 pages. Now, don’t go running amok with the cut function yet. First, put all these evergreen pages into your inventory. In the notes section, write a quick analysis of how useful this copy is. Example questions: Is your contact page up-to-date? Does your about page link to the right places? Is your portfolio current? Does your 404 page give people a way to find what they were looking for? We’ll come back to this in a few days once we have a clearer idea of how to improve our content. Bonus gift: the audio and slides of a talk I gave on microcopy and 404 pages at @media WebDirections last year. On the fourth day of Contentmas, Relly gave to me: 4. Stalling nerds Actually, I guess more accurately this is something I get given a lot. Designers and developers particularly can find a million ways to extract themselves from the content of a site but, as the site owner, and this being your personal playground and all, you mustn’t. You actually can’t, sorry. But I do understand that at this point, ‘sorting out your site’ suddenly seems a lot less exciting, especially if you are a visually-minded person and words and lists aren’t really your thing. So far, there has been a lot of not-very-exciting exercises in planning, and there’s probably a nice pile of DVDs and video games that you got from Santa worth investigating. Stay strong my friend. By now, you have probably hit upon an idea of some sort you are itching to start on, so for every half-hour you spend doing inventory, gift yourself another thirty minutes to play with that idea. Bonus gift: the Pomodoro Technique. Take one kitchen timer and a to-do list and see how far you can go. On the fifth day of Contentmas, Relly gave to me: 5. Golden rules Here are some guidelines for writing online: Make headlines for tutorials and similar content useful and descriptive; use a subheading for any terrible pun you want to work in. Create a broad opening paragraph that addresses what your article is about. Part of the creative skill in writing is to do this in a way that both informs the reader and captures their attention. If you struggle with this, consider a boxout giving a summary of the article. Use headings to break up chunks of text and allow people to scan. Most people will have a scoot about an article before starting at the beginning to give it a proper read. These headings should be equal parts informative and enticing. Try them out as questions that might be posed by the reader too. Finish articles by asking your reader to take an affirmative action: subscribe to your RSS feed; leave a comment (if comments are your thing – more on that later); follow you on Twitter; link you to somewhere they have used your tutorial or code. The web is about getting excited, making things and sharing with others, so give your readers the chance to do that. For portfolio sites, this call to action is extra important as you want to pick up new business. Encourage people to e-mail you or call you – don’t just rely on a number in the footer or an e-mail link at the top. Think up some consistent calls-to-action you can use and test them out. So, my gift to you today is a simplified page table for planning out your content to make it as useful as possible. Feel free to write a new article or tutorial, or work on that great idea from yesterday and try out these guidelines for yourself. It’s a simple framework – good headline; broad opening; headings to break up volume; strong call to action – but it will help you recognise if what you’ve written is in good shape to face the world. It doesn’t tell you anything about how to create it – that’s your endeavour – but it does give you a start. No more staring at a blank page. Bonus gift: okay, you have to buy yourself this one, but it is the gift that keeps on giving: Ginny Reddish’s Letting Go of the Words – the hands down best guide to web writing there is, with a ton of illustrative examples. On the sixth day of Contentmas, Relly gave to me: 6. Foundation-a-laying Yesterday, we played with a page table for articles. Today, we are going to set the foundations for your new, spangly, spruced up, relaunched site (for when you’re ready, of course). We’ve checked out what we’ve got, we’ve thought about what we’d like, we have a wish list for the future. Now is the time for a small reality check. Be realistic with yourself. Can you really give your site some attention every day? Record a short snippet of audio once a week? A photo diary post once a month? Look back at the wish list you made. What can you do? What can you aim for? What just isn’t possible right now? As much as we’d all love to be producing a slick video podcast and screencast three times a week, it’s better to set realistic expectations and work your way up. Where does your site sit in your online world? Do you want it to be the hub of all your social interactions, a lifestream, a considered place of publication or a free for all? Do you want to have comments (do you have the personal resource to monitor comments?) or would you prefer conversation to happen via Twitter, Facebook or not at all? Does this apply to all pages, posts and content types or just some? Get these things straight in your head and it’s easier to know what sort of environment you want to create and what content you’ll need to sustain it. Get your notebook again and think about specific topics you’d like to cover, or aspects of a project you want to go into more, and how you can go ahead and do just that. A good motivator is to think what you’ll get out of doing it, even if that is “And I’ll finally show the poxy $whatever_community that my $chosen_format is better than their $other_format.” What topics have you really wanted to get off your chest? Look through your inventory again. What gaps are there in your content just begging to be filled? Today, you’re going to give everyone the gift of your opinion. Find one of those things where someone on the internet is wrong and create a short but snappy piece to set them straight. Doesn’t that feel good? Soon you’ll be able to do this in a timely manner every time someone is wrong on the internet! Bonus gift: we’re halfway through, so I think something fun is in order. How about a man sledding naked down a hill in Brighton on a tea tray? Sometimes, even with a whole ton of content planning, it’s the spontaneous stuff that is still the most fun to share. On the seventh day of Contentmas, Relly gave to me: 7. Styles-a-guiding Not colour style guides or brand style guides or code style guides. Content style guides. You could go completely to town and write yourself a full document defining every aspect of your site’s voice and personality, plus declaring your view on contracted phrases and the Oxford comma, but this does seem a tad excessive. Unless you’re writing an entire site as a fictional character, you probably know your own voice and vocabulary better than anyone. It’s in your head, after all. Instead, equip yourself with a good global style guide (I like the Chicago Manual of Style because I can access it fully online, but the Associated Press (AP) Stylebook has a nifty iPhone app and, if I’m entirely honest, I’ve found a copy of Eats, Shoots and Leaves has set me right on all but the most technical aspects of punctuation). Next, pick a good dictionary and bookmark thesaurus.com. Then have a go at Kristina Halvorson’s ‘Voice and Tone’ exercise from her book Content Strategy for the Web, to nail down what you’d like your future content to be like: To introduce the voice and tone qualities you’re [looking to create], a good approach is to offer contrasting values. For example: Professional, not academic. Confident, not arrogant. Clever, not cutesy. Savvy, not hipster. Expert, not preachy. Take a look around some of your favourite sites and examine the writing and stylistic handling of content. What do you like? What do you want to emulate? What matches your values list? Today’s gift to you is an idea. Create a ‘swipe file’ through Evernote or Delicious and save all the stuff you come across that, regardless of topic, makes you think, “That’s really cool.” This isn’t the same as an Instapaper list you’d like to read. This is stuff you have read or have seen that is worth looking at in closer detail. Why is it so good? What is the language and style like? What impact does the typography have? How does the imagery work to enhance the message? This isn’t about creating a personal brand or any such piffle. It’s about learning to recognise how good content works and how to create something awesome yourself. Obviously, your ideas are brilliant, so take the time to understand how best to spring them on the unsuspecting public for easier world domination. Bonus gift: a nifty style guide is a must when you do have to share content creation duties with others. Here is Leeds University’s publicly available PDF version for you to take a gander at. I especially like the Rationale sections for chopping off dissenters at the knees. On the eighth day of Contentmas, Relly gave to me: 8. Times-a-making You have an actual, real plan for what you’d like to do with your site and how it is going to sound (and probably some ideas on how it’s going to look, too). I hope you are full of enthusiasm and Getting Excited To Make Things. Just before we get going and do exactly that, we are going to make sure we have made time for this creative outpouring. Have you tried to blog once a week before and found yourself losing traction after a month or two? Are there a couple of podcasts lurking neglected in your archives? Whereas half of the act of running is showing up for training, half of creating is making time rather than waiting for it to become urgent. It’s okay to write something and set a date to come back to it (which isn’t the same as leaving it to decompose in your drafts folder). Putting a date in your calendar to do something for your site means that you have a forewarning to think of a topic to write about, and space in your schedule to actually do it. Crucially, you’ve actually made some time for this content lark. To do this, you need to think about how long it takes to get something out of the door/shipped/published/whatever you want to call it. It might take you just thirty minutes to record a podcast, but also a further hour to research the topic beforehand and another hour to edit and upload the clips. Suddenly, doing a thirty minute podcast every day seems a bit unlikely. But, on the flipside, it is easy to see how you could schedule that in three chunks weekly. Put it in your calendar. Do it, publish it, book yourself in for the next week. Keep turning up. Today my gift to you is the gift of time. Set up your own small content calendar, using your favourite calendar system, and schedule time to play with new ways of creating content, time to get it finished and time to get it on your site. Don’t let good stuff go to your drafts folder to die of neglect. Bonus gift: lots of writers swear by the concept of ‘daily pages’. That is, churning out whatever is in your head to see if there is anything worth building upon, or just to lose the grocery list getting in the way. 750words.com is a site built around this concept. Go have a play. On the ninth day of Contentmas, Relly gave to me: 9. Copy enhancing An incredibly radical idea for day number nine. We are going to look at that list of permanent pages you made back on day three and rewrite the words first, before even looking at a colour palette or picking a font! Crazy as it sounds, doing it this way round could influence your design. It could shape the imagery you use. It could affect your choice of typography. IMAGINE THE POSSIBILITIES! Look at the page table from day five. Print out one for each of your homepage, about page, contact page, portfolio, archive, 404 page or whatever else you have. Use these as a place to brainstorm your ideas and what you’d like each page to do for your site. Doodle in the margin, choose words you think sound fun to say, daydream about pictures you’d like to use and colours you think would work, but absolutely, completely and utterly fill in those page tables to understand how much (or how little) content you’re playing with and what you need to do to get to ‘launch’. Then, use them for guidance as you start to write. Don’t skimp. Don’t think that a fancy icon of an envelope encourages people to e-mail you. Use your words. People get antsy at this bit. Writing can be hard work and it’s easy for me to say, “Go on and write it then!” I know this. I mean, you should see the faces I pull when I have to do anything related to coding. The closest equivalent would be when scientists have to stick their hands in big gloves attached to a glass box to do dangerous experiments. Here’s today’s gift, a little something about writing that I hope brings you comfort: To write something fantastic you almost always have to write a rubbish draft first. Now, you might get lucky and write a ‘good enough’ draft first time and that’s fab – you’ve cut some time getting to ‘fantastic’. If, however, you’ve always looked at your first attempt to write more than the bare minimum and sighed in despair, and resigned yourself to adding just a title, date and a screenshot, be cheered because you have taken the first step to being able to communicate with clarity, wit and panache. Keep going. Look at writing you admire and emulate it. Think about how you will lovingly design those words when they are done. Know that you can go back and change them. Check back with your page table to keep you on track. Do that first draft. Bonus gift: becoming a better writer helps you to explain design concepts to clients. On the tenth day of Contentmas, Relly gave to me: 10. Ideas for keeping Hurrah! You have something down on paper, ready to start evolving your site around it. Here’s where the words and visuals and interaction start to come together. Because you have a plan, you can think ahead and do things you wouldn’t be able to pull together otherwise. How about finding a fresh-faced stellar illustrator on Dribbble to create you something perfect to pep up your contact page or visualize your witty statement on statements of work. A List Apart has been doing it for years and it hasn’t worked out too badly for them, has it? What about spending this month creating a series of introductory tutorials on a topic, complete with screencasts and audio and give them a special home on your site? How about putting in some hours creating a glorious about me page, with a biography, nice picture, and where you spend your time online? You could even do the web equivalent of getting up in the attic and sorting out your site’s search to make it easier to find things in your archives. Maybe even do some manual recommendations for relevant content and add them as calls to action. How about writing a few awesome case studies with individual screenshots of your favourite work, and creating a portfolio that plays to your strengths? Don’t just rely on the pretty pictures; use your words. Otherwise no-one understands why things are the way they are on that screenshot and BAM! you’ll be judged on someone else’s tastes. (Elliot has a head start on you for this, so get to it!) Do you have a serious archive of content? What’s it like being a first-time visitor to your site? Could you write them a guide to introduce yourself and some of the most popular stuff on your site? Ali Edwards is a massively popular crafter and every day she gets new visitors who have found her multiple papercraft projects on Flickr, Vimeo and elsewhere, so she created a welcome guide just for them. What about your microcopy? Can you improve on your blogging platform’s defaults for search, comment submission and labels? I’ll bet you can. Maybe you could plan a collaboration with other like-minded souls. A week of posts about the more advanced wonders of HTML5 video. A month-long baton-passing exercise in extolling the virtues of IE (shut up, it could happen!). Just spare me any more online advent calendars. Watch David McCandless’s TED talk on his jawdropping infographic work and make something as awesome as the Billion Dollar O Gram. I dare you. Bonus gift: Grab a copy of Brian Suda’s Designing with Data, in print or PDF if Santa didn’t put one in your stocking, and make that awesome something with some expert guidance. On the eleventh day of Contentmas, Relly gave to me: 11. Pixels pushing Oh, go on then. Make a gorgeous bespoke velvet-lined container for all that lovely content. It’s proper informed design now, not just decoration. Mr. Zeldman says so. Bonus gift: I made you a movie! If books were designed like websites. On the twelfth day of Contentmas, Relly gave to me: 12. Delighters delighting The Epiphany is upon us; your site is now well on its way to being a beautiful, sustainable hub of content and you have a date in your calendar to help you keep that resolution of blogging more. What now? Keep on top of your inventory. One day it will save your butt, I promise. Keep making a little bit of time regularly to create something new: an article; an opinion piece; a small curation of related links; a photo diary; a new case study. That’s easier than an annual content bootcamp for sure. And today’s gift: look for ways to play with that content and make something a bit special. Stretch yourself a little. It’ll be worth it. Bonus gift: Paul Annett’s presentation on Ooh, that’s clever: Delighters in design from SxSW 09. All my favourite designers and developers have their own unique styles and touches. It’s what sets them apart. My very, very favourites have an eloquence and expression that they bring to their sites and to their projects. I absolutely love to explore a well-crafted, well-written site – don’t we all? I know the time it takes. I appreciate the time it takes. But the end results are delicious. Do please share your spangly, refreshed sites with me in the comments. Catch me on Twitter, I’m @RellyAB, and I’ve been your host for these Twelve Days of Contentmas. 2010 Relly Annett-Baker rellyannettbaker 2010-12-21T00:00:00+00:00 https://24ways.org/2010/a-contentmas-epiphany/ content
233 Wrapping Things Nicely with HTML5 Local Storage HTML5 is here to turn the web from a web of hacks into a web of applications – and we are well on the way to this goal. The coming year will be totally and utterly awesome if you are excited about web technologies. This year the HTML5 revolution started and there is no stopping it. For the first time all the browser vendors are rallying together to make a technology work. The new browser war is fought over implementation of the HTML5 standard and not over random additions. We live in exciting times. Starting with a bang As with every revolution there is a lot of noise with bangs and explosions, and that’s the stage we’re at right now. HTML5 showcases are often CSS3 showcases, web font playgrounds, or video and canvas examples. This is great, as it gets people excited and it gives the media something to show. There is much more to HTML5, though. Let’s take a look at one of the less sexy, but amazingly useful features of HTML5 (it was in the HTML5 specs, but grew at such an alarming rate that it warranted its own spec): storing information on the client-side. Why store data on the client-side? Storing information in people’s browsers affords us a few options that every application should have: You can retain the state of an application – when the user comes back after closing the browser, everything will be as she left it. That’s how ‘real’ applications work and this is how the web ones should, too. You can cache data – if something doesn’t change then there is no point in loading it over the Internet if local access is so much faster You can store user preferences – without needing to keep that data on your server at all. In the past, storing local data wasn’t much fun. The pain of hacky browser solutions In the past, all we had were cookies. I don’t mean the yummy things you get with your coffee, endorsed by the blue, furry junkie in Sesame Street, but the other, digital ones. Cookies suck – it isn’t fun to have an unencrypted HTTP overhead on every server request for storing four kilobytes of data in a cryptic format. It was OK for 1994, but really neither an easy nor a beautiful solution for the task of storing data on the client. Then came a plethora of solutions by different vendors – from Microsoft’s userdata to Flash’s LSO, and from Silverlight isolated storage to Google’s Gears. If you want to know just how many crazy and convoluted ways there are to store a bit of information, check out Samy’s evercookie. Clearly, we needed an easier and standardised way of storing local data. Keeping it simple – local storage And, lo and behold, we have one. The local storage API (or session storage, with the only difference being that session data is lost when the window is closed) is ridiculously easy to use. All you do is call a few methods on the window.localStorage object – or even just set the properties directly using the square bracket notation: if('localStorage' in window && window['localStorage'] !== null){ var store = window.localStorage; // valid, API way store.setItem(‘cow’,‘moo’); console.log( store.getItem(‘cow’) ); // => ‘moo’ // shorthand, breaks at keys with spaces store.sheep = ‘baa’ console.log( store.sheep ); // ‘baa’ // shorthand for all store[‘dog’] = ‘bark’ console.log( store[‘dog’] ); // => ‘bark’ } Browser support is actually pretty good: Chrome 4+; Firefox 3.5+; IE8+; Opera 10.5+; Safari 4+; plus iPhone 2.0+; and Android 2.0+. That should cover most of your needs. Of course, you should check for support first (or use a wrapper library like YUI Storage Utility or YUI Storage Lite). The data is stored on a per domain basis and you can store up to five megabytes of data in localStorage for each domain. Strings attached By default, localStorage only supports strings as storage formats. You can’t store results of JavaScript computations that are arrays or objects, and every number is stored as a string. This means that long, floating point numbers eat into the available memory much more quickly than if they were stored as numbers. var cowdesc = "the cow is of the bovine ilk, "+ "one end is for the moo, the "+ "other for the milk"; var cowdef = { ilk“bovine”, legs, udders, purposes front“moo”, end“milk” } }; window.localStorage.setItem(‘describecow’,cowdesc); console.log( window.localStorage.getItem(‘describecow’) ); // => the cow is of the bovine… window.localStorage.setItem(‘definecow’,cowdef); console.log( window.localStorage.getItem(‘definecow’) ); // => [object Object] = bad! This limits what you can store quite heavily, which is why it makes sense to use JSON to encode and decode the data you store: var cowdef = { "ilk":"bovine", "legs":4, "udders":4, "purposes":{ "front":"moo", "end":"milk" } }; window.localStorage.setItem(‘describecow’,JSON.stringify(cowdef)); console.log( JSON.parse( window.localStorage.getItem(‘describecow’) ) ); // => Object { ilk=“bovine”, more…} You can also come up with your own formatting solutions like CSV, or pipe | or tilde ~ separated formats, but JSON is very terse and has native browser support. Some use case examples The simplest use of localStorage is, of course, storing some data: the current state of a game; how far through a multi-form sign-up process a user is; and other things we traditionally stored in cookies. Using JSON, though, we can do cooler things. Speeding up web service use and avoiding exceeding the quota A lot of web services only allow you a certain amount of hits per hour or day, and can be very slow. By using localStorage with a time stamp, you can cache results of web services locally and only access them after a certain time to refresh the data. I used this technique in my An Event Apart 10K entry, World Info, to only load the massive dataset of all the world information once, and allow for much faster subsequent visits to the site. The following screencast shows the difference: For use with YQL (remember last year’s 24 ways entry?), I’ve built a small script called YQL localcache that wraps localStorage around the YQL data call. An example would be the following: yqlcache.get({ yql: 'select * from flickr.photos.search where text="santa"', id: 'myphotos', cacheage: ( 60*60*1000 ), callback: function(data) { console.log(data); } }); This loads photos of Santa from Flickr and stores them for an hour in the key myphotos of localStorage. If you call the function at various times, you receive an object back with the YQL results in a data property and a type property which defines where the data came from – live is live data, cached means it comes from cache, and freshcache indicates that it was called for the first time and a new cache was primed. The cache will work for an hour (60×60×1,000 milliseconds) and then be refreshed. So, instead of hitting the YQL endpoint over and over again, you hit it once per hour. Caching a full interface Another use case I found was to retain the state of a whole interface of an application by caching the innerHTML once it has been rendered. I use this in the Yahoo Firehose search interface, and you can get the full story about local storage and how it is used in this screencast: The stripped down code is incredibly simple (JavaScript with PHP embed): // test for localStorage support if(('localStorage' in window) && window['localStorage'] !== null){ var f = document.getElementById(‘mainform’); // test with PHP if the form was sent (the submit button has the name “sent”) // get the HTML of the form and cache it in the property “state” localStorage.setItem(‘state’,f.innerHTML); // if the form hasn’t been sent… // check if a state property exists and write back the HTML cache if(‘state’ in localStorage){ f.innerHTML = localStorage.getItem(‘state’); } } Other ideas In essence, you can use local storage every time you need to speed up access. For example, you could store image sprites in base-64 encoded datasets instead of loading them from a server. Or you could store CSS and JavaScript libraries on the client. Anything goes – have a play. Issues with local and session storage Of course, not all is rainbows and unicorns with the localStorage API. There are a few niggles that need ironing out. As with anything, this needs people to use the technology and raise issues. Here are some of the problems: Inadequate information about storage quota – if you try to add more content to an already full store, you get a QUOTA_EXCEEDED_ERR and that’s it. There’s a great explanation and test suite for localStorage quota available. Lack of automatically expiring storage – a feature that cookies came with. Pamela Fox has a solution (also available as a demo and source code) Lack of encrypted storage – right now, everything is stored in readable strings in the browser. Bigger, better, faster, more! As cool as the local and session storage APIs are, they are not quite ready for extensive adoption – the storage limits might get in your way, and if you really want to go to town with accessing, filtering and sorting data, real databases are what you’ll need. And, as we live in a world of client-side development, people are moving from heavy server-side databases like MySQL to NoSQL environments. On the web, there is also a lot of work going on, with Ian Hickson of Google proposing the Web SQL database, and Nikunj Mehta, Jonas Sicking (Mozilla), Eliot Graff (Microsoft) and Andrei Popescu (Google) taking the idea beyond simply replicating MySQL and instead offering Indexed DB as an even faster alternative. On the mobile front, a really important feature is to be able to store data to use when you are offline (mobile coverage and roaming data plans anybody?) and you can use the Offline Webapps API for that. As I mentioned at the beginning, we have a very exciting time ahead – let’s make this web work faster and more reliably by using what browsers offer us. For more on local storage, check out the chapter on Dive into HTML5. 2010 Christian Heilmann chrisheilmann 2010-12-06T00:00:00+00:00 https://24ways.org/2010/html5-local-storage/ code
234 An Introduction to CSS 3-D Transforms Ladies and gentlemen, it is the second decade of the third millennium and we are still kicking around the same 2-D interface we got three decades ago. Sure, Apple debuted a few apps for OSX 10.7 that have a couple more 3-D flourishes, and Microsoft has had that Flip 3D for a while. But c’mon – 2011 is right around the corner. That’s Twenty Eleven, folks. Where is our 3-D virtual reality? By now, we should be zipping around the Metaverse on super-sonic motorbikes. Granted, the capability of rendering complex 3-D environments has been present for years. On the web, there are already several solutions: Flash; three.js in <canvas>; and, eventually, WebGL. Finally, we meagre front-end developers have our own three-dimensional jewel: CSS 3-D transforms! Rationale Like a beautiful jewel, 3-D transforms can be dazzling, a true spectacle to behold. But before we start tacking 3-D diamonds and rubies to our compositions like Liberace‘s tailor, we owe it to our users to ask how they can benefit from this awesome feature. An entire application should not take advantage of 3-D transforms. CSS was built to style documents, not generate explorable environments. I fail to find a benefit to completing a web form that can be accessed by swivelling my viewport to the Sign-Up Room (although there have been proposals to make the web just that). Nevertheless, there are plenty of opportunities to use 3-D transforms in between interactions with the interface, via transitions. Take, for instance, the Weather App on the iPhone. The application uses two views: a details view; and an options view. Switching between these two views is done with a 3-D flip transition. This informs the user that the interface has two – and only two – views, as they can exist only on either side of the same plane. Flipping from details view to options view via a 3-D transition Also, consider slide shows. When you’re looking at the last slide, what cues tip you off that advancing will restart the cycle at the first slide? A better paradigm might be achieved with a 3-D transform, placing the slides side-by-side in a circle (carousel) in three-dimensional space; in that arrangement, the last slide obviously comes before the first. 3-D transforms are more than just eye candy. We can also use them to solve dilemmas and make our applications more intuitive. Current support The CSS 3D Transforms module has been out in the wild for over a year now. Currently, only Safari supports the specification – which includes Safari on Mac OS X and Mobile Safari on iOS. The support roadmap for other browsers varies. The Mozilla team has taken some initial steps towards implementing the module. Mike Taylor tells me that the Opera team is keeping a close eye on CSS transforms, and is waiting until the specification is fleshed out. And our best friend Internet Explorer still needs to catch up to 2-D transforms before we can talk about the 3-D variety. To make matters more perplexing, Safari’s WebKit cousin Chrome currently accepts 3-D transform declarations, but renders them in 2-D space. Chrome team member Paul Irish, says that 3-D transforms are on the horizon, perhaps in one of the next 8.0 releases. This all adds up to a bit of a challenge for those of us excited by 3-D transforms. I’ll give it to you straight: missing the dimension of depth can make degradation a bit ungraceful. Unless the transform is relatively simple and holds up in non-3D-supporting browsers, you’ll most likely have to design another solution. But what’s another hurdle in a steeplechase? We web folk have had our mettle tested for years. We’re prepared to devise multiple solutions. Here’s the part of the article where I mention Modernizr, and you brush over it because you’ve read this part of an article hundreds of times before. But seriously, it’s the best way to test for CSS 3-D transform support. Use it. Even with these difficulties mounting up, trying out 3-D transforms today is the right move. The CSS 3-D transforms module was developed by the same team at Apple that produced the CSS 2D Transforms and Animation modules. Both specifications have since been adopted by Mozilla and Opera. Transforming in three-dimensions now will guarantee you’ll be ahead of the game when the other browsers catch up. The choice is yours. You can make excuses and pooh-pooh 3-D transforms because they’re too hard and only snobby Apple fans will see them today. Or, with a tip of the fedora to Mr Andy Clarke, you can get hard-boiled and start designing with the best features out there right this instant. So, I bid you, in the words of the eternal Optimus Prime… Transform and roll out. Let’s get coding. Perspective To activate 3-D space, an element needs perspective. This can be applied in two ways: using the transform property, with the perspective as a functional notation: -webkit-transform: perspective(600); or using the perspective property: -webkit-perspective: 600; See example: Perspective 1. The red element on the left uses transform: perspective() functional notation; the blue element on the right uses the perspective property These two formats both trigger a 3-D space, but there is a difference. The first, functional notation is convenient for directly applying a 3-D transform on a single element (in the previous example, I use it in conjunction with a rotateY transform). But when used on multiple elements, the transformed elements don’t line up as expected. If you use the same transform across elements with different positions, each element will have its own vanishing point. To remedy this, use the perspective property on a parent element, so each child shares the same 3-D space. See Example: Perspective 2. Each red box on the left has its own vanishing point within the parent container; the blue boxes on the right share the vanishing point of the parent container The value of perspective determines the intensity of the 3-D effect. Think of it as a distance from the viewer to the object. The greater the value, the further the distance, so the less intense the visual effect. perspective: 2000; yields a subtle 3-D effect, as if we were viewing an object from far away. perspective: 100; produces a tremendous 3-D effect, like a tiny insect viewing a massive object. By default, the vanishing point for a 3-D space is positioned at its centre. You can change the position of the vanishing point with perspective-origin property. -webkit-perspective-origin: 25% 75%; See Example: Perspective 3. 3-D transform functions As a web designer, you’re probably well acquainted with working in two dimensions, X and Y, positioning items horizontally and vertically. With a 3-D space initialised with perspective, we can now transform elements in all three glorious spatial dimensions, including the third Z dimension, depth. 3-D transforms use the same transform property used for 2-D transforms. If you’re familiar with 2-D transforms, you’ll find the basic 3D transform functions fairly similar. rotateX(angle) rotateY(angle) rotateZ(angle) translateZ(tz) scaleZ(sz) Whereas translateX() positions an element along the horizontal X-axis, translateZ() positions it along the Z-axis, which runs front to back in 3-D space. Positive values position the element closer to the viewer, negative values further away. The rotate functions rotate the element around the corresponding axis. This is somewhat counter-intuitive at first, as you might imagine that rotateX will spin an object left to right. Instead, using rotateX(45deg) rotates an element around the horizontal X-axis, so the top of the element angles back and away, and the bottom gets closer to the viewer. See Example: Transforms 1. 3-D rotate() and translate() functions around each axis There are also several shorthand transform functions that require values for all three dimensions: translate3d(tx,ty,tz) scale3d(sx,sy,sz) rotate3d(rx,ry,rz,angle) Pro-tip: These foo3d() transform functions also have the benefit of triggering hardware acceleration in Safari. Dean Jackson, CSS 3-D transform spec author and main WebKit dude, writes (to Thomas Fuchs): In essence, any transform that has a 3D operation as one of its functions will trigger hardware compositing, even when the actual transform is 2D, or not doing anything at all (such as translate3d(0,0,0)). Note this is just current behaviour, and could change in the future (which is why we don’t document or encourage it). But it is very helpful in some situations and can significantly improve redraw performance. For the sake of simplicity, my demos will use the basic transform functions, but if you’re writing production-ready CSS for iOS or Safari-only, make sure to use the foo3d() functions to get the best rendering performance. Card flip We now have all the tools to start making 3-D objects. Let’s get started with something simple: flipping a card. Here’s the basic markup we’ll need: <section class="container"> <div id="card"> <figure class="front">1</figure> <figure class="back">2</figure> </div> </section> The .container will house the 3-D space. The #card acts as a wrapper for the 3-D object. Each face of the card has a separate element: .front; and .back. Even for such a simple object, I recommend using this same pattern for any 3-D transform. Keeping the 3-D space element and the object element(s) separate establishes a pattern that is simple to understand and easier to style. We’re ready for some 3-D stylin’. First, apply the necessary perspective to the parent 3-D space, along with any size or positioning styles. .container { width: 200px; height: 260px; position: relative; -webkit-perspective: 800; } Now the #card element can be transformed in its parent’s 3-D space. We’re combining absolute and relative positioning so the 3-D object is removed from the flow of the document. We’ll also add width: 100%; and height: 100%;. This ensures the object’s transform-origin will occur in the centre of .container. More on transform-origin later. Let’s add a CSS3 transition so users can see the transform take effect. #card { width: 100%; height: 100%; position: absolute; -webkit-transform-style: preserve-3d; -webkit-transition: -webkit-transform 1s; } The .container’s perspective only applies to direct descendant children, in this case #card. In order for subsequent children to inherit a parent’s perspective, and live in the same 3-D space, the parent can pass along its perspective with transform-style: preserve-3d. Without 3-D transform-style, the faces of the card would be flattened with its parents and the back face’s rotation would be nullified. To position the faces in 3-D space, we’ll need to reset their positions in 2-D with position: absolute. In order to hide the reverse sides of the faces when they are faced away from the viewer, we use backface-visibility: hidden. #card figure { display: block; position: absolute; width: 100%; height: 100%; -webkit-backface-visibility: hidden; } To flip the .back face, we add a basic 3-D transform of rotateY(180deg). #card .front { background: red; } #card .back { background: blue; -webkit-transform: rotateY(180deg); } With the faces in place, the #card requires a corresponding style for when it is flipped. #card.flipped { -webkit-transform: rotateY(180deg); } Now we have a working 3-D object. To flip the card, we can toggle the flipped class. When .flipped, the #card will rotate 180 degrees, thus exposing the .back face. See Example: Card 1. Flipping a card in three dimensions Slide-flip Take another look at the Weather App 3-D transition. You’ll notice that it’s not quite the same effect as our previous demo. If you follow the right edge of the card, you’ll find that its corners stay within the container. Instead of pivoting from the horizontal centre, it pivots on that right edge. But the transition is not just a rotation – the edge moves horizontally from right to left. We can reproduce this transition just by modifying a couple of lines of CSS from our original card flip demo. The pivot point for the rotation occurs at the right side of the card. By default, the transform-origin of an element is at its horizontal and vertical centre (50% 50% or center center). Let’s change it to the right side: #card { -webkit-transform-origin: right center; } That flip now needs some horizontal movement with translateX. We’ll set the rotation to -180deg so it flips right side out. #card.flipped { -webkit-transform: translateX(-100%) rotateY(-180deg); } See Example: Card 2. Creating a slide-flip from the right edge of the card Cube Creating 3-D card objects is a good way to get started with 3-D transforms. But once you’ve mastered them, you’ll be hungry to push it further and create some true 3-D objects: prisms. We’ll start out by making a cube. The markup for the cube is similar to the card. This time, however, we need six child elements for all six faces of the cube: <section class="container"> <div id="cube"> <figure class="front">1</figure> <figure class="back">2</figure> <figure class="right">3</figure> <figure class="left">4</figure> <figure class="top">5</figure> <figure class="bottom">6</figure> </div> </section> Basic position and size styles set the six faces on top of one another in the container. .container { width: 200px; height: 200px; position: relative; -webkit-perspective: 1000; } #cube { width: 100%; height: 100%; position: absolute; -webkit-transform-style: preserve-3d; } #cube figure { width: 196px; height: 196px; display: block; position: absolute; border: 2px solid black; } With the card, we only had to rotate its back face. The cube, however, requires that five of the six faces to be rotated. Faces 1 and 2 will be the front and back. Faces 3 and 4 will be the sides. Faces 5 and 6 will be the top and bottom. #cube .front { -webkit-transform: rotateY(0deg); } #cube .back { -webkit-transform: rotateX(180deg); } #cube .right { -webkit-transform: rotateY(90deg); } #cube .left { -webkit-transform: rotateY(-90deg); } #cube .top { -webkit-transform: rotateX(90deg); } #cube .bottom { -webkit-transform: rotateX(-90deg); } We could remove the first #cube .front style declaration, as this transform has no effect, but let’s leave it in to keep our code consistent. Now each face is rotated, and only the front face is visible. The four side faces are all perpendicular to the viewer, so they appear invisible. To push them out to their appropriate sides, they need to be translated out from the centre of their positions. Each side of the cube is 200 pixels wide. From the cube’s centre they’ll need to be translated out half that distance, 100px. #cube .front { -webkit-transform: rotateY(0deg) translateZ(100px); } #cube .back { -webkit-transform: rotateX(180deg) translateZ(100px); } #cube .right { -webkit-transform: rotateY(90deg) translateZ(100px); } #cube .left { -webkit-transform: rotateY(-90deg) translateZ(100px); } #cube .top { -webkit-transform: rotateX(90deg) translateZ(100px); } #cube .bottom { -webkit-transform: rotateX(-90deg) translateZ(100px); } Note here that the translateZ function comes after the rotate. The order of transform functions is important. Take a moment and soak this up. Each face is first rotated towards its position, then translated outward in a separate vector. We have a working cube, but we’re not done yet. Returning to the Z-axis origin For the sake of our users, our 3-D transforms should not distort the interface when the active panel is at its resting position. But once we start pushing elements off their Z-axis origin, distortion is inevitable. In order to keep 3-D transforms snappy, Safari composites the element, then applies the transform. Consequently, anti-aliasing on text will remain whatever it was before the transform was applied. When transformed forward in 3-D space, significant pixelation can occur. See Example: Transforms 2. Looking back at the Perspective 3 demo, note that no matter how small the perspective value is, or wherever the transform-origin may be, the panel number 1 always returns to its original position, as if all those funky 3-D transforms didn’t even matter. To resolve the distortion and restore pixel perfection to our #cube, we can push the 3-D object back, so that the front face will be positioned back to the Z-axis origin. #cube { -webkit-transform: translateZ(-100px); } See Example: Cube 1. Restoring the front face to the original position on the Z-axis Rotating the cube To expose any face of the cube, we’ll need a style that rotates the cube to expose any face. The transform values are the opposite of those for the corresponding face. We toggle the necessary class on the #box to apply the appropriate transform. #cube.show-front { -webkit-transform: translateZ(-100px) rotateY(0deg); } #cube.show-back { -webkit-transform: translateZ(-100px) rotateX(-180deg); } #cube.show-right { -webkit-transform: translateZ(-100px) rotateY(-90deg); } #cube.show-left { -webkit-transform: translateZ(-100px) rotateY(90deg); } #cube.show-top { -webkit-transform: translateZ(-100px) rotateX(-90deg); } #cube.show-bottom { -webkit-transform: translateZ(-100px) rotateX(90deg); } Notice how the order of the transform functions has reversed. First, we push the object back with translateZ, then we rotate it. Finishing up, we can add a transition to animate the rotation between states. #cube { -webkit-transition: -webkit-transform 1s; } See Example: Cube 2. Rotating the cube with a CSS transition Rectangular prism Cubes are easy enough to generate, as we only have to worry about one measurement. But how would we handle a non-regular rectangular prism? Let’s try to make one that’s 300 pixels wide, 200 pixels high, and 100 pixels deep. The markup remains the same as the #cube, but we’ll switch the cube id for #box. The container styles remain mostly the same: .container { width: 300px; height: 200px; position: relative; -webkit-perspective: 1000; } #box { width: 100%; height: 100%; position: absolute; -webkit-transform-style: preserve-3d; } Now to position the faces. Each set of faces will need their own sizes. The smaller faces (left, right, top and bottom) need to be positioned in the centre of the container, where they can be easily rotated and then shifted outward. The thinner left and right faces get positioned left: 100px ((300 − 100) ÷ 2), The stouter top and bottom faces get positioned top: 50px ((200 − 100) ÷ 2). #box figure { display: block; position: absolute; border: 2px solid black; } #box .front, #box .back { width: 296px; height: 196px; } #box .right, #box .left { width: 96px; height: 196px; left: 100px; } #box .top, #box .bottom { width: 296px; height: 96px; top: 50px; } The rotate values can all remain the same as the cube example, but for this rectangular prism, the translate values do differ. The front and back faces are each shifted out 50 pixels since the #box is 100 pixels deep. The translate value for the left and right faces is 150 pixels for their 300 pixels width. Top and bottom panels take 100 pixels for their 200 pixels height: #box .front { -webkit-transform: rotateY(0deg) translateZ(50px); } #box .back { -webkit-transform: rotateX(180deg) translateZ(50px); } #box .right { -webkit-transform: rotateY(90deg) translateZ(150px); } #box .left { -webkit-transform: rotateY(-90deg) translateZ(150px); } #box .top { -webkit-transform: rotateX(90deg) translateZ(100px); } #box .bottom { -webkit-transform: rotateX(-90deg) translateZ(100px); } See Example: Box 1. Just like the cube example, to expose a face, the #box needs to have a style to reverse that face’s transform. Both the translateZ and rotate values are the opposites of the corresponding face. #box.show-front { -webkit-transform: translateZ(-50px) rotateY(0deg); } #box.show-back { -webkit-transform: translateZ(-50px) rotateX(-180deg); } #box.show-right { -webkit-transform: translateZ(-150px) rotateY(-90deg); } #box.show-left { -webkit-transform: translateZ(-150px) rotateY(90deg); } #box.show-top { -webkit-transform: translateZ(-100px) rotateX(-90deg); } #box.show-bottom { -webkit-transform: translateZ(-100px) rotateX(90deg); } See Example: Box 2. Rotating the rectangular box with a CSS transition Carousel Front-end developers have a myriad of choices when it comes to content carousels. Now that we have 3-D capabilities in our browsers, why not take a shot at creating an actual 3-D carousel? The markup for this demo takes the same form as the box, cube and card. Let’s make it interesting and have a carousel with nine panels. <div class="container"> <div id="carousel"> <figure>1</figure> <figure>2</figure> <figure>3</figure> <figure>4</figure> <figure>5</figure> <figure>6</figure> <figure>7</figure> <figure>8</figure> <figure>9</figure> </div> </div> Now, apply basic layout styles. Let’s give each panel of the #carousel 20 pixel gaps between one another, done here with left: 10px; and top: 10px;. The effective width of each panel is 210 pixels. .container { width: 210px; height: 140px; position: relative; -webkit-perspective: 1000; } #carousel { width: 100%; height: 100%; position: absolute; -webkit-transform-style: preserve-3d; } #carousel figure { display: block; position: absolute; width: 186px; height: 116px; left: 10px; top: 10px; border: 2px solid black; } Next up: rotating the faces. This #carousel has nine panels. If each panel gets an equal distribution on the carousel, each panel would be rotated forty degrees from its neighbour (360 ÷ 9). #carousel figure:nth-child(1) { -webkit-transform: rotateY(0deg); } #carousel figure:nth-child(2) { -webkit-transform: rotateY(40deg); } #carousel figure:nth-child(3) { -webkit-transform: rotateY(80deg); } #carousel figure:nth-child(4) { -webkit-transform: rotateY(120deg); } #carousel figure:nth-child(5) { -webkit-transform: rotateY(160deg); } #carousel figure:nth-child(6) { -webkit-transform: rotateY(200deg); } #carousel figure:nth-child(7) { -webkit-transform: rotateY(240deg); } #carousel figure:nth-child(8) { -webkit-transform: rotateY(280deg); } #carousel figure:nth-child(9) { -webkit-transform: rotateY(320deg); } Now, the outward shift. Back when we were creating the cube and box, the translate value was simple to calculate, as it was equal to one half the width, height or depth of the object. With this carousel, there is no size we can automatically use as a reference. We’ll have to calculate the distance of the shift by other means. Drawing a diagram of the carousel, we can see that we know only two things: the width of each panel is 210 pixels; and the each panel is rotated forty degrees from the next. If we split one of these segments down its centre, we get a right-angled triangle, perfect for some trigonometry. We can determine the length of r in this diagram with a basic tangent equation: There you have it: the panels need to be translated 288 pixels in 3-D space. #carousel figure:nth-child(1) { -webkit-transform: rotateY(0deg) translateZ(288px); } #carousel figure:nth-child(2) { -webkit-transform: rotateY(40deg) translateZ(288px); } #carousel figure:nth-child(3) { -webkit-transform: rotateY(80deg) translateZ(288px); } #carousel figure:nth-child(4) { -webkit-transform: rotateY(120deg) translateZ(288px); } #carousel figure:nth-child(5) { -webkit-transform: rotateY(160deg) translateZ(288px); } #carousel figure:nth-child(6) { -webkit-transform: rotateY(200deg) translateZ(288px); } #carousel figure:nth-child(7) { -webkit-transform: rotateY(240deg) translateZ(288px); } #carousel figure:nth-child(8) { -webkit-transform: rotateY(280deg) translateZ(288px); } #carousel figure:nth-child(9) { -webkit-transform: rotateY(320deg) translateZ(288px); } If we decide to change the width of the panel or the number of panels, we only need to plug in those two variables into our equation to get the appropriate translateZ value. In JavaScript terms, that equation would be: var tz = Math.round( ( panelSize / 2 ) / Math.tan( ( ( Math.PI * 2 ) / numberOfPanels ) / 2 ) ); // or simplified to var tz = Math.round( ( panelSize / 2 ) / Math.tan( Math.PI / numberOfPanels ) ); Just like our previous 3-D objects, to show any one panel we need only apply the reverse transform on the carousel. Here’s the style to show the fifth panel: -webkit-transform: translateZ(-288px) rotateY(-160deg); See Example: Carousel 1. By now, you probably have two thoughts: Rewriting transform styles for each panel looks tedious. Why bother doing high school maths? Aren’t robots supposed to be doing all this work for us? And you’re absolutely right. The repetitive nature of 3-D objects lends itself to scripting. We can offload all the monotonous transform styles to our dynamic script, which, if done correctly, will be more flexible than the hard-coded version. See Example: Carousel 2. Conclusion 3-D transforms change the way we think about the blank canvas of web design. Better yet, they change the canvas itself, trading in the flat surface for voluminous depth. My hope is that you took at least one peak at a demo and were intrigued. We web designers, who have rejoiced for border-radius, box-shadow and background gradients, now have an incredible tool at our disposal in 3-D transforms. They deserve just the same enthusiasm, research and experimentation we have seen on other CSS3 features. Now is the perfect time to take the plunge and start thinking about how to use three dimensions to elevate our craft. I’m breathless waiting for what’s to come. See you on the flip side. 2010 David DeSandro daviddesandro 2010-12-14T00:00:00+00:00 https://24ways.org/2010/intro-to-css-3d-transforms/ code
236 Extreme Design Recently, I set out with twelve other designers and developers for a 19th century fortress on the Channel Island of Alderney. We were going to /dev/fort, a sort of band camp for geeks. Our cohort’s mission: to think up, build and finish something – without readily available internet access. Alderney runway, photo by Chris Govias Wait, no internet? Well, pretty much. As the creators of /dev/fort James Aylett and Mark Norman Francis put it: “Imagine a place with no distractions – no IM, no Twitter”. But also no way to quickly look up a design pattern, code sample or source material. Like packing for camping, /dev/fort means bringing everything you’ll need on your back or your hard drive: from long johns to your favourite icon set. We got to work the first night discussing ideas for what we wanted to build. By the time breakfast was cleared up the next morning, we’d settled on Russ’s idea to make the Apollo 13 (PDF) transcript accessible. Days two and three were spent collaboratively planning (KJ style) what features we wanted to build, and unravelling the larger UX challenges of the project. The next five days were spent building it. Within 36 hours of touchdown at Southampton Airport, we launched our creation: spacelog.org The weather was cold, the coal fire less than ideal, food and supplies a hike away, and the process lightning-fast. A week of designing under extreme circumstances called for an extreme process. Some of this was driven by James’s and Norm’s experience running these things, but a lot of it materialised while we were there – especially for our three-strong design team (myself, Gavin O’ Carroll and Chris Govias) who, though we knew each other, had never worked together as a group in this kind of scenario before. The outcome was a pretty spectacular process, with a some key takeaways useful for any small group trying to build something quickly. What it’s like inside the fort /dev/fort has the pressure and pace of a hack day without being a hack day – primarily, no workshops or interruptions‚ but also a different mentality. While hack days are typically developer-driven with a ‘hack first, design later (if at all)’ attitude, James was quick to tell the team to hold off from writing any code until we had a plan. This put a healthy pressure on the design and product folks to slash through the UX problems before we started building. While the fort had definitely more of a hack day feel, all of us were familiar with Agile methods, so we borrowed a few useful techniques such as morning stand-ups and an emphasis on teamwork. We cut some really good features to make our launch date, and chunked the work based on user goals, iterating as we went. What made this design process work? A golden ratio of teams My personal experience both professionally and in free-form situations like this, is a tendency to get/hire a designer. Leaders of businesses, founders of start-ups, organisers of events: one designer is not enough! Finding one ace-blooded designer who can ‘do everything’ will always result in bottleneck and burnout. Like the nuances between different development languages, design is a multifaceted discipline, and very few can claim to be equally strong in every aspect. Overlap in skill set will result in a stronger, more robust interface. More importantly, however, having lots of designers to go around meant that we all had the opportunity to pair with developers, polishing the details that don’t usually get polished. As soon as we launched, the public reception of the design and UX was overwhelmingly positive (proof!). But also, a lot of people asked us who the designer was, attributing it to one person. While it’s important to note that everyone in our team was multitalented (and could easily shift between roles, helping us all stay unblocked), the golden ratio James and Norm devised was two product/developer folks, three interaction designers and eight developers. photo by Ben Firshman Equality inside the fortress walls Something magical about the fort is how everyone leaves the outside world on the drawbridge. Job titles, professional status, Twitter followers, and so on. Like scout camp, a mutual respect and trust is expected of all the participants. Like extreme programming, extreme design requires us all to be equal partners in a collaborative team. I think this is especially worth noting for designers; our past is filled with the clear hierarchy of the traditional studio system which, however important for taste and style, seems less compatible with modern web/software development methods. Being equal doesn’t mean being the same, however. We established clear roles and teams for ourselves on the second day, deferring to that person when a decision needed to be made. As the interface coalesced, the designers and developers took ownership over certain parts to ensure the details got looked after, while staying open to ideas and revisions from the rest of the cohort. Create a space where everyone who enters is equal, but be sure to establish clear roles. Even if it’s just for a short while, the environment will be beneficial. photo by Ben Firshman Hang your heraldry from the rafters Forts and castles are full of lore: coats of arms; paintings of battles; suits of armour. It’s impossible not to be surrounded by these stories, words and ways of thinking. Like the whiteboards on the walls, putting organisational lore in your physical surroundings makes it impossible not to see. Ryan Alexander brought some of those static-cling whiteboard sheets which were quickly filled with use cases; IA; team roles; and, most importantly, a glossary. As soon as we started working on the project, we realised we needed to get clear on what certain words meant: what was a logline, a range, a phase, a key moment? Were the back-end people using these words in the same way design and product was? Quickly writing up a glossary of terms meant everyone was instantly speaking the same language. There was no “Ah, I misunderstood because in the data structure x means y” or, even worse, accidental seepage of technical language into the user interface copy. Put a glossary of your internal terminology somewhere big and fat on the wall. Stand around it and argue until you agree on what it says. Leave it up; don’t underestimate the power of ambient communication and physical reference. Plan more, download less While internet is forbidden inside the fort, we did go on downloading expeditions: NASA photography; code documentation; and so on. The project wouldn’t have been possible without a few trips to the web. We had two lists on the wall: groceries and supplies; internets – “loo roll; Tom Stafford photo“. This changed our usual design process, forcing us to plan carefully and think of what we needed ahead of time. Getting to the internet was a thirty-minute hike up a snow covered cliff to the town airport, so you really had to need it, too. The path to the internet For the visual design, especially, this resulted in more focus up front, and communication between the designers on what assets we required. It made us make decisions earlier and stick with them, creating less distraction and churn later in the process. Try it at home: unplug once you’ve got the things you need. As an artist, it’s easier to let your inner voice shine through if you’re not looking at other people’s work while creating. Social design Finally, our design team experimented with a collaborative approach to wireframing. Once we had collectively nailed down use cases, IA, user journeys and other critical artefacts, we tried a pairing approach. One person drew in Illustrator in real time as the other two articulated what to draw. (This would work equally well with two people, but with three it meant that one of us could jump up and consult the lore on the walls or clarify a technical detail.) The result: we ended up considering more alternatives and quickly rallying around one solution, and resolved difficult problems more quickly. At a certain stage we discovered it was more efficient for one person to take over – this happened around the time when the basic wireframes existed in Illustrator and we’d collectively run through the use cases, making sure that everything was accounted for in a broad sense. At this point, take a break, go have a beer, and give yourself a pat on the back. Put the files somewhere accessible so everyone can use them as their base, and divide up the more detailed UI problems, screens or journeys. At this level of detail it’s better to have your personal headspace. Gavin called this ‘social design’. Chatting and drawing in real time turned what was normally a rather solitary act into a very social process, with some really promising results. I’d tried something like this before with product or developer folks, and it can work – but there’s something really beautiful about switching places and everyone involved being equally quick at drawing. That’s not something you get with non-designers, and frequent swapping of the ‘driver’ and ‘observer’ roles is a key aspect to pairing. Tackle the forest collectively and the trees individually – it will make your framework more robust and your details more polished. Win/win. The return home Grateful to see a 3G signal on our phones again, our flight off the island was delayed, allowing for a flurry of domain name look-ups, Twitter catch-up, and e-mails to loved ones. A week in an isolated fort really made me appreciate continuous connectivity, but also just how unique some of these processes might be. You just never know what crazy place you might be designing from next. 2010 Hannah Donovan hannahdonovan 2010-12-09T00:00:00+00:00 https://24ways.org/2010/extreme-design/ process
238 Everything You Wanted To Know About Gradients (And a Few Things You Didn’t) Hello. I am here to discuss CSS3 gradients. Because, let’s face it, what the web really needed was more gradients. Still, despite their widespread use (or is it overuse?), the smartly applied gradient can be a valuable contributor to a designer’s vocabulary. There’s always been a tension between the inherently two-dimensional nature of our medium, and our desire for more intensity, more depth in our designs. And a gradient can evoke so much: the splay of light across your desk, the slow decrease in volume toward the end of your favorite song, the sunset after a long day. When properly applied, graded colors bring a much needed softness to our work. Of course, that whole ‘proper application’ thing is the tricky bit. But given their place in our toolkit and their prominence online, it really is heartening to see we can create gradients directly with CSS. They’re part of the draft images module, and implemented in two of the major rendering engines. Still, I’ve always found CSS gradients to be one of the more confusing aspects of CSS3. So if you’ll indulge me, let’s take a quick look at how to create CSS gradients—hopefully we can make them seem a bit more accessible, and bring a bit more art into the browser. Gradient theory 101 (I hope that’s not really a thing) Right. So before we dive into the code, let’s cover a few basics. Every gradient, no matter how complex, shares a few common characteristics. Here’s a straightforward one: I spent seconds hours designing this gradient. I hope you like it. At either end of our image, we have a final color value, or color stop: on the left, our stop is white; on the right, black. And more color-rich gradients are no different: (Don’t ever really do this. Please. I beg you.) It’s visually more intricate, sure. But at the heart of it, we have just seven color stops (red, orange, yellow, and so on), making for a fantastic gradient all the way. Now, color stops alone do not a gradient make. Between each is a transition point, the fail-over point between the two stops. Now, the transition point doesn’t need to fall exactly between stops: it can be brought closer to one stop or the other, influencing the overall shape of the gradient. A tale of two syntaxes Armed with our new vocabulary, let’s look at a CSS gradient in the wild. Behold, the simple input button: There’s a simple linear gradient applied vertically across the button, moving from a bright sunflowerish hue (#FAA51A, for you hex nuts in the audience) to a much richer orange (#F47A20). And here’s the CSS that makes it happen: input[type=submit] { background-color: #F47A20; background-image: -moz-linear-gradient( #FAA51A, #F47A20 ); background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #FAA51A), color-stop(1, #F47A20) ); } I’ve borrowed David DeSandro’s most excellent formatting suggestions for gradients to make this snippet a bit more legible but, still, the code above might have turned your stomach a bit. And that’s perfectly understandable—heck, it sort of turned mine. But let’s step through the CSS slowly, and see if we can’t make it a little less terrifying. Verbose WebKit is verbose Here’s the syntax for our little gradient on WebKit: background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #FAA51A), color-stop(1, #F47A20) ); Woof. Quite a mouthful, no? Well, here’s what we’re looking at: WebKit has a single -webkit-gradient property, which can be used to create either linear or radial gradients. The next two values are the starting and ending positions for our gradient (0 0 and 0 100%, respectively). Linear gradients are simply drawn along the path between those two points, which allows us to change the direction of our gradient simply by altering its start and end points. Afterward, we specify our color stops with the oh-so-aptly named color-stop parameter, which takes the stop’s position on the gradient (0 being the beginning, and 100% or 1 being the end) and the color itself. For a simple two-color gradient like this, -webkit-gradient has a bit of shorthand notation to offer us: background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#FAA51A), to(#FAA51A) ); from(#FAA51A) is equivalent to writing color-stop(0, #FAA51A), and to(#FAA51A) is the same as color-stop(1, #FAA51A) or color-stop(100%, #FAA51A)—in both cases, we’re simply declaring the first and last color stops in our gradient. Terse Gecko is terse WebKit proposed its syntax back in 2008, heavily inspired by the way gradients are drawn in the canvas specification. However, a different, leaner syntax came to the fore, eventually appearing in a draft module specification in CSS3. Naturally, because nothing on the web was meant to be easy, this is the one that Mozilla has implemented. Here’s how we get gradient-y in Gecko: background-image: -moz-linear-gradient( #FAA51A, #F47A20 ); Wait, what? Done already? That’s right. By default, -moz-linear-gradient assumes you’re trying to create a vertical gradient, starting from the top of your element and moving to the bottom. And, if that’s the case, then you simply need to specify your color stops, delimited with a few commas. I know: that was almost… painless. But the W3C/Mozilla syntax also affords us a fair amount of flexibility and control, by introducing features as we need them. We can specify an origin point for our gradient: background-image: -moz-linear-gradient(50% 100%, #FAA51A, #F47A20 ); As well as an angle, to give it a direction: background-image: -moz-linear-gradient(50% 100%, 45deg, #FAA51A, #F47A20 ); And we can specify multiple stops, simply by adding to our comma-delimited list: background-image: -moz-linear-gradient(50% 100%, 45deg, #FAA51A, #FCC, #F47A20 ); By adding a percentage after a given color value, we can determine its position along the gradient path: background-image: -moz-linear-gradient(50% 100%, 45deg, #FAA51A, #FCC 20%, #F47A20 ); So that’s some of the flexibility implicit in the W3C/Mozilla-style syntax. Now, I should note that both syntaxes have their respective fans. I will say that the W3C/Mozilla-style syntax makes much more sense to me, and lines up with how I think about creating gradients. But I can totally understand why some might prefer WebKit’s more verbose approach to the, well, looseness behind the -moz syntax. À chacun son gradient syntax. Still, as the language gets refined by the W3C, I really hope some consensus is reached by the browser vendors. And with Opera signaling that it will support the W3C syntax, I suppose it falls on WebKit to do the same. Reusing color stops for fun and profit But CSS gradients aren’t all simple colors and shapes and whatnot: by getting inventive with individual color stops, you can create some really complex, compelling effects. Tim Van Damme, whose brain, I believe, should be posthumously donated to science, has a particularly clever application of gradients on The Box, a site dedicated to his occasional podcast series. Now, there are a fair number of gradients applied throughout the UI, but it’s the feature image that really catches the eye. You see, there’s nothing that says you can’t reuse color stops. And Tim’s exploited that perfectly. He’s created a linear gradient, angled at forty-five degrees from the top left corner of the photo, starting with a fully transparent white (rgba(255, 255, 255, 0)). At the halfway mark, he’s established another color stop at an only slightly more opaque white (rgba(255, 255, 255, 0.1)), making for that incredibly gradual brightening toward the middle of the photo. But then he has set another color stop immediately on top of it, bringing it back down to rgba(255, 255, 255, 0) again. This creates that fantastically hard edge that diagonally bisects the photo, giving the image that subtle gloss. And his final color stop ends at the same fully transparent white, completing the effect. Hot? I do believe so. Rocking the radials We’ve been looking at linear gradients pretty exclusively. But I’d be remiss if I didn’t at least mention radial gradients as a viable option, including a modest one as a link accent on a navigation bar: And here’s the relevant CSS: background: -moz-radial-gradient(50% 100%, farthest-side, rgb(204, 255, 255) 1%, rgb(85, 85, 85) 15%, rgba(85, 85, 85, 0) ); background: -webkit-gradient(radial, 50% 100%, 0, 50% 100%, 15, from(rgb(204, 255, 255)), to(rgba(85, 85, 85, 0)) ); Now, the syntax builds on what we’ve already learned about linear gradients, so much of it might be familiar to you, picking out color stops and transition points, as well as the two syntaxes’ reliance on either a separate property (-moz-radial-gradient) or parameter (-webkit-gradient(radial, …)) to shift into circular mode. Mozilla introduces another stand-alone property (-moz-radial-gradient), and accepts a starting point (50% 100%) from which the circle radiates. There’s also a size constant defined (farthest-side), which determines the reach and shape of our gradient. WebKit is again the more verbose of the two syntaxes, requiring both starting and ending points (50% 100% in both cases). Each also accepts a radius in pixels, allowing you to control the skew and breadth of the circle. Again, this is a fairly modest little radial gradient. Time and article length (and, let’s be honest, your author’s completely inadequate grasp of geometry) prevent me from covering radial gradients in much more detail, because they are incredibly powerful. For those interested in learning more, I can’t recommend the references at Mozilla and Apple strongly enough. Leave no browser behind But no matter the kind of gradients you’re working with, there is a large swathe of browsers that simply don’t support gradients. Thankfully, it’s fairly easy to declare a sensible fallback—it just depends on the kind of fallback you’d like. Essentially, gradient-blind browsers will disregard any properties containing references to either -moz-linear-gradient, -moz-radial-gradient, or -webkit-gradient, so you simply need to keep your fallback isolated from those properties. For example: if you’d like to fall back to a flat color, simply declare a separate background-color: .nav { background-color: #000; background-image: -moz-linear-gradient(rgba(0, 0, 0, 0), rgba(255, 255, 255, 0.45)); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(0, 0, 0, 0)), to(rgba(255, 255, 255, 0.45))); } Or perhaps just create three separate background properties. .nav { background: #000; background: #000 -moz-linear-gradient(rgba(0, 0, 0, 0), rgba(255, 255, 255, 0.45)); background: #000 -webkit-gradient(linear, 0 0, 0 100%, from(rgba(0, 0, 0, 0)), to(rgba(255, 255, 255, 0.45))); } We can even build on this to fall back to a non-gradient image: .nav { background: #000 <strong>url("faux-gradient-lol.png") repeat-x</strong>; background: #000 -moz-linear-gradient(rgba(0, 0, 0, 0), rgba(255, 255, 255, 0.45)); background: #000 -webkit-gradient(linear, 0 0, 0 100%, from(rgba(0, 0, 0, 0)), to(rgba(255, 255, 255, 0.45))); } No matter the approach you feel most appropriate to your design, it’s really just a matter of keeping your fallback design quarantined from its CSS3-ified siblings. (If you’re feeling especially masochistic, there’s even a way to get simple linear gradients working in IE via Microsoft’s proprietary filters. Of course, those come with considerable performance penalties that even Microsoft is quick to point out, so I’d recommend avoiding those. And don’t tell Andy Clarke I told you, or he’ll probably unload his Derringer at me. Or something.) Go forth and, um, gradientify! It’s entirely possible your head’s spinning. Heck, mine is, but that might be the effects of the ’nog. But maybe you’re wondering why you should care about CSS gradients. After all, images are here right now, and work just fine. Well, there are some quick benefits that spring to mind: fewer HTTP requests are needed; CSS3 gradients are easily made scalable, making them ideal for variable widths and heights; and finally, they’re easily modifiable by tweaking a few CSS properties. Because, let’s face it, less time spent yelling at Photoshop is a very, very good thing. Of course, CSS-generated gradients are not without their drawbacks. The syntax can be confusing, and it’s still under development at the W3C. As we’ve seen, browser support is still very much in flux. And it’s possible that gradients themselves have some real performance drawbacks—so test thoroughly, and gradient carefully. But still, as syntaxes converge, and support improves, I think generated gradients can make a compelling tool in our collective belts. The tasteful design is, of course, entirely up to you. So have fun, and get gradientin’. 2010 Ethan Marcotte ethanmarcotte 2010-12-22T00:00:00+00:00 https://24ways.org/2010/everything-you-wanted-to-know-about-gradients/ code
240 My CSS Wish List I love Christmas. I love walking around the streets of London, looking at the beautifully decorated windows, seeing the shiny lights that hang above Oxford Street and listening to Christmas songs. I’m not going to lie though. Not only do I like buying presents, I love receiving them too. I remember making long lists that I would send to Father Christmas with all of the Lego sets I wanted to get. I knew I could only get one a year, but I would spend days writing the perfect list. The years have gone by, but I still enjoy making wish lists. And I’ll tell you a little secret: my mum still asks me to send her my Christmas list every year. This time I’ve made my CSS wish list. As before, I’d be happy with just one present. Before I begin… … this list includes: things that don’t exist in the CSS specification (if they do, please let me know in the comments – I may have missed them); others that are in the spec, but it’s incomplete or lacks use cases and examples (which usually means that properties haven’t been implemented by even the most recent browsers). Like with any other wish list, the further down I go, the more unrealistic my expectations – but that doesn’t mean I can’t wish. Some of the things we wouldn’t have thought possible a few years ago have been implemented and our wishes fulfilled (think multiple backgrounds, gradients and transformations, for example). The list Cross-browser implementation of font-size-adjust When one of the fall-back fonts from your font stack is used, rather than the preferred (first) one, you can retain the aspect ratio by using this very useful property. It is incredibly helpful when the fall-back fonts are smaller or larger than the initial one, which can make layouts look less polished. What font-size-adjust does is divide the original font-size of the fall-back fonts by the font-size-adjust value. This preserves the x-height of the preferred font in the fall-back fonts. Here’s a simple example: p { font-family: Calibri, "Lucida Sans", Verdana, sans-serif; font-size-adjust: 0.47; } In this case, if the user doesn’t have Calibri installed, both Lucida Sans and Verdana will keep Calibri’s aspect ratio, based on the font’s x-height. This property is a personal favourite and one I keep pointing to. Firefox supported this property from version three. So far, it’s the only browser that does. Fontdeck provides the font-size-adjust value along with its fonts, and has a handy tool for calculating it. More control over overflowing text The text-overflow property lets you control text that overflows its container. The most common use for it is to show an ellipsis to indicate that there is more text than what is shown. To be able to use it, the container should have overflow set to something other than visible, and white-space: nowrap: div { white-space: nowrap; width: 100%; overflow: hidden; text-overflow: ellipsis; } This, however, only works for blocks of text on a single line. In the wish list of many CSS authors (and in mine) is a way of defining text-overflow: ellipsis on a block of multiple text lines. Opera has taken the first step and added support for the -o-ellipsis-lastline property, which can be used instead of ellipsis. This property is not part of the CSS3 spec, but we could certainly make good use of it if it were… WebKit has -webkit-line-clamp to specify how many lines to show before cutting with an ellipsis, but support is patchy at best and there is no control over where the ellipsis shows in the text. Many people have spent time wrangling JavaScript to do this for us, but the methods used are very processor intensive, and introduce a JavaScript dependency. Indentation and hanging punctuation properties You might notice a trend here: almost half of the items in this list relate to typography. The lack of fine-grained control over typographical detail is a general concern among designers and CSS authors. Indentation and hanging punctuation fall into this category. The CSS3 specification introduces two new possible values for the text-indent property: each-line; and hanging. each-line would indent the first line of the block container and each line after a forced line break; hanging would invert which lines are affected by the indentation. The proposed hanging-punctuation property would allow us to specify whether opening and closing brackets and quotes should hang outside the edge of the first and last lines. The specification is still incomplete, though, and asks for more examples and use cases. Text alignment and hyphenation properties Following the typographic trend of this list, I’d like to add better control over text alignment and hyphenation properties. The CSS3 module on Generated Content for Paged Media already specifies five new hyphenation-related properties (namely: hyphenate-dictionary; hyphenate-before and hyphenate-after; hyphenate-lines; and hyphenate-character), but it is still being developed and lacks examples. In the text alignment realm, the new text-align-last property allows you to define how the last line of a block (or a line just before a forced break) is aligned, if your text is set to justify. Its value can be: start; end; left; right; center; and justify. The text-justify property should also allow you to have more control over text set to text-align: justify but, for now, only Internet Explorer supports this. calc() This is probably my favourite item in the list: the calc() function. This function is part of the CSS3 Values and Units module, but it has only been implemented by Firefox (4.0). To take advantage of it now you need to use the Mozilla vendor code, -moz-calc(). Imagine you have a fluid two-column layout where the sidebar column has a fixed width of 240 pixels, and the main content area fills the rest of the width available. This is how you could create that using -moz-calc(): #main { width: -moz-calc(100% - 240px); } Can you imagine how many hacks and headaches we could avoid were this function available in more browsers? Transitions and animations are really nice and lovely but, for me, it’s the ability to do the things that calc() allows you to that deserves the spotlight and to be pushed for implementation. Selector grouping with -moz-any() The -moz-any() selector grouping has been introduced by Mozilla but it’s not part of any CSS specification (yet?); it’s currently only available on Firefox 4. This would be especially useful with the way HTML5 outlines documents, where we can have any number of variations of several levels of headings within numerous types of containers (think sections within articles within sections…). Here is a quick example (copied from the Mozilla blog post about the article) of how -moz-any() works. Instead of writing: section section h1, section article h1, section aside h1, section nav h1, article section h1, article article h1, article aside h1, article nav h1, aside section h1, aside article h1, aside aside h1, aside nav h1, nav section h1, nav article h1, nav aside h1, nav nav h1, { font-size: 24px; } You could simply write: -moz-any(section, article, aside, nav) -moz-any(section, article, aside, nav) h1 { font-size: 24px; } Nice, huh? More control over styling form elements Some are of the opinion that form elements shouldn’t be styled at all, since a user might not recognise them as such if they don’t match the operating system’s controls. I partially agree: I’d rather put the choice in the hands of designers and expect them to be capable of deciding whether their particular design hampers or improves usability. I would say the same idea applies to font-face: while some fear designers might go crazy and litter their web pages with dozens of different fonts, most welcome the freedom to use something other than Arial or Verdana. There will always be someone who will take this freedom too far, but it would be useful if we could, for example, style the default Opera date picker: <input type="date" /> or Safari’s slider control (think star movie ratings, for example): <input type="range" min="0" max="5" step="1" value="3" /> Parent selector I don’t think there is one CSS author out there who has never come across a case where he or she wished there was a parent selector. There have been many suggestions as to how this could work, but a variation of the child selector is usually the most popular: article < h1 { … } One can dream… Flexible box layout The Flexible Box Layout Module sounds a bit like magic: it introduces a new box model to CSS, allowing you to distribute and order boxes inside other boxes, and determine how the available space is shared. Two of my favourite features of this new box model are: the ability to redistribute boxes in a different order from the markup the ability to create flexible layouts, where boxes shrink (or expand) to fill the available space Let’s take a quick look at the second case. Imagine you have a three-column layout, where the first column takes up twice as much horizontal space as the other two: <body> <section id="main"> </section> <section id="links"> </section> <aside> </aside> </body> With the flexible box model, you could specify it like this: body { display: box; box-orient: horizontal; } #main { box-flex: 2; } #links { box-flex: 1; } aside { box-flex: 1; } If you decide to add a fourth column to this layout, there is no need to recalculate units or percentages, it’s as easy as that. Browser support for this property is still in its early stages (Firefox and WebKit need their vendor prefixes), but we should start to see it being gradually introduced as more attention is drawn to it (I’m looking at you…). You can read a more comprehensive write-up about this property on the Mozilla developer blog. It’s easy to understand why it’s harder to start playing with this module than with things like animations or other more decorative properties, which don’t really break your layouts when users don’t see them. But it’s important that we do, even if only in very experimental projects. Nested selectors Anyone who has never wished they could do something like the following in CSS, cast the first stone: article { h1 { font-size: 1.2em; } ul { margin-bottom: 1.2em; } } Even though it can easily turn into a specificity nightmare and promote redundancy in your style sheets (if you abuse it), it’s easy to see how nested selectors could be useful. CSS compilers such as Less or Sass let you do this already, but not everyone wants or can use these compilers in their projects. Every wish list has an item that could easily be dropped. In my case, I would say this is one that I would ditch first – it’s the least useful, and also the one that could cause more maintenance problems. But it could be nice. Implementation of the ::marker pseudo-element The CSS Lists module introduces the ::marker pseudo-element, that allows you to create custom list item markers. When an element’s display property is set to list-item, this pseudo-element is created. Using the ::marker pseudo-element you could create something like the following: Footnote 1: Both John Locke and his father, Anthony Cooper, are named after 17th- and 18th-century English philosophers; the real Anthony Cooper was educated as a boy by the real John Locke. Footnote 2: Parts of the plane were used as percussion instruments and can be heard in the soundtrack. where the footnote marker is generated by the following CSS: li::marker { content: "Footnote " counter(notes) ":"; text-align: left; width: 12em; } li { counter-increment: notes; } You can read more about how to use counters in CSS in my article from last year. Bear in mind that the CSS Lists module is still a Working Draft and is listed as “Low priority”. I did say this wish list would start to grow more unrealistic closer to the end… Variables The sight of the word ‘variables’ may make some web designers shy away, but when you think of them applied to things such as repeated colours in your stylesheets, it’s easy to see how having variables available in CSS could be useful. Think of a website where the main brand colour is applied to elements like the main text, headings, section backgrounds, borders, and so on. In a particularly large website, where the colour is repeated countless times in the CSS and where it’s important to keep the colour consistent, using variables would be ideal (some big websites are already doing this by using server-side technology). Again, Less and Sass allow you to use variables in your CSS but, again, not everyone can (or wants to) use these. If you are using Less, you could, for instance, set the font-family value in one variable, and simply call that variable later in the code, instead of repeating the complete font stack, like so: @fontFamily: Calibri, "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif; body { font-family: @fontFamily; } Other features of these CSS compilers might also be useful, like the ability to ‘call’ a property value from another selector (accessors): header { background: #000000; } footer { background: header['background']; } or the ability to define functions (with arguments), saving you from writing large blocks of code when you need to write something like, for example, a CSS gradient: .gradient (@start:"", @end:"") { background: -webkit-gradient(linear, left top, left bottom, from(@start), to(@end)); background: -moz-linear-gradient(-90deg,@start,@end); } button { .gradient(#D0D0D0,#9F9F9F); } Standardised comments Each CSS author has his or her own style for commenting their style sheets. While this isn’t a massive problem on smaller projects, where maybe only one person will edit the CSS, in larger scale projects, where dozens of hands touch the code, it would be nice to start seeing a more standardised way of commenting. One attempt at creating a standard for CSS comments is CSSDOC, an adaptation of Javadoc (a documentation generator that extracts comments from Java source code into HTML). CSSDOC uses ‘DocBlocks’, a term borrowed from the phpDocumentor Project. A DocBlock is a human- and machine-readable block of data which has the following structure: /** * Short description * * Long description (this can have multiple lines and contain <p> tags * * @tags (optional) */ CSSDOC includes a standard for documenting bug fixes and hacks, colours, versioning and copyright information, amongst other important bits of data. I know this isn’t a CSS feature request per se; rather, it’s just me pointing you at something that is usually overlooked but that could contribute towards keeping style sheets easier to maintain and to hand over to new developers. Final notes I understand that if even some of these were implemented in browsers now, it would be a long time until all vendors were up to speed. But if we don’t talk about them and experiment with what’s available, then it will definitely never happen. Why haven’t I mentioned better browser support for existing CSS3 properties? Because that would be the same as adding chocolate to your Christmas wish list – you don’t need to ask, everyone knows you want it. The list could go on. There are dozens of other things I would love to see integrated in CSS or further developed. These are my personal favourites: some might be less useful than others, but I’ve wished for all of them at some point. Part of the research I did while writing this article was asking some friends what they would add to their lists; other than a couple of items I already had in mine, everything else was different. I’m sure your list would be different too. So tell me, what’s on your CSS wish list? 2010 Inayaili de León Persson inayailideleon 2010-12-03T00:00:00+00:00 https://24ways.org/2010/my-css-wish-list/ code
Powered by Datasette · Query took 0.949ms