{"version":"https://jsonfeed.org/version/1","title":"Aaron Gustafson: Content tagged responsive web design","description":"The latest 20 posts and links tagged responsive web design.","home_page_url":"https://www.aaron-gustafson.com","feed_url":"https://www.aaron-gustafson.com/feeds/responsive-web-design.json","author":{"name":"Aaron Gustafson","url":"https://www.aaron-gustafson.com"},"icon":"https://www.aaron-gustafson.com/i/og-logo.png","favicon":"https://www.aaron-gustafson.com/favicon.png","expired":false,"items":[{"id":"https://www.aaron-gustafson.com/publications/books/learning-web-design-sixth-edition/","title":"📗 Learning Web Design","content_html":"<p>Do you want to build web pages but have no prior experience? This friendly guide is the perfect place to start. You'll begin at square one, learning how the web and web pages work, and then steadily build from there. By the end of the book, you'll have the skills to create a simple site with multicolumn pages that adapt for mobile devices.</p>\n","url":"https://www.oreilly.com/library/view/learning-web-design/9781098137670/","tags":["accessibility","CSS","HTML","JavaScript","progressive enhancement","responsive web design","web design","web development","web standards"],"date_published":"2025-05-01T00:00:00Z"},{"id":"https://www.aaron-gustafson.com/publications/articles/request-with-intent-caching-strategies-in-the-age-of-pwas/","title":"📄 Request with Intent: Caching Strategies in the Age of PWAs","content_html":"<p>Caching media files, especially images, seems like an obvious way to improve performance, but should we? To provide a more performant UX without abusing users’ network connections or hard drives, I put a spin on classic best practices, experiment with media caching strategies, and share smart Cache API tricks.</p>\n","url":"https://alistapart.com/article/request-with-intent-caching-strategies-in-the-age-of-pwas/","tags":["progressive web apps","responsive web design","performance"],"date_published":"2019-11-21T00:00:00Z"},{"id":"https://www.aaron-gustafson.com/speaking-engagements/designing-for-everyone-building-great-web-experiences-for-any-device/","title":"📢 Designing for Everyone: Building Great Web Experiences for Any Device","summary":"<p>In this session, I help you think about user experience from its foundation, so you understand what it means to build adaptive web experiences – whether in an app, in a browser, or beyond.</p>","content_html":"<p>As the capabilities of the web platform advance, and the pervasiveness of web content proliferates, fundamental design principles are more important than ever: How do you enhance your experience as new capabilities become available in Microsoft Edge and other browsers? You’ve considered how your content looks and operates on mobile, but how does that design adapt to desktop devices? Is it usable via “headless” interfaces like screen readers or Cortana? Does your content adapt gracefully to the constraints of its environment?</p>\n<p>In this session, I help you think about user experience from its foundation, so you understand what it means to build adaptive web experiences – whether in an app, in a browser, or beyond. We’ll show you some of the newest capabilities coming to Microsoft Edge that let you build differentiated experiences on Windows 10. You’ll walk away practical, cross-platform code examples you can put to use in your projects today, and foundational principles to ensure that your projects are ready for anything.</p>\n","social_text":"In this session, I help you think about user experience from its foundation, so you understand what it means to build adaptive web experiences – whether in an app, in a browser, or beyond.","url":"https://www.aaron-gustafson.com/speaking-engagements/designing-for-everyone-building-great-web-experiences-for-any-device/","tags":["progressive web apps","mobile","performance","progressive enhancement","responsive web design"],"image":"https://www.aaron-gustafson.com/undefined","date_published":"2018-05-07T13:00:00Z"},{"id":"https://www.aaron-gustafson.com/speaking-engagements/advanced-design-methods/","title":"📢 Advanced Design Methods","summary":"<p>Two days of advanced design &amp; layout workshops covering responsive design, progressive enhancement, performance, flexbox, css grid, and more.</p>","content_html":"<p>Two days of advanced design &amp; layout workshops covering responsive design, progressive enhancement, performance, flexbox, css grid, and more.</p>\n","social_text":"Two days of advanced design &amp; layout workshops covering responsive design, progressive enhancement, performance, flexbox, css grid, and more.","url":"https://www.aaron-gustafson.com/speaking-engagements/advanced-design-methods/","tags":["web design","accessibility","CSS","JavaScript","progressive enhancement","responsive web design"],"image":"https://www.aaron-gustafson.com/undefined","date_published":"2017-11-15T00:09:00Z"},{"id":"https://www.aaron-gustafson.com/notebook/planning-adaptive-interfaces-the-workshop/","title":"✍🏻 Planning Adaptive Interfaces: The Workshop","summary":"<p>For the last few years I’ve been running a workshop alternately titled “Planning Adaptive Interfaces” or “Beyond Responsive”, depending on the conference. It’s been one of my favorite workshops to run for a number of reasons, but before I get into that, let me explain what it is and how it works.</p>","content_html":"<p>For the last few years I’ve been running a workshop alternately titled “Planning Adaptive Interfaces” or “Beyond Responsive”, depending on the conference. It’s been one of my favorite workshops to run for a number of reasons, but before I get into that, let me explain what it is and how it works.</p>\n<p>I think we all recognize how much Ethan’s seminal article <a href=\"http://alistapart.com/article/responsive-web-design\">“Responsive Web Design”</a> (and <a href=\"https://abookapart.com/products/responsive-web-design\">his follow-up book</a>) shook up our industry. It changed the way we look at visual design and kindled (or in some cases re-kindled) an interest in catering an experience to mobile devices. But simply incorporating responsive design’s three core strategies—fluid grids, flexible media, media queries—is not the goal; meeting our user’s needs is. Responsive design is not an end in itself… it’s just the beginning.</p>\n<p>We need to embrace the heterogenous nature of the Web—myriad connected devices with vastly different screen sizes (if they even have screens), network connectivity, and capabilities in use by countless individuals, each with their own special needs—and craft experiences that will work anywhere at any time. We need to build robust systems that adapt in ways far beyond aesthetics. I designed this workshop to explore the rich variety of use cases that often get overlooked in the course of building web projects and to show how we can begin considering them as early as possible.</p>\n<p>When I was starting out, I gave “workshops” that basically amounted to a half-day or (worse) a full day for folks to listen to me blather on about one topic or another. People liked them, but I wouldn’t call them fun. And, in hindsight, I question how much value people got from an extended survey of what’s possible without the opportunity to put that knowledge to use. Workshops should encourage attendees to get their hand dirty.</p>\n<p>I kick this workshop off with a relatively brief discussion of the considerations that we should be aware of—beyond screen size and pixel density. I also provide examples of how to adapt interfaces so they rise to meet our customers’ needs. Then I throw out a list of common interface patterns—modals, tabs, etc.—and turn the floor over to the attendees, asking them to build small teams that each examine a single pattern in detail with these considerations in mind. They then spend the rest of the workshop planning out how that interface would adapt to consider factors like accessibility, screen dimensions, device capabilities, JavaScript availability, and so on. All the while, I circulate among the groups, asking and answering questions, pressing them to go a little further with each iteration. Some teams sketch, some prototype, and all spend a lot of time debating, which is awesome!</p>\n<p>I leave the last hour or so for a group discussion of what each team’s accomplished. It gives them a chance to talk through their approach, what they learned, what their pain points were, and how they overcame them. Not does it celebrate their work, but it helps the other attendees discover novel ways to approach these common UI constructs.</p>\n<p>It’s been a blast and I have learned so much from the teams I’ve coached. Each workshop is completely different because each group of attendees is completely different. I’ve run it with groups ranging from 12 to 120, for internal teams at large companies to mixed audiences from all over the world. Everyone who has attended one of these workshops has brought a unique perspective and helped us all get better at our jobs. That’s been one of the best parts of this experience for me.</p>\n<p>If a workshop like this sounds up your alley, I’ll be giving it a few more times in 2016. Your next opportunity will be at <a href=\"http://enhanceconf.com/workshop.html\">EnhanceConf in London in early March</a>. Later in the year, I’ll be giving it as part of <a href=\"https://buildright.io/maker-series/2016/aaron-gustafson\">Sparkbox’s Build Right: Maker Series</a>. I’d love the opportunity to work with you if you can make it!</p>\n","url":"https://www.aaron-gustafson.com/notebook/planning-adaptive-interfaces-the-workshop/","tags":["conferences","progressive enhancement","responsive web design","pattern libraries","empathy","Adaptive Web Design"],"date_published":"2016-02-21T23:56:05Z"},{"id":"https://www.aaron-gustafson.com/speaking-engagements/beyond-responsive/","title":"📢 Beyond Responsive","summary":"<p>Responsive design is not an end in itself… it’s just the beginning.</p>","content_html":"<p>Responsive web design has taken our industry by storm and with good reason: it helps us improve our reach with less effort. But incorporating responsive design is not the goal, meeting your user’s needs is. Responsive design is not an end in itself… it’s just the beginning.</p>\n<p>Embracing the heterogenous nature of the web—the myriad web-enabled devices with vastly different dimensions, screen sizes, networks, and capabilities in use by countless individuals, each with their own special needs—allows you to craft experiences that will work anywhere at any time. It also helps you build robust systems that adapt in ways far beyond aesthetics. This talk will cover a number of considerations that you should be aware of, beyond screen size and pixel density, and provide examples of how to adapt your interfaces so they rise to meet your users’ needs.</p>\n","social_text":"Responsive design is not an end in itself… it’s just the beginning.","url":"https://www.aaron-gustafson.com/speaking-engagements/beyond-responsive/","tags":["responsive web design","progressive enhancement","web design"],"image":"https://www.aaron-gustafson.com/undefined","date_published":"2015-08-12T13:00:00Z"},{"id":"https://www.aaron-gustafson.com/notebook/where-do-we-go-from-here/","title":"✍🏻 Where Do We Go From Here?","summary":"<p><em>I had the great pleasure of delivering the closing keynote for the final Responsive Day Out. Here’s what I had to say.</em></p>","content_html":"<p><em>I had the great pleasure of delivering the closing keynote for the final Responsive Day Out. Here’s what I had to say.</em></p>\n<hr>\n<p>Today has provided an amazing tour of the world of responsive design. We’ve seen how to level-up our workflows and processes. We’ve learned new ways to improve the accessibility of our products. We’ve grappled with modern CSS and HTML capabilities that help us embrace the hugely variable display sizes that swirl and whirl around us.</p>\n<p>We’ve explored the future of modular code and browsers’ capacity for working without network connectivity. And we’ve even taken a trip into the possible future of where the web might go.</p>\n<figure id=\"figure-2015-06-22-01\">\n<p><img src=\"https://www.aaron-gustafson.com/i/posts/2015-06-22/01.jpg\" alt=\"\"></p>\n</figure>\n<p>We’ve come a long way since <a href=\"https://huffduffer.com/adactio/243780\">Ethan’s article</a>, fluid grids, flexible media, and media queries. Those three tenets sowed a seed that has grown and flourished as we have come to better understand the implications of device proliferation. We’ve seen that the web is capable of going anywhere and doing pretty much anything.</p>\n<p>I would argue that <a href=\"https://huffduffer.com/adactio/243780\">“Responsive Web Design”</a> was the first article that really managed to capture the concepts that John Allsopp had discussed so many years before in <a href=\"http://www.alistapart.com/articles/dao/\">“A Dao of Web Design”</a> and distilled them into something the design and development community could really sink their teeth into. It provided a concrete example of the web’s ability to flex and mold itself into whatever shape it needed to take on.</p>\n<p>It was the first time many designers had come to terms with the idea that “experience” was not some monolithic thing.</p>\n<p>Sure, many of us in the web standards community had been talking the talk and walking the walk with regard to <a href=\"http://alistapart.com/article/understandingprogressiveenhancement\">progressive enhancement</a>. And we were gaining converts, but progress was slow. Ethan demonstrated—directly and succinctly—what the progressive enhancement of visual design could look like.</p>\n<p>Providing an identical experience for each and every human being that tries to access our sites would be impossible. There are simply far too many factors to consider. We’ve got screen size, display density, CPU speed, amount of RAM, sensor availability, feature availability, interface methods … <em>breathe</em> … operating system type, operating system version, browser type, browser version, plug-ins installed, network speed, network latency, network congestion, firewalls, proxies, routers, and probably a dozen other factors my mind is incapable of plucking amid the whirlwind of technical considerations.</p>\n<p><strong>And that doesn’t even consider our users.</strong></p>\n<p>When it comes to the people we need to reach for our work to actually matter, we have to consider literacy level, reading acumen, level of domain knowledge, cognitive impairments like learning disabilities and dyslexia, attention deficit issues, environmental distractions, vision impairment, hearing impairment, motor impairment, how much they understand how to use their device, how much they understand how to use their browser, how well-versed in common web conventions they are, and a ton of other “human factors”.</p>\n<p>Every person is different and everyone comes to the web with their own set of special needs. Some are always with them, blindness for example. Others are transient, like breaking your mousing arm. Still others are purely situational and dependent on the device you are using at the time and its technical capabilities or constraints.</p>\n<p>Trying to devise one monolithic experience for each and every person to have in every context that considers every factor would be impossible. And yet, Sir Tim Berners Lee had a vision for a web that was capable of going anywhere. Was he insane?</p>\n<p><a href=\"http://www.w3.org/History/1989/proposal.html\">Sir Tim’s vision for the web</a> was that content could be created once and accessed from anywhere. Disparate but related pieces of “hypermedia” scattered across the globe could be connected to one another via links. Moreover, they would be retrievable by anyone on any device capable of reading HTML. For free.</p>\n<p><strong>Ultimately, Sir Tim envisioned universal accessibility.</strong></p>\n<p>For a great many of us, ensuring our websites are accessible is an afterthought. We talk a good game when it comes to “user centered” this or that, but often treat the word “accessibility” as a synonym for “screen reader”. It’s so much more than that. “Accessibility” is about people. People consume content and use interfaces in many different ways, some similar and some quite dissimilar to how we do it.</p>\n<p>Sure, people with visual impairments often use a screen reader to consume content. But they might also use a braille touch feedback device or a braille printer. They probably also use a keyboard. Or they may use a touchscreen in concert with audio cues. Or they may even use a camera to allow them to “read” content via OCR and text-to-speech. And yes, visual impairment affects a decent percentage of the populace (especially as we age), but it is only part of the “accessibility” puzzle.</p>\n<p>The contrast between text and the background is an important factor in ensuring content remains readable in different lighting situations. Color choice is an accessibility concern.</p>\n<p>The language we use on our sites and in our interfaces directly affects how easy it is for our users to understand what we do, the products we are offering, and why it matters. It also affects how we make our users feel about themselves, their experience, and our companies. Language is an accessibility concern.</p>\n<p>The size of our web pages has a direct effect on how long our pages take to download, how much it costs our customers to access them, and (sometimes) even whether or not the content can be reached. Performance is an accessibility concern.</p>\n<p>I could keep going, but I’m sure you get the point.</p>\n<p>Accessibility is about providing good experiences for everyone, regardless of physical or mental abilities, gender, race, or language. It recognizes that we all have special needs—physical limitations, bandwidth limitations, device limitations—that may require us to experience the same interface in different ways.</p>\n<p>When I visit a website on my phone, for example, I am visually limited by my screen resolution (especially if I am using a browser that encourages zooming) and I am limited in my ability to interact with buttons and links because I am browsing with my fingertips, which are larger and far less accurate than a mouse cursor.</p>\n<p>On a touchscreen, I may need the experience to be slightly different, but I still need to be able to do whatever it is I came to the site to do. I need <em>an</em> experience, but moreover I need the <em>appropriate</em> experience.</p>\n<p>Embracing the reality that experience does’t need to be just one thing will help us reach more people with fewer headaches. Experience can—and should—be crafted as a continuum. This is progressive enhancement: We start with a baseline experience that works for everyone—content, real links, first generation form controls, and forms that actually submit to the server. Then we build up the experience from there.</p>\n<figure id=\"figure-2015-06-22-02\">\n<p><img src=\"https://www.aaron-gustafson.com/i/posts/2015-06-22/02.gif\" alt=\"\"></p>\n</figure>\n<p>Your browser supports HTML5 form controls? Great! You’ll get a better virtual keyboard when you go to type your email address. You can use CSS? Awesome, let me make that reading experience better for you. Oh, you can handle media queries! Let me adjust the layout so those line lengths are a little more comfortable. Wow, your browser supports Ajax?! Here let me load in some teasers for related content you might find interesting.</p>\n<p>Imagine sitting down in a restaurant only to have the waiter immediately bring you a steak. But you’re a vegetarian. You ask if they offer something you can eat and they politely reply <em>Oh I’m sorry, meat is a requirement. Why don’t you just eat meat? It’s easy! You’re really missing out on some tasty food.</em> No waiter who actually cares about your experience would do that.</p>\n<p>And yet we—as an industry—don’t seem to have any problem telling someone they need to change their browser to accommodate us. That’s just wrong. Our work is meaningless without users. We should be bending over backwards to attract and retain them. This is customer service 101.</p>\n<p>This comes back to Postel’s law, which Jeremy often recounts:</p>\n<blockquote>\n<p>Be conservative in what you do, be liberal in what you accept from others.</p>\n</blockquote>\n<p>We need to be lax when it comes to browser support and not make to many (or better yet any) assumptions about what we can send.</p>\n<p>Of course this is not an approach everyone in our industry is ready to embrace, so I’ll offer another quote I come back to time and time again…</p>\n<blockquote>\n<p>When something happens, the only thing in your power is your attitude toward it; you can either accept it or resent it.</p>\n</blockquote>\n<p>We can’t control the world, we can only control our reaction to it.</p>\n<p>Now those of you who’ve gathered for this final Responsive Day Out (or who are following along at home) probably understand this more than most. We feel the constant bombardment of new devices, screen sizes, and capabilities. The only way I’ve found to deal with all of this is to accept it, embrace the diversity, and view device and browser proliferation as a feature, not a bug.</p>\n<p>It’s up to us to educate those around us who have—either by accident or intent—not accepted that diversity is the reality we live in and things are only going to get crazier. Burying our heads in the sand is not an option.</p>\n<p>When I am trying to help folks understand and embrace diversity, I often reach for one of my favorite thought exercises from <a href=\"https://en.wikipedia.org/wiki/John_Rawls\">John Rawls</a>.</p>\n<figure id=\"figure-2015-06-22-03\">\n<p><img src=\"https://www.aaron-gustafson.com/i/posts/2015-06-22/03.jpg\" alt=\"\"></p>\n</figure>\n<p>Rawls was a philosopher who used to run a social experiment with students, church groups, and the like.</p>\n<p>In the experiment, participants were allowed to create their ideal society. It could follow any philosophy: It could be a monarchy or democracy or anarchy. It could be capitalist or socialist. The people in this experiment had free rein to control absolutely every facet of the society… but then he’d add the twist: They could not control what position they occupied in that society.</p>\n<p>This twist is what <a href=\"https://en.wikipedia.org/wiki/John_Harsanyi\">John Harsanyi</a>—an early game theorist—refers to as the <a href=\"https://en.wikipedia.org/wiki/Veil_of_ignorance\">“Veil of Ignorance”</a> and what Rawls found, time and time again, was that individuals participating in the experiment would gravitate toward creating the most egalitarian societies.</p>\n<p>It makes sense: what rational, self-interested human being would treat the elderly, the sick, people of a particular gender, race, creed, or color poorly if they could find themselves in that very same position when the veil is pulled away?</p>\n<p>The things we do to accommodate special needs now pay dividends in the future. Look at ramps.</p>\n<figure id=\"figure-2015-06-22-04\">\n<p><img src=\"https://www.aaron-gustafson.com/i/posts/2015-06-22/04.jpg\" alt=\"\"></p>\n</figure>\n<p>They’re a classic example of an accessibility feature for people in wheelchairs that also benefit people who aren’t in them: People toting luggage, delivery services hauling heavy things on dollies, parents pushing children (or their dressed up dogs) in strollers, a commuter walking her bike, and that guy who just prefers walking up a gentle incline to expending the effort required to mount a step.</p>\n<p>When we create alternative paths to get from Point A to Point B, people can take the one most appropriate for them, whether by choice or necessity. And everyone can accomplish their goals.</p>\n<p>We all have special needs. Some we’re born with. Some we develop. Some are temporary. Some have nothing to do with us personally, but are situational or purely dependent on the hardware we are using, the interaction methods we have available to us, or even the speed at which we can access the Internet or process data.</p>\n<p>What is responsive web design about if not accessibility? Yes, its fundamental tenets are concerned with visual design, but in terms of the big picture, they’re all about providing the best possible reading experience.</p>\n<p>As practitioners of responsive design, we understand the benefits of adapting our interfaces. We understand fallbacks. We understand how to design robust experiences that work under a wide variety of conditions. Every day we broaden the accessibility of our products.</p>\n<p>These skills will make us invaluable as technology continues to offer novel ways of consuming and interacting with our websites.</p>\n<p>We’re just starting to dip or toes—er, hands—into the world of motion-based gestural controls. Sure, we’ve had them in two dimensions on touch screens for a while now but three dimensional motion-based controls are only beginning to appear.</p>\n<p><a href=\"https://www.youtube.com/watch?v=VXhhE-l96qQ#41s/78s\">https://www.youtube.com/watch?v=VXhhE-l96qQ#41s/78s</a></p>\n<p>The first big leap in this direction was <a href=\"https://en.wikipedia.org/wiki/Kinect\">Kinect</a> on the Xbox 360 (and later, Windows). With Kinect, we interact with the computer using body movements like raising a hand (which gets Kinect to pay attention), pushing our hand forward to click/tap, and grasping to drag the canvas in a particular direction.</p>\n<p>The Kinect ushered in a major revolution in terms of interfacing with computers, but from an interaction perspective, it presents similar challenges to those of the <a href=\"https://en.wikipedia.org/wiki/Wii#Wii_Remote\">Wii controller</a> and Sony’s <a href=\"https://en.wikipedia.org/wiki/PlayStation_Move\">PlayStation Move</a>. Large body gestures like raising your hand (or a wand controller) can be tiring.</p>\n<p><a href=\"https://www.youtube.com/watch?v=21LtA5-wiwU#7s/19s\">https://www.youtube.com/watch?v=21LtA5-wiwU#7s/19s</a></p>\n<p>They’re also not terribly accurate. If you thought that touchscreen accuracy was an issue, hand gestures like those for the Kinect or <a href=\"https://en.wikipedia.org/wiki/Leap_Motion\">LEAP Motion</a> pose even more of a challenge.</p>\n<p>To accommodate interactions like this (which we currently have no way of detecting) we need to be aware of how easy it is to click on interactive controls. We need to determine if our buttons and links are large enough and whether there is enough space between them to ensure our user’s intent is accurately conveyed to the browser. Two specs which can help address this are Media Queries Level 4 and Pointer Events.</p>\n<p>In <a href=\"http://dev.w3.org/csswg/mediaqueries-4/\">Media Queries Level 4</a>, we became able to apply style rules to particular interaction contexts. For instance, when we have very accurate control over our cursor (as in the case of a stylus or mouse) or less accurate control (as in the case of a touch screen or physical gesture):</p>\n<pre class=\"language-css\" tabindex=\"0\"><code class=\"language-css\"><span class=\"token atrule\"><span class=\"token rule\">@media</span> <span class=\"token punctuation\">(</span><span class=\"token property\">pointer</span><span class=\"token punctuation\">:</span> fine<span class=\"token punctuation\">)</span></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/* Smaller links and buttons are ok */</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token atrule\"><span class=\"token rule\">@media</span> <span class=\"token punctuation\">(</span><span class=\"token property\">pointer</span><span class=\"token punctuation\">:</span> coarse<span class=\"token punctuation\">)</span></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/* Larger links and buttons are probably a good idea */</span>\n<span class=\"token punctuation\">}</span></code></pre>\n<p>Of course, we want to offer a sensible default in terms of size and spacing as a fallback for older browsers and devices.</p>\n<p>We also have the ability to determine whether the device is capable of hovering over an element and can adjust the interface accordingly.</p>\n<pre class=\"language-css\" tabindex=\"0\"><code class=\"language-css\"><span class=\"token atrule\"><span class=\"token rule\">@media</span> <span class=\"token punctuation\">(</span><span class=\"token property\">hover</span><span class=\"token punctuation\">:</span> hover<span class=\"token punctuation\">)</span></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/* hover-related interactions are A-OK */</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token atrule\"><span class=\"token rule\">@media</span> <span class=\"token punctuation\">(</span><span class=\"token property\">hover</span><span class=\"token punctuation\">:</span> on-demand<span class=\"token punctuation\">)</span></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/* hover-related interactions are potentially difficult,\n     maybe do something else instead */</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token atrule\"><span class=\"token rule\">@media</span> <span class=\"token punctuation\">(</span><span class=\"token property\">hover</span><span class=\"token punctuation\">:</span> none<span class=\"token punctuation\">)</span></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">/* No hover possible :-( */</span>\n<span class=\"token punctuation\">}</span></code></pre>\n<p>We still need to figure out how well all of this ends up working on multimodal devices like the Surface tablet, however. Will the design change as the user switches between input modes? Should it? To that end, the spec also provides <code>any-pointer</code> and <code>any-hover</code> to allow you to query for whether <em>any</em> supported interaction method meets your requirements, but here’s a word of warning from the spec:</p>\n<blockquote>\n<p>Designing a page that relies on hovering or accurate pointing only because <code>any-hover</code> or <code>any-pointer</code> indicate that an input mechanism with these capabilities is available, is likely to result in a poor experience.</p>\n</blockquote>\n<p>These media query options are starting to roll out in Chrome, Mobile Safari, and Microsoft Edge, so it’s worth taking a look at them.</p>\n<p><a href=\"http://www.w3.org/TR/pointerevents/\">Pointer Events</a> is another spec that is beginning to gain some traction. It generalizes interaction to a single event rather than forcing us to silo experience into mouse-driven, touch-driven, pen-driven, (sigh) force-driven, and so on.</p>\n<p>We can unobtrusively detect support for Pointer Events…</p>\n<pre class=\"language-js\" tabindex=\"0\"><code class=\"language-js\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>window<span class=\"token punctuation\">.</span>PointerEvent<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  window<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"pointerdown\"</span><span class=\"token punctuation\">,</span> detectType<span class=\"token punctuation\">,</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre>\n<p>…and then handle them all in the same way or create branches based on the <code>pointerType</code>:</p>\n<pre class=\"language-js\" tabindex=\"0\"><code class=\"language-js\"><span class=\"token keyword\">function</span> <span class=\"token function\">detectType</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">event</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">switch</span> <span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">.</span>pointerType<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> <span class=\"token string\">\"mouse\"</span><span class=\"token operator\">:</span>\n      <span class=\"token comment\">/* mouse input detected */</span>\n      <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> <span class=\"token string\">\"pen\"</span><span class=\"token operator\">:</span>\n      <span class=\"token comment\">/* pen/stylus input detected */</span>\n      <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">case</span> <span class=\"token string\">\"touch\"</span><span class=\"token operator\">:</span>\n      <span class=\"token comment\">/* touch input detected */</span>\n      <span class=\"token keyword\">break</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">default</span><span class=\"token operator\">:</span>\n    <span class=\"token comment\">/* pointerType is empty (could not be detected) or UA-specific custom type */</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>\n<p>Of course, in addition to considering the level of accuracy our users have while interacting with our screens, we also need to consider the potentially increased distance at which our users are reading our content.</p>\n<p>To that end, I’ve been experimenting with the viewport width (<code>vw</code>) unit.</p>\n<p>For a long time, I’ve used ems for the layout’s <code>max-width</code> (so the line length is proportional to the font size). I also use relative font sizes. With that as the foundation, I can use a media query that matches the maximum width and set the base font size at the vw equivalent at the max width.</p>\n<pre class=\"language-css\" tabindex=\"0\"><code class=\"language-css\"><span class=\"token selector\">body</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">max-width</span><span class=\"token punctuation\">:</span> 64em<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token atrule\"><span class=\"token rule\">@media</span> screen <span class=\"token keyword\">and</span> <span class=\"token punctuation\">(</span><span class=\"token property\">min-width</span><span class=\"token punctuation\">:</span> 64em<span class=\"token punctuation\">)</span></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token selector\">body</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token property\">font-size</span><span class=\"token punctuation\">:</span> 1.5625vw<span class=\"token punctuation\">;</span> <span class=\"token comment\">/* ( 1em / 64em ) * 100 */</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>\n<p>Then the whole design will simply zoom the layout when viewed beyond that size.</p>\n<p><a href=\"https://www.youtube.com/watch?v=6XoN9mMgI38\">https://www.youtube.com/watch?v=6XoN9mMgI38</a></p>\n<p>If you don’t want to turn something like that on automatically, you can enable it to be toggled on and off with JavaScript.</p>\n<p><a href=\"https://www.youtube.com/watch?v=96l_W7ca6SM\">https://www.youtube.com/watch?v=96l_W7ca6SM</a></p>\n<p>Things get even crazier when you start to factor in devices like the HoloLens. And no, I have not gotten to play with one yet.</p>\n<p><a href=\"https://www.youtube.com/watch?v=3AADEqLIALk#87s/117s\">https://www.youtube.com/watch?v=3AADEqLIALk#87s/117s</a></p>\n<p>But the idea of being able to drop a resizable virtual screen on any surface presents some interesting possibilities as a user and some unique challenges as a designer. HoloLens, of course, brings with it gesture controls as well, so accounting for a variety of input types should get us pretty far.</p>\n<p>In a similar vein, we should begin to think about what experiences can and should look like when we are browsing solely with our gaze. Gaze tracking has its origins in the accessibility space as a means of providing interface control to folks with limited or no use of their hands. Traditionally, gaze tracking hardware has been several thousand dollars, putting it out of the reach of many people, but that is starting to change.</p>\n<p>In the last few years, the computational power of our devices has increased as the hardware costs associated with supporting gaze tracking have dropped dramatically. Looking around, you can see gaze tracking beginning to move into the public sphere: Many smartphones and smartwatches can recognize when you are looking at them (or at least they do sometimes). This is only a short step away from knowing where on the screen you are looking. And nearly every high-end smartphone is now equipped with a front-facing camera which makes them perfect candidates to provide this interaction method.</p>\n<p><a href=\"https://www.youtube.com/watch?v=DEk7PlJWQgI#18s/54s\">https://www.youtube.com/watch?v=DEk7PlJWQgI#18s/54s</a></p>\n<p>The <a href=\"http://sesame-enable.com/phone/\">Sesame Phone</a> was designed to allow people to use a smartphone without using their hands. It uses facial tracking to move a virtual cursor around the screen, allowing users to interact with the underlying operating system as well as individual applications. It supports tap, swipe, and other gestures (via a context menu) and is pretty impressive in my experience. Technology like this enables people suffering from MS, arthritis, Muscular Dystrophy, and more to use a smartphone and—more importantly to us—browse the web.</p>\n<p><a href=\"https://theeyetribe.com/\">The Eye Tribe</a> and <a href=\"http://www.fixational.com/\">Fixational</a> are similarly working to bring eye tracking to smartphones and tablets. Eye tracking is similar to face tracking, but the cursor follows your focus. Micro gestures—blink, wink, etc.—allow you to interact with the device.</p>\n<p>Even though most gaze tracking software mimics a mouse and has adjustable sensitivity, the accuracy of it as a pointer device is not fantastic. When I’ve used the Sesame Phone, for instance, I’ve have a hard time controlling the position of my head in order to hold the cursor still to hover and click a button. I’m sure this would improve with practice, but it’s safe to say that in a gaze interaction, larger, well spaced, and more easily targeted links and buttons would be a godsend.</p>\n<p>So far, I’ve focused on interaction methods that facilitate navigation and consuming content. But what about filling out a form? I can tell you that typing an email letter-by-letter on a virtual keyboard using your face, sucks…</p>\n<p>Thankfully, most of these gestural implementations are coupled with some form of voice recognition. The Kinect, for instance, will accept verbal commands to navigate and accomplish tasks like filling in forms. The Sesame Phone also supports voice commands for certain basic actions, dictating email, and the like.</p>\n<p>Coupled with voice, the alternative interaction methods of Kinect and Sesame Phone work really well. But voice interaction can stand on its own too.</p>\n<p>Most of us are familiar with <a href=\"https://en.wikipedia.org/wiki/Siri\">Apple’s Siri</a>, <a href=\"https://en.wikipedia.org/wiki/Google_Now\">Google Now</a>, and <a href=\"https://en.wikipedia.org/wiki/Microsoft_Cortana\">Microsoft’s Cortana</a>. These digital assistants are great at retrieving information from select sources and doing other assistant-y things like calculating a tip and setting a reminder. As far as interacting with the web, however, they don’t… yet. We can engage with them, but they can‘t (necessarily) engage with a web page.</p>\n<p>Exposing the information stored in our webpages via semantic HTML and structured syntaxes like <a href=\"http://microformats.org/\">microformats</a>, <a href=\"https://en.wikipedia.org/wiki/Microdata_(HTML)\">microdata</a>, and <a href=\"https://en.wikipedia.org/wiki/RDFa\">RDFa</a> <em>should</em> eventually make our content available to these assistants, but we don’t really know. Their various makers haven’t really given us any clue as to how to do that and, as it stands right now, none of them can look up a web page and read it to you. For that you need to invoke a screen reader.</p>\n<p>Each company offers a first-party screen reader. And all are capable of helping you interact with a page, including helping you fill in forms, without having to see the page. And yet, these technologies have not been coupled with their corresponding assistants. It probably won’t be long before we see that happen.</p>\n<p>When we start to consider how our websites will be experienced in a voice context, the readability of our web pages becomes crucial. Clear well-written prose and a logical source order will be an absolute necessity. If our pages don’t make sense when read, what’s the point?</p>\n<p>Content strategist Steph Hay views interface as an opportunity to have a conversation with our users. Soon it literally will be.</p>\n<p>Interestingly, Microsoft has given us a peek at what it might be like to design custom voice commands for our websites beyond what the OS supports with Cortana. In other words, they let us teach their assistant.</p>\n<p>In Windows 10, installable web apps can include a <a href=\"https://msdn.microsoft.com/en-us/library/windows/apps/dn722331.aspx\">Voice Command Definition (VCD) file</a> in the <code>head</code> of the page to enable custom commands:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>meta</span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>msapplication-cortanavcd<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">content</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>http://myapp.io/vcd.xml<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span></code></pre>\n<p>The referenced VCD file is simply an XML file defining the keyword for the web app and commands that can be issued.</p>\n<p>Using very basic syntax, The VCD identifies optional pieces of a given phrase and variables Cortana should extract:</p>\n<pre class=\"language-xml\" tabindex=\"0\"><code class=\"language-xml\"><span class=\"token prolog\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>VoiceCommands</span> <span class=\"token attr-name\">xmlns</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>http://schemas.microsoft.com/voicecommands/1.2<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>CommandSet</span> <span class=\"token attr-name\"><span class=\"token namespace\">xml:</span>lang</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>en-us<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">Name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>groupPost<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>CommandPrefix</span><span class=\"token punctuation\">></span></span>Group Post<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>CommandPrefix</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Example</span><span class=\"token punctuation\">></span></span>Group Post add note<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Example</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Command</span> <span class=\"token attr-name\">Name</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>addNote<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Example</span><span class=\"token punctuation\">></span></span>add a note {message} using group post<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Example</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ListenFor</span> <span class=\"token attr-name\">RequireAppName</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>BeforeOrAfterPhrase<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>[please] add a note [that] {noteSubject}<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ListenFor</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Feedback</span><span class=\"token punctuation\">></span></span>adding {noteSubject} to Group Post<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Feedback</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>Navigate</span> <span class=\"token attr-name\">Target</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>/addNote.htm<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">/></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>Command</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>PhraseTopic</span> <span class=\"token attr-name\">Label</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>noteSubject<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">Scenario</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Dictation<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>PhraseTopic</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>CommandSet</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>VoiceCommands</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>This particular app passes the captured information over to JavaScript for processing. That’s right, <a href=\"https://msdn.microsoft.com/en-us/library/dn722330.aspx#handle_activation_and_execute_voice_commands\">Cortana has a JavaScript API too</a>. Pretty neat.</p>\n<p>But traditional computers and smart mobile devices aren’t the only place we’re starting to see voice based experiences. We also have disembodied voices like <a href=\"https://en.wikipedia.org/wiki/Amazon_Echo\">Amazon’s Echo</a> and <a href=\"http://www.theubi.com/\">the Ubi</a> which are completely headless.</p>\n<figure id=\"figure-2015-06-22-11\">\n<p><img src=\"https://www.aaron-gustafson.com/i/posts/2015-06-22/05.jpg\" alt=\"\"></p>\n</figure>\n<p>Right now, they both seem squarely focused on helping your house become “smarter”—streaming music, adjusting the thermostat, etc.—but it isn’t hard to imagine these devices becoming coupled with the ability to browse and interact with the web.</p>\n<p>In the near future, voice-based interactions with the web will be entirely possible. They will likely suck a bit at first, but they’ll get better.</p>\n<p>I’m going to make a somewhat bold prediction: while touch has been revolutionary in many ways toward improving digital access, voice is going to be even more significant. Voice-based interfaces will create new opportunities for people to interact with and participate in the digital world.</p>\n<p>Because we’ve been thinking about how the experiences we create are consumable across a variety of devices, we’ve got the jump on other folks working on the web when it comes to voice. We see experience as a continuum, starting with text.</p>\n<p>As voice technology matures, we will be the ones people look to as the experts. We will empower the next generation of websites and applications to become voice-enabled and in so doing, we will improve the lives of billions. Because “accessibility” is not about disabilities, it’s about access and <strong>it’s about people</strong>.</p>\n<p>Sure, we’ll make it easier to look up movie times and purchase tickets to see the latest <cite>Transformers</cite> debacle, but we will also empower the nearly 900 million people globally—over 60% of whom are women—that are illiterate. And that’s a population that has been largely ignored on our dominantly textual web.</p>\n<p>We will create new opportunities for the poor and disadvantaged to participate in a world that has excluded them. You may not be aware, but 80% of Fortune 500 companies—think Target, Walmart—only accept job applications online or via computers. We will enable people who have limited computer skills or who struggle with reading to apply for jobs with these companies.</p>\n<p>We can help bridge the digital divide and the literacy gap. We can create opportunities for people to better their lives and the lives of their families. We have the power to create more equity in this world than most of us have ever dreamed.</p>\n<p>This is an incredibly exciting time, not just for the responsive design community, not just the web, but for the world! The future is coming and I can’t wait to see how awesome you make it!</p>\n<figure id=\"figure-2015-06-22-12\">\n<p><img src=\"https://www.aaron-gustafson.com/i/posts/2015-06-22/06.jpg\" alt=\"\"></p>\n</figure>\n<hr>\n<p><em>Responsive Day Out 3: The Final Breakpoint was held in Brighton, UK on 19 June 2015.</em></p>\n<ul>\n<li><a href=\"https://huffduffer.com/adactio/243780\">Listen to this presentation on Huffduffer</a>.</li>\n<li>Read <a href=\"https://decadecity.net/blog/2015/06/19/aaron-gustafson-where-do-we-go-here\">Orde Saunders’ notes</a> from my talk.</li>\n<li>Read <a href=\"https://hiddedevries.nl/en/blog/2015-06-20-responsive-day-out-3-the-final-breakpoint/\">Hidde de Vries’ recap of the day</a>.</li>\n</ul>\n","social_text":"Here’s my closing keynote from Responsive Day Out 3.","url":"https://www.aaron-gustafson.com/notebook/where-do-we-go-from-here/","tags":["progressive enhancement","accessibility","responsive web design"],"date_published":"2015-06-22T15:49:56Z"},{"id":"https://www.aaron-gustafson.com/speaking-engagements/where-do-we-go-from-here/","title":"📢 Where Do We Go From Here?","summary":"<p>We’ve come a long way since Ethan’s article, fluid grids, flexible media, and media queries. What’s next?</p>","content_html":"<p>We’ve come a long way since Ethan’s article, fluid grids, flexible media, and media queries. What’s next?</p>\n","social_text":"We’ve come a long way since Ethan’s article, fluid grids, flexible media, and media queries. What’s next?","url":"https://www.aaron-gustafson.com/speaking-engagements/where-do-we-go-from-here/","tags":["responsive web design","progressive enhancement"],"image":"https://www.aaron-gustafson.com/undefined","date_published":"2015-06-19T13:00:00Z"},{"id":"https://www.aaron-gustafson.com/appearances/podcasts/2015-01-26-cross-device-adaptive-design/","title":"🎧 Cross-device Adaptive Design","content_html":"<p>Jenn Lukas and I talked to Jared about responsive web design, progressive enhancement, and mobile in advance of our talk and workshop at UXIM in April.</p>\n","url":"http://archive.uie.com/brainsparks/2015/01/26/aaron-gustafson-jenn-lukas-cross-device-adaptive-design/","tags":["responsive web design","progressive enhancement","mobile"],"date_published":"2015-01-26T00:00:00Z"},{"id":"https://www.aaron-gustafson.com/notebook/adaptive-images-in-expressionengine-with-ce-image/","title":"✍🏻 Adaptive Images in ExpressionEngine with CE Image","summary":"<p>One of the biggest headaches of responsive design has been dealing with images. Thankfully our work on the <a href=\"http://ricg.io\">Responsive <del>Images</del> <ins>Issues</ins> Community Group</a> has resulted in a rock-solid set of elements and attributes to address all of your adaptive image needs. My company, <a href=\"http://easy-designs.net\">Easy Designs</a>, recently redesigned <a href=\"http://www.nichols.edu\">Nichols College’s website</a> and that project just happened to coincide adaptive images landing in <a href=\"http://www.chromium.org/blink\">Blink</a> (the rendering engine that powers Chrome and Opera). Naturally, we jumped at the opportunity to use them.</p>","content_html":"<p>One of the biggest headaches of responsive design has been dealing with images. Thankfully our work on the <a href=\"http://ricg.io\">Responsive <del>Images</del> <ins>Issues</ins> Community Group</a> has resulted in a rock-solid set of elements and attributes to address all of your adaptive image needs. My company, <a href=\"http://easy-designs.net\">Easy Designs</a>, recently redesigned <a href=\"http://www.nichols.edu\">Nichols College’s website</a> and that project just happened to coincide adaptive images landing in <a href=\"http://www.chromium.org/blink\">Blink</a> (the rendering engine that powers Chrome and Opera). Naturally, we jumped at the opportunity to use them.</p>\n<p>Most Nichols College sites run on <a href=\"http://ellislabs.com/expressionengine\">EllisLab’s ExpressionEngine</a>, a solid little workhorse of a CMS we’ve been using for years. We love it because it gives us complete control over the markup it generates. Now EE offers some pretty decent file management and image manipulation utilities out of the box, but the options it provides were not enough to handle our adaptive image needs; we needed backup. <a href=\"http://www.causingeffect.com/software/expressionengine/ce-image\">Causing Effect’s CE Image</a> add-on is reasonably priced and offered exactly the functionality we needed to make our adaptive image dreams a reality.</p>\n<p>I won’t bore you with how to set up CE Image as there is <a href=\"http://www.causingeffect.com/software/expressionengine/ce-image/user-guide\">documentation on that</a>, but I will walk you through two different responsive image use-cases we had and how we addressed them using this add-on.</p>\n<h2 id=\"header-images\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#header-images\" aria-hidden=\"true\">#</a> Header images</h2>\n<p>The first use case we had was a series of large, focal images. You can find different examples of them on <a href=\"http://www.nichols.edu\">the homepage</a> and landing pages (like <a href=\"http://www.nichols.edu/admissions/\">this one for Admissions</a>). The first pass on making these images adaptive involved the <code>picture</code> element for which <a href=\"https://html.spec.whatwg.org/multipage/embedded-content.html#adaptive-images\">the spec</a> is known. The markup we were generating was based on the pattern outlined for <a href=\"http://scottjehl.github.io/picturefill/\">Picturefill</a>, a JavaScript polyfill that implements adaptive images in browsers that don’t:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>picture</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>page__image-header__photo<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token comment\">&lt;!--[if IE 9]>&lt;video style=\"display: none;\">&lt;![endif]--></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>source</span> <span class=\"token attr-name\">srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>about_940_343_int_s_c1_full.jpg<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">media</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>(min-width: 40em)<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>source</span> <span class=\"token attr-name\">srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>about_800_350_int_c1_medium.jpg<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">media</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>(min-width: 20em)<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>source</span> <span class=\"token attr-name\">srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>about_480_350_int_c1_small.jpg<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n  <span class=\"token comment\">&lt;!--[if IE 9]>&lt;/video>&lt;![endif]--></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>img</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>{made}<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">alt</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span><span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>picture</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>To get to that point, however, we needed to use CE Image to generate (and cache) the specific sizes we needed:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>picture</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>page__image-header__photo<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token comment\">&lt;!--[if IE 9]>&lt;video style=\"display: none;\">&lt;![endif]--></span>\n  {exp:ce_img:pair src=\"{content_focal_image}\" filename_suffix=\"_full\"\n  width=\"940\" allow_scale_larger=\"yes\" crop=\"yes\" interlace=\"yes\" cache_dir=\"/\"\n  }\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>source</span> <span class=\"token attr-name\">srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>{made}<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">media</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>(min-width: 40em)<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n  {/exp:ce_img:pair} {exp:ce_img:pair src=\"{content_focal_image}\"\n  filename_suffix=\"_medium\" width=\"800\" height=\"600\" crop=\"yes\" interlace=\"yes\"\n  cache_dir=\"/\" }\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>source</span> <span class=\"token attr-name\">srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>{made}<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">media</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>(min-width: 20em)<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n  {/exp:ce_img:pair} {exp:ce_img:pair src=\"{content_focal_image}\"\n  filename_suffix=\"_small\" width=\"480\" height=\"360\" crop=\"yes\" interlace=\"yes\"\n  cache_dir=\"/\" }\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>source</span> <span class=\"token attr-name\">srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>{made}<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n  <span class=\"token comment\">&lt;!--[if IE 9]>&lt;/video>&lt;![endif]--></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>img</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>{made}<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">alt</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span><span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n  {/exp:ce_img:pair}\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>picture</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>Not what’s a lot of code, so let’s just look at one segment of that jumble:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\">{exp:ce_img:pair src=\"{content_focal_image}\" filename_suffix=\"_full\" width=\"940\"\nallow_scale_larger=\"yes\" crop=\"yes\" interlace=\"yes\" cache_dir=\"/\" }\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>source</span> <span class=\"token attr-name\">srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>{made}<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">media</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>(min-width: 40em)<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n{/exp:ce_img:pair}</code></pre>\n<p>This is an example using CE Image’s tag pair option, which lets you control the markup output. In the opening tag, we set several properties:</p>\n<ul>\n<li><code>src</code> is the path to the original image uploaded by content authors;</li>\n<li><code>filename_suffix</code> is the suffix we want added to the cached file to differentiate it from others in the cache (and make the files more easily scannable);</li>\n<li><code>width</code> is our desired output width for the generated image;</li>\n<li><code>allow_scale_larger</code> does exactly what you’d expect: it dictates whether or not CE Image should scale the image to reach the desired width;</li>\n<li><code>crop</code> tells CE Image whether it’s okay to crop the image;</li>\n<li><code>interlace</code> tells CE Image to use image interlacing (which can speed load time); and</li>\n<li><code>cache_dir</code> tells CE Image where to store the cached image (in relation to our global configuration)</li>\n</ul>\n<p>Then, within the tag pair is the <code>source</code> element with the <code>srcset</code> value set to the path to the file CE Image generated (referenced by the <code>made</code> variable) and the associated media query.</p>\n<p>Multiply that a few times for the different sizes and you have the full <code>picture</code> element.</p>\n<p>Now that’s all well and good, but shortly after launch, <a href=\"http://ericportis.com/\">Eric Portis</a> wrote <a href=\"http://ericportis.com/posts/2014/srcset-sizes/\">an amazing post explaining how the <code>srcset</code> and <code>sizes</code> attributes operate</a> and it cleared up a lot of my confusion on the matter. He convinced me that the age-old <code>img</code> element, with these new attributes, would be far more maintainable. With a fire in my belly, I rewrote the markup:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\">&lt;img class=\"page__image-header__photo\" alt=\"\"\n    {exp:ce_img:pair\n        src=\"{embed:image}\"\n        filename_suffix=\"_small\"\n        width=\"480\"\n        height=\"320\"\n        crop=\"yes\"\n        interlace=\"yes\"\n        cache_dir=\"/\"\n        }\n        src=\"{made}\"\n        srcset=\"{made} 480w,\n    {/exp:ce_img:pair}\n    {exp:ce_img:pair\n        src=\"{embed:image}\"\n        filename_suffix=\"_medium\"\n        width=\"800\"\n        height=\"600\"\n        crop=\"yes\"\n        interlace=\"yes\"\n        cache_dir=\"/\"\n        }\n        {made} 800w,\n    {/exp:ce_img:pair}\n    {exp:ce_img:pair\n        src=\"{embed:image}\"\n        filename_suffix=\"_full\"\n        width=\"940\"\n        allow_scale_larger=\"yes\"\n        crop=\"yes\"\n        interlace=\"yes\"\n        cache_dir=\"/\"\n        }\n        {made} 940w\"\n    {/exp:ce_img:pair}\n    ></code></pre>\n<p>The CE Image behavior is exactly the same, but the resulting markup is much clearer:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>img</span>\n  <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>page__image-header__photo<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">alt</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span><span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>about_480_320_int_c1_small.jpg<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>\n    about_480_320_int_c1_small.jpg  480w,\n    about_800_350_int_c1_medium.jpg 800w,\n    about_940_343_int_s_c1_full.jpg 940w\n  <span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">/></span></span></code></pre>\n<p>The added bonus of this approach is that I am not hard-coding any media queries and the browser gets to make the ultimate decision of which image to request. All I am doing is telling the browser the image options and their respective widths within the <code>srcset</code> attribute. As all of the images take up 100% of their containers, I didn’t even need to use the <code>sizes</code> attribute. Easy peasy.</p>\n<h2 id=\"%E2%80%9Cnice-to-have%E2%80%9D-images\" tabindex=\"-1\"><a class=\"header-anchor\" href=\"#%E2%80%9Cnice-to-have%E2%80%9D-images\" aria-hidden=\"true\">#</a> “Nice to Have” Images</h2>\n<p>Not every image adds something to the page. Some are purely optional, a visual enhancement. In order to reduce the size of pages on smaller screens, we often choose to “lazy load” certain image assets after page load, when we know there is enough room to display the image or when we feel it would be an enhancement to the design.</p>\n<p>Now some of you might be wondering: <em>Why not just <code>display:none</code> below a certain threshold?</em> Well, I’ll tell you: images that are hidden with CSS are still requested by the browser. That means users who don’t see the images are still paying to download them (whether in terms of time waiting for the page to render or actual money on a metered connection). That kinda sucks for them. We should show our users a bit more respect and only request the images when we need them.</p>\n<p>We wrote <a href=\"https://github.com/easy-designs/easy-lazy-images.js\">a lazy-loading image script</a> a few years back and have battle tested it on numerous sites to great success. It’s all based on a simple markup pattern:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span>\n  <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>module__image image--lazy<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">data-image-src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Tim-Smith_220x140_220_140_int_c1.jpg<span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>The <code>data-img-src</code> attribute defines the path to the “nice to have” image and then the JavaScript adds the image element into the page when the appropriate conditions are met:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span>\n  <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>module__image image--lazy<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">data-image-src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Tim-Smith_220x140_220_140_int_c1.jpg<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">data-image-loaded</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span><span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>img</span> <span class=\"token attr-name\">alt</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span><span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>Tim-Smith_220x140_220_140_int_c1.jpg<span class=\"token punctuation\">\"</span></span> <span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>Pretty simple. It even supports <code>srcset</code>:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span>\n  <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>module__image image--lazy<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">data-image</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>about_480_320_int_c1_small.jpg<span class=\"token punctuation\">\"</span></span>\n  <span class=\"token attr-name\">data-image-srcset</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>about_480_320_int_c1_small.jpg 480w,\n                      about_800_350_int_c1_medium.jpg 800w,\n                      about_940_343_int_s_c1_full.jpg 940w<span class=\"token punctuation\">\"</span></span>\n<span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span></code></pre>\n<p>The <a href=\"https://github.com/easy-designs/easy-lazy-images.js#usage\">full documentation is up on Github</a>.</p>\n<p>Implementing this in the context of CE Image was a breeze and builds on the <code>source</code> pattern I showed earlier:</p>\n<pre class=\"language-html\" tabindex=\"0\"><code class=\"language-html\">{if testimonial_photo} {exp:ce_img:pair src=\"{testimonial_photo}\" width=\"223\"\nheight=\"140\" allow_scale_larger=\"yes\" crop=\"yes\" interlace=\"yes\" cache_dir=\"/\" }\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">class</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>module__image image--lazy<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">data-image-src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>{made}<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n{/exp:ce_img:pair} {/if}</code></pre>\n<p>We are only just beginning to scratch the surface of what’s possible with adaptive images and I am sure we will come up with newer, better ways to do this stuff. Heck, there may even be an adaptive images add-on in the pipeline for ExpressionEngine. But, in the meantime, if you are trying to implement adaptive images with ExpressionEngine, CE Image is a good way to go.</p>\n","url":"https://www.aaron-gustafson.com/notebook/adaptive-images-in-expressionengine-with-ce-image/","tags":["web design","responsive web design","ExpressionEngine","progressive enhancement"],"date_published":"2014-11-21T23:18:23Z"},{"id":"https://www.aaron-gustafson.com/publications/books/responsive-typography-using-type-well-on-the-web/","title":"📗 Responsive Typography","content_html":"<p>I can honestly say that <cite>Responsive Typography</cite> is a book well worth reading. Jason’s natural and friendly style makes for an easy read and it’s chock-full of actionable recommendations and tips you’ll want to start using right away.</p>\n","url":"http://shop.oreilly.com/product/0636920034063.do","tags":["responsive web design","web design","CSS"],"date_published":"2014-10-06T17:00:00Z"},{"id":"https://www.aaron-gustafson.com/notebook/responsive-typography/","title":"✍🏻 Responsive Typography","summary":"<p>I’m incredibly excited to see that <a href=\"https://twitter.com/jpamental\">Jason Pamental</a>’s fantastic <a href=\"https://www.amazon.com/gp/product/1491907096/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1491907096&amp;linkCode=as2&amp;tag=easydesign-20&amp;linkId=JC6INFXF3DHODKEM\"><cite>Responsive Typography</cite></a> is finally available. I had the great pleasure of reviewing an early galley and I can honestly say that it’s a book well worth reading. Jason’s natural and friendly style makes for an easy read and it’s chock-full of actionable recommendations and tips you’ll want to start using right away.</p>","content_html":"<p>I’m incredibly excited to see that <a href=\"https://twitter.com/jpamental\">Jason Pamental</a>’s fantastic <a href=\"https://www.amazon.com/gp/product/1491907096/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1491907096&amp;linkCode=as2&amp;tag=easydesign-20&amp;linkId=JC6INFXF3DHODKEM\"><cite>Responsive Typography</cite></a> is finally available. I had the great pleasure of reviewing an early galley and I can honestly say that it’s a book well worth reading. Jason’s natural and friendly style makes for an easy read and it’s chock-full of actionable recommendations and tips you’ll want to start using right away.</p>\n<p>In fact, I think <cite>Responsive Typography</cite> is such an invaluable book, I offered to write the Foreword and Jason (and O’Reilly) have been kind enough to let me reprint it here:</p>\n<blockquote>\n<p>Back in my day, all we had was the <code>font</code> element.</p>\n<p>I fully realize that makes me sound like an old man, but I’m not ready to chase young whippersnappers off my lawn quite yet. But the fact remains that when I taught myself how to build web pages back in the mid-’90s, our design options were fairly limited. Heck, my first experience on the Web was on a text-based browser that provided me access to page upon glorious page of stark, blocky Courier. White text. Black background. 100% responsive.</p>\n<p>When visual browsers finally hit the scene, ushering in images and the <code>font</code> element, we web designers finally had the opportunity to move out of monospace. I’ll leave it to Jason to delve into the history of typography on the Web, but the advent of visual browsers opened the floodgates for use (and abuse) of type online. It was the desktop publishing revolution all over again: a direct assault on the sensibilities of anyone with even the slightest understanding of typography.</p>\n<p>Over the years, we’ve made a lot of mistakes with web type: Fonts embedded in images. Fonts embedded in Flash. Fonts embedded in JavaScript. Many of those were attempts to bypass the gridlock created by browser makers, type foundries, and the W3C, who couldn’t come to a consensus on how to balance a desire for more type options on the Web while ensuring typographers got paid for all of their hard work. While they bickered, we soldiered on, looking for more accessible and maintainable ways to use more typefaces.</p>\n<p>And while we were busy tinkering with sIFR and Cufón, eagerly awaiting the day we could abandon those hacks and have real browser support for actual font formats, an army of little black rectangles had caught a whiff of the awesome content we were serving up to desktop browsers.</p>\n<p>Like ants at a Sunday picnic, these little black rectangles initially appeared one or two at a time. They were easily ignored, a nuisance. Nothing to take too seriously. But before we knew what was happening, that trickle turned into a flood and those little rectangles were hungry. Instead of taking a crumb here and there—which we tossed to them with a great sense of self-satisfaction—these ambitious ants were carrying off whole deli trays and the friggin’ <cite>New York Times</cite>.</p>\n<p>These little black rectangles are, of course, the surge of handheld (or at least hand-holdable) devices that have been redefining our concept of “the Web” almost daily. They exhibit widely variable screen sizes: from about the size of a matchbook, to ones that are bigger than an extra large pizza. They sport a plethora of pixel densities, new interaction methods, unpredictable network connection speeds, and low-powered processors that can’t possibly compete with traditional laptop and desktop CPUs (not to mention a handful of different operating systems and browsers). All of these factors affect how—and even whether—your typographic choices will make it to your customers, and it’s a lot to take in.</p>\n<p>Thankfully, Jason has your back. The book you’re now reading is invaluable: it’s chock-full of useful approaches, practical code samples, and advice for dealing with typography in the age of responsive web design.</p>\n<p>By the time you finish this brief book, you’ll be ready to handle pretty much any device someone may throw at you. But hopefully they won’t. Devices are hard. And expensive.</p>\n<p>— Aaron Gustafson<br/>\n   Author, <cite>Adaptive Web Design</cite></p>\n</blockquote>\n<p>By the way, if you’re on a typography kick I’ll also recommend an second new book by another Jason I respect greatly: <a href=\"https://jasonsantamaria.com\">Jason Santa Maria</a>’s <a href=\"https://www.abookapart.com/products/on-web-typography\"><cite>On Web Typography</cite></a>. The two books books compliment each other perfectly, with very little overlap. They’d make an awesome bundle.</p>\n","url":"https://www.aaron-gustafson.com/notebook/responsive-typography/","tags":["web design","writing","responsive web design"],"date_published":"2014-09-20T20:43:22Z"},{"id":"https://www.aaron-gustafson.com/appearances/podcasts/2014-09-05-progressive-enhancement-and-friends/","title":"🎧 Progressive Enhancement and Friends","content_html":"<p>Justin Avery and I chat about responsive design, element queries, progressive enhancement and dumb JavaScript.</p>\n","url":"https://web.archive.org/web/20210226070435/https://responsivedesign.is/podcasts/rwd-podcast-episode-18-aaron-gustafson/","tags":["progressive enhancement","responsive web design","JavaScript"],"date_published":"2014-09-05T00:00:00Z"},{"id":"https://www.aaron-gustafson.com/speaking-engagements/responsive-design-and-beyond/","title":"📢 Responsive Design and Beyond","summary":"<p>Responsive design is not an end in itself… it’s just the beginning.</p>","content_html":"<p>Responsive web design has taken our industry by storm and with good reason: it helps us improve our reach with less effort. But incorporating responsive design is not the goal, meeting our user’s needs is. Responsive design is not an end in itself… it’s just the beginning.</p>\n<p>As a fitting way to kick off our new workshop series, Code &amp; Creativity asked two internationally-renown mobile web and responsive design experts—Brad Frost (of This is Responsive, and Pattern Lab fame) and I—to come and teach you everything we need to know about working in this multi-device reality.</p>\n<p>For the first part of the day, Brad and I surveyed the landscape of responsive design, covering:</p>\n<ul>\n<li>broad concepts,</li>\n<li>strategies,</li>\n<li>the design process &amp; deliverables,</li>\n<li>emerging design patterns and principles, and</li>\n<li>development best practices and considerations.</li>\n</ul>\n<p>Then, we broke into small groups to tackle some thorny responsive challenges through discussions, sketching, and even a little coding, while Brad &amp; I provided real-time feedback and pushed attendees to go further. At the end, everyone shared their findings with the class and got additional feedback from the experts.</p>\n","social_text":"Responsive design is not an end in itself… it’s just the beginning.","url":"https://www.aaron-gustafson.com/speaking-engagements/responsive-design-and-beyond/","tags":["progressive enhancement","responsive web design","user experience","web design","web development"],"image":"https://www.aaron-gustafson.com/undefined","date_published":"2014-05-02T13:00:00Z"},{"id":"https://www.aaron-gustafson.com/notebook/beyond-responsive-workshops-this-may/","title":"✍🏻 Beyond Responsive Workshops this May","summary":"<p>\tA lot fo my work lately has been consulting and working with teams to help them to establish or improve upon their responsive strategies.</p>","content_html":"<p>\n\tA lot fo my work lately has been consulting and working with teams to help them to establish or improve upon their responsive strategies.</p>\n<p>\n\tI love this sort of work and I live for helping teams and individuals tackle the thorny issues (in code or processes) that make responsive projects a challenge. For a lot of small companies, it can be a challenge to pull ogether enough budget to fly me in for a few days of private working sessions, which is why I am such a huge fan of running public workshops… especially über-affordable ones like I am leading this May.</p>\n<p>\n\tThe first will be on my home turf in Chattanooga, Tennessee on May 2nd and I will be co-leadiing the workshop with my esteemed colleague <a href=\"http://bradfrostweb.com\">Brad Frost</a>. It’s the first workshop from our successful <a href=\"http://codeandcreativity.com\">Code & Creativity</a> event series and should be a heck of a lot of fun. There are a few tickets left for <a href=\"http://www.eventbrite.com/e/responsive-design-and-beyond-registration-11005454611\">$399 each on Eventbrite</a>.</p>\n<p>\n\tThe second workshop will be in Düsseldorf, Germany on May 21st. There are a handful of <a href=\"https://ti.to/beyondtellerrand/2014/\">tickets still available for €349 (VAT included)</a> and a ticket also gets you into the incredible <a href=\"http://2014.beyondtellerrand.com/\">Beyond Tellerrand</a> conference which runs on the 19th & 20th. I’ve spoken at this conference twice before and it is one of only a handful of events in the world I enthusiatically recommend attending.</p>\n<p>\n\tHere’s a rough idea of what I’ll be covering in the two workshops:</p>\n<blockquote>\n<p>\n\t\tResponsive web design has taken our industry by storm and with good reason: it helps us improve our reach with less effort. But incorporating responsive design is not the goal, meeting our user’s needs is. Responsive design is not an end in itself… it’s just the beginning.</p>\n<p>\n\t\tWe need to embrace the heterogenous nature of the web—myriad web-enabled devices with vastly different dimensions, screen sizes, networks, and capabilities in use by countless individuals, each with their own special needs—and craft experiences that will work anywhere at any time. We need to build robust systems that adapt in ways far beyond aesthetics.</p>\n<p>\n\t\tEach workshop with a discussion of a number of considerations that we should be aware of, beyond screen size and pixel density, and provide examples of how to adapt our interfaces so they rise to meet our customers’ needs. Then he’ll turn it over to you to propose gnarly design and/or interface challenges you are struggling with. Once everyone’s challenges are collected, attendees will be given the opportunity to form small groups around each and you will spend a portion of the day working on solutions while Aaron mentors each group and pushes you to think more about accessibility, alternate interaction methods, slow networks, and other considerations.</p>\n<p>\n\t\tThe workshop will wrap up with brief presentations from each group followed by a an open question and answer session.</p>\n</blockquote>\n<p>\n\tI hope you’ll join me in Chattanooga or Düsseldorf next month. Bring your questions and your challenges and let’s dig in.</p>\n","url":"https://www.aaron-gustafson.com/notebook/beyond-responsive-workshops-this-may/","tags":["responsive web design","conferences","presentations"],"date_published":"2014-04-15T14:39:00Z"},{"id":"https://www.aaron-gustafson.com/speaking-engagements/designing-across-devices-with-progressive-enhancement/","title":"📢 Designing Across Devices with Progressive Enhancement","summary":"<p>Today, browsers are just one of the issues among a sea of considerations like accessibility, device compatibility, and responsive or adaptive design. And with new techniques and devices coming out daily, it’s easy to feel overwhelmed.</p>","content_html":"<p>Remember the good old days when getting IE6 to “work” was our main worry?</p>\n<p>My, we’ve come a long way, baby.</p>\n<p>Today, browsers are just one of the issues among a sea of considerations like accessibility, device compatibility, and responsive or adaptive design. And with new techniques and devices coming out daily, it’s easy to feel overwhelmed.</p>\n<p>Fortunately, I know how to wrangle all of these elements using progressive enhancement. With his practical approach, he designs for humans on any spectrum ­­ with and without javascript enabled—and soon enough, you will, too.</p>\n<p>Create experiences without technological constraints</p>\n<ul>\n<li>Understand progressive enhancement and integrate it with your process</li>\n<li>Use content as your foundation and build the experience from there</li>\n</ul>\n<p>Stop assuming users are just like you</p>\n<ul>\n<li>Come to a better understanding of how existing design decisions can unintentionally skew your analytics</li>\n<li>Prevent the typical myopic view of web and mobile experiences</li>\n</ul>\n<p>Make a content­-first approach work</p>\n<ul>\n<li>Fuse responsive web design and mobile­-first with progressive enhancement</li>\n<li>Focus content, core tasks, and visual designs on a continuum</li>\n</ul>\n<p>Establish a solid strategy for planning</p>\n<ul>\n<li>Sketch different experiences using basic UI elements and flow charts</li>\n<li>Plan decision points and outcomes from simple through complex interactions</li>\n</ul>\n<p>Join us for this seminar if you:</p>\n<ul>\n<li>Need a manageable design process that works for your whole team</li>\n<li>Feel your sanity slipping away as more devices launch every. single. day.</li>\n<li>Want to plan, design, and test all potential experiences across platforms</li>\n</ul>\n<p>If you’re trying to create a better web ­­ and are open to rethinking how you approach designing for any interface, then you need to watch Aaron’s seminar.</p>\n","social_text":"Today, browsers are just one of the issues among a sea of considerations like accessibility, device compatibility, and responsive or adaptive design. And with new techniques and devices coming out daily, it’s easy to feel overwhelmed.","url":"https://www.aaron-gustafson.com/speaking-engagements/designing-across-devices-with-progressive-enhancement/","tags":["accessibility","inclusive design","mobile","progressive enhancement","responsive web design"],"image":"https://www.aaron-gustafson.com/undefined","date_published":"2013-11-21T17:30:00Z"},{"id":"https://www.aaron-gustafson.com/notebook/zoom-layouts-v2/","title":"✍🏻 Zoom Layouts v2","summary":"<p>\tSome of you might find it hard to believe, but I began working with adaptive layouts way back in 2005. I was working on project for the Connecticut Department of Transportation and my primary design made heavy use of fixed positioning and white space. Sadly this is the only screenshot I have of the now-defunct project:</p><figure style=\"max-width:320px\"><img alt=\"\" src=\"/i/posts/2013-09-16/drink-drive-lose-ad-challenge.png\"/></figure><p>\tThe layout really started to break down on smaller screens—we had quite a few 800x600 monitors to deal with back in the day—so, inspired by Joe Clark’s A List Apart article “<a href=\"http://alistapart.com/article/lowvision\">Big, Stark & Chunky</a>,” I created an alternate stylesheet that rearranged the page layout, enlarged the text, and improved the reading experience. Sadly, I don’t have a screenshot of what that looked like, but here’s a decent approximation (sans background images), courtesy of the Wayback Machine:</p>","content_html":"<p>\n\tSome of you might find it hard to believe, but I began working with adaptive layouts way back in 2005. I was working on project for the Connecticut Department of Transportation and my primary design made heavy use of fixed positioning and white space. Sadly this is the only screenshot I have of the now-defunct project:</p>\n<figure style=\"max-width:320px\">\n<img alt=\"\" src=\"/i/posts/2013-09-16/drink-drive-lose-ad-challenge.png\"/></figure>\n<p>\n\tThe layout really started to break down on smaller screens—we had quite a few 800x600 monitors to deal with back in the day—so, inspired by Joe Clark’s A List Apart article “<a href=\"http://alistapart.com/article/lowvision\">Big, Stark & Chunky</a>,” I created an alternate stylesheet that rearranged the page layout, enlarged the text, and improved the reading experience. Sadly, I don’t have a screenshot of what that looked like, but here’s a decent approximation (sans background images), courtesy of the Wayback Machine:</p>\n<figure>\n<img alt=\"\" src=\"/i/posts/2013-09-16/drink-drive-lose-ad-challenge-small.png\"/></figure>\n<p>\n\tWe didn’t have media queries in those days, so I relied on JavaScript to do the stylesheet switching. It was pretty good work for the time, but I see a <em>ton</em> of things I would do differently if I had the opportunity to revisit it.</p>\n<p>\n\tSo why am I bringing this up? Well, I remembered Joe’s article the other day and was thinking about how relevant it is in this, the age of responsive design. I think the idea of high-contrast zoom layouts is incredibly useful, but not just for mobile. When you start to think about the other end of the spectrum—giant high-definition televisions sitting 8-10 feet from your face—zoom layouts become really useful again.</p>\n<p>\n\tTo that end, I have been thinking quite a bit about <a href=\"http://css-tricks.com/viewport-sized-typography/\">the viewport-based units available to us in modern browsers</a> and how we can use them to create automated zoom layouts by simply increasing the font size of the <code>body</code> element. Consider this bit of code:</p>\n<pre class=\"css\"><code>\n@media screen and (min-width: 64em) {\n  body {\n    font-size: 1.5625vw;\n  }\n}\n</code></pre>\n<p>\n\tThis tiny bit of CSS can ensure that the entire layout is proportionately scaled up based on the screen size being used to access it. To figure out how this bit of code would fit best into your own work, use this formula (replace “X” with your max width size in ems):</p>\n<pre class=\"css\"><code>\n@media screen and (min-width: 64em) {\n  body {\n    font-size: 1.5625vw;\n  }\n}\n</code></pre>\n<p>\n\tThe site I developed this technique for is not live yet, so I threw together <a href=\"http://codepen.io/aarongustafson/pen/ojqtr\">a simple demo on Codepen</a>. <em>Note: Chrome currently requires a forced repaint on window resize to make it shrink or enlarge the layout. Hopefully <a href=\"https://code.google.com/p/chromium/issues/detail?id=124331\">that bug</a> will be fixed soon.</em></p>\n<p>\n\tI’m still feeling my way around this technique, but I am intrigued by the possibilities it holds. What do you think?</p>\n","url":"https://www.aaron-gustafson.com/notebook/zoom-layouts-v2/","tags":["responsive web design","CSS","accessibility"],"date_published":"2013-09-16T15:56:00Z"},{"id":"https://www.aaron-gustafson.com/speaking-engagements/responsive-design-studio/","title":"📢 Responsive Design Studio","summary":"<p>A deep dive into the implications of responsive design.</p>","content_html":"<p>A deep dive into the implications of responsive design.</p>\n","social_text":"A deep dive into the implications of responsive design.","url":"https://www.aaron-gustafson.com/speaking-engagements/responsive-design-studio/","tags":["accessibility","CSS","HTML","progressive enhancement","responsive web design"],"image":"https://www.aaron-gustafson.com/undefined","date_published":"2013-04-29T13:00:00Z"},{"id":"https://www.aaron-gustafson.com/speaking-engagements/the-real-responsive-process/","title":"📢 The Real Responsive Process?","summary":"<p>The web is not a fixed width. So if the medium is fluid, should the process be fixed?</p>","content_html":"<p>The web is not a fixed width. So if the medium is fluid, should the process be fixed? Fireworks and Photoshop are not flexible enough to demonstrate media queries, button and menu states, HTML5 and JavaScript behaviors, dynamic resizing of elements and navigation flow.</p>\n<p>Diving into responsive design projects can be daunting. Old design practices are cumbersome when thinking in terms of web systems that will span a wide variety of devices and dimensions. Four industry leaders will delve into how they handle the responsive process or how they don’t. A fluid process to match the fluidity of responsive design. Bam! We’ll also explore some of recent successes and failures while establishing why a responsive process is a responsible process.</p>\n<p>One web to rule them all?</p>\n","social_text":"The web is not a fixed width. So if the medium is fluid, should the process be fixed?","url":"https://www.aaron-gustafson.com/speaking-engagements/the-real-responsive-process/","tags":["responsive web design","web design"],"date_published":"2013-03-08T15:00:00Z"},{"id":"https://www.aaron-gustafson.com/notebook/responsive-tables/","title":"✍🏻 Responsive Tables","summary":"<p>A few smart folks have already put together their thoughts on responsive tables and, while I think the proposed methods are pretty good, I think there might be room for improvement. As such, I’ve been tinkering for a while and came up with the following strategy when it comes to tables.</p>","content_html":"<p>A few smart folks have already put together their thoughts on responsive tables and, while I think the proposed methods are pretty good, I think there might be room for improvement. As such, I’ve been tinkering for a while and came up with the following strategy when it comes to tables.</p>\n<p><strong>Step 1:</strong> Use <code class=\"html\">data-*</code> attributes to hold information about the column header(s) associated with the markup:</p>\n```html\n  <table>\n   <thead>\n   <tr>\n   <th scope=\"col\">Name</th>\n   <th scope=\"col\">Email</th>\n   <th scope=\"col\">Dept, Title</th>\n   <th scope=\"col\">Phone</th>\n   </tr>\n   </thead>\n   <tbody>\n   <tr class=\"vcard\">\n   <th scope=\"row\" class=\"n\" data-title=\"Name\">\n   <b class=\"family-name\">Smith</b>,\n   <b class=\"given-name\">Laura</b>\n   </th>\n   <td data-title=\"Email\">\n   <a class=\"email\" href=\"mailto:laura.smith@domain.com\">laura.smith@domain.com</a>\n   </td>\n   <td data-title=\"Dept, Title\">Biology, Director</td>\n   <td class=\"tel\" data-title=\"Phone\">\n   <a href=\"tel:+1123456789\">123-456-789</a>\n   </td>\n   </tr>\n   <tr class=\"vcard\">\n   <th scope=\"row\" class=\"n\" data-title=\"Name\">\n   <b class=\"family-name\">Johnson</b>,\n   <b class=\"given-name\">Ron</b>\n   </th>\n   <td data-title=\"Email\">\n   <a class=\"email\" href=\"mailto:ron.johnson@domain.com\">ron.johnson@domain.com</a>\n   </td>\n   <td data-title=\"Dept, Title\">Purchasing, Director</td>\n   <td class=\"tel\" data-title=\"Phone\">\n   <a href=\"tel:+11234567891\">123-456-7891</a>\n   </td>\n   </tr>\n   </tbody>\n  </table>\n```\n<p><strong>Step 2:</strong> When the screen is below a certain threshold, set the <code class=\"html\">table</code> elements to <code class=\"html\">display: block</code> (thereby linearizing the table), hide the <code class=\"html\">thead</code> where assistive tech won’t see it, and use generated content to expose the <code class=\"html\">data-*</code> attributes. Here’s a snippet of SASS & Compass that does that:</p>\n```scss\n  // undo tables for small screens\n  // $break-4 is the px-width break at which you want to cut it off\n  @media (max-width: px-to-ems($break-4 - 1px)) {\n<p>// make each table separate from other ones\ntable {</p>\n<p>border: 0;\n@include trailing-border;\npadding-bottom: 0;\ndisplay: block;\nwidth: 100%;</p>\n<p>// make sure captions are displayed\ncaption {\ndisplay: block;\n}</p>\n<p>/*\n* wipe the thead from the face of the earth\n* modern screen readers will expose the\n* generated content\n*/\nthead {\ndisplay: none;\nvisibility: hidden;\n}</p>\n<p>/*\n* make everything display block so it\n* aligns vertically\n*/\ntbody, tr, th, td {\nborder: 0;\ndisplay: block;\npadding: 0;\ntext-align: left;\nwhite-space: normal;\n}</p>\n<p>// give each row a little space\ntr {\n@include trailer;\n}</p>\n<p>/* Labeling\n* adding a data-title attribute to the cells\n* lets us add text before the content to provide\n* the missing context\n*\n* Markup:\n*   <td data-title=\"Column Header\">Content Here</td>\n*\n* Display:\n*   Column Header: Content Here\n*/\nth[data-title]:before,\ntd[data-title]:before {\ncontent: attr(data-title) “:\\00A0”;\nfont-weight: bold;\n}\nth:not([data-title]) {\nfont-weight: bold;\n}</p>\n<p>// hide empty cells\ntd:empty {\ndisplay: none;\n}\n}\n}</p>\n<pre><code>&lt;p&gt;We’ve been using this approach on a number of sites currently in development and it works really well. I put together &lt;a href=&quot;http://codepen.io/aarongustafson/pen/ucJGv&quot;&gt;a demo of this technique&lt;/a&gt; so you could play around with it yourself.&lt;/p&gt;\n&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;/p&gt;\n&lt;ol&gt;\n&lt;li&gt;I chose to use a &lt;code class=&quot;html&quot;&gt;data-*&lt;/code&gt; attribute (&lt;code class=&quot;html&quot;&gt;data-title&lt;/code&gt;) instead of &lt;code class=&quot;html&quot;&gt;title&lt;/code&gt; as the &lt;code class=&quot;html&quot;&gt;title&lt;/code&gt; attribute could be read out by assistive technology and in the case of the &lt;code class=&quot;html&quot;&gt;thead&lt;/code&gt; being available as well (when not &lt;code class=&quot;html&quot;&gt;display: none&lt;/code&gt;), resulting in the information being read twice (which is not ideal). &lt;a href=&quot;http://www.paciellogroup.com/resources/articles/WE05/#slide9&quot;&gt;That’s not a certainty however&lt;/a&gt;, so you could choose to go the &lt;code class=&quot;html&quot;&gt;title&lt;/code&gt; route if that’s your preference. I prefer to avoid the potential issue.&lt;/li&gt;\n&lt;li&gt;If you have multiple header rows over a cell (say a parent row and then a child row), I’d recommend making the &lt;code class=&quot;html&quot;&gt;data-title&lt;/code&gt; something like “Parent Header - Child Header.&lt;span class=&quot;final quote&quot;&gt;”&lt;/span&gt;&lt;/li&gt;\n&lt;li&gt;While you could use JavaScript to auto-generate the &lt;code class=&quot;html&quot;&gt;data-title&lt;/code&gt; attributes by referencing the column headers, I feel this is information that should exist even if JavaScript is not available. You may disagree.&lt;/li&gt;\n&lt;/ol&gt;\n</code></pre>\n","url":"https://www.aaron-gustafson.com/notebook/responsive-tables/","tags":["responsive web design","HTML","accessibility"],"date_published":"2013-02-02T17:32:27Z"}]}