<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

    <channel>

    <title><![CDATA[A List Apart: The Full Feed]]></title>
    <link>https://alistapart.com</link>
    <description>Articles for people who make web sites.</description>
    <dc:language>en</dc:language>
    <dc:creator>The fine folks at A List Apart</dc:creator>
    <dc:rights>Copyright 2019</dc:rights>
    <dc:date>2019-04-04T13:14:00+00:00</dc:date>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/alistapart/main" /><feedburner:info uri="alistapart/main" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title><![CDATA[Accessibility for Vestibular Disorders: How My Temporary Disability Changed My Perspective]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/facundocorradini">Facundo Corradini</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/Zw7tx-r5WA0/accessibility-for-vestibular</link>
      <guid isPermaLink="false">http://alistapart.com/article/accessibility-for-vestibular</guid>
      <description>&lt;p&gt;Accessibility can be tricky. There are plenty of conditions to take into consideration, and many technical limitations and weird exceptions that make it quite hard to master for most designers and developers. &lt;/p&gt;

&lt;p&gt;I never considered myself an accessibility &lt;em&gt;expert&lt;/em&gt;, but I took great pride in making my projects Web Content Accessibility Guidelines (WCAG) compliant…ish. They would pass most automated tests, show perfectly in the accessibility tree, and work quite well with keyboard navigation. I would even try (and fail) to use a screen reader every now and then.&lt;/p&gt;

&lt;p&gt;But life would give me a lesson I would probably never learn otherwise: last October, my &lt;em&gt;abled&lt;/em&gt; life took a drastic change—I started to feel extremely dizzy, with a constant sensation of falling or spinning to the right. I was suffering from a bad case of vertigo caused by labyrinthitis that made it impossible to get &lt;em&gt;anything&lt;/em&gt; done. &lt;/p&gt;

&lt;p&gt;Vertigo can have a wide range of causes, the most common being a viral infection or tiny calcium crystal free floating in the inner ear, which is pretty much our body’s accelerometer. Any disruption in there sends the brain confusing signals about the body’s position, which causes really heavy nausea, dizziness, and headaches. If you’ve ever felt seasick, it’s quite a similar vibe. If not, think about that feeling when you just get off a rollercoaster…it’s like that, only &lt;em&gt;all day long&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For most people, &lt;a href="https://vestibular.org/understanding-vestibular-disorders/types-vestibular-disorders/benign-paroxysmal-positional-vertigo"&gt;vertigo is something they’ll suffer just once in a lifetime&lt;/a&gt;, and it normally goes away in a week or two. Incidence is really high, with some estimates claiming that up to 40% of the population suffers vertigo at least once in their lifetime. Some people live all their lives with it (or with similar symptoms caused by a range of diseases and syndromes grouped under the umbrella term of &lt;i&gt;vestibular disorders&lt;/i&gt;), with 4% of US adults reporting chronic problems with balance, and an additional 1.1% reporting chronic dizziness, &lt;a href="https://www.asha.org/PRPSpecificTopic.aspx?folderid=8589942134&amp;amp;section=Incidence_and_Prevalence"&gt;according to the American Speech-Language-Hearing Association&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In my case, it was a little over a month. Here’s what I learned while going through it.&lt;/p&gt;

&lt;h2&gt;Slants can trigger vestibular symptoms&lt;/h2&gt;

&lt;p&gt;It all started as I was out for my daily jog. I felt slightly dizzy, then suddenly my vision got totally distorted. Everything appeared further away, like looking at a fun house’s distortion mirror. I stumbled back home and rested; at that moment I believed I might have over-exercised, and that hydration, food, and rest were all I needed. Time would prove me wrong.&lt;/p&gt;

&lt;p&gt;What I later learned was that experiencing vertigo is a constant war between one of your inner ears telling the brain “everything is fine, we’re level and still” and the other ear shouting “oh my God, we’re falling, we&amp;#8217;re falling!!!” Visual stimuli can act as an intermediary, supporting one ear’s message or the other’s. Vertigo can also work in the opposite way, with the dizziness interfering with your vision. &lt;/p&gt;

&lt;p&gt;I quickly found that when symptoms peaked, staring at a distant object would ease the falling sensation &lt;em&gt;somewhat&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the same fashion, some visual stimuli would worsen it.&lt;/p&gt;

&lt;p&gt;Vertical slants were a big offender in that sense. For instance, looking at a subtle vertical slant (the kind that you’d have to look at twice to make sure it’s not perfectly vertical) on a webpage would instantly trigger symptoms for me. Whether it was a page-long slant used to create some interest beside text or a tiny decoration to mark active tabs, looking at anything with slight slants would instantly send me into the rollercoaster. &lt;/p&gt;

&lt;p&gt;Horizontal slants (whatever the degree) and harder vertical slants wouldn’t cause these issues. &lt;/p&gt;

&lt;p&gt;My best guess is that slight vertical slants can look like forced perspective and therefore reinforce the falling-from-height sensation, so I would recommend avoiding vertical slants if you can, or make them super obvious. A slight slant looks like perspective, a harder one looks like a triangle.&lt;/p&gt;

&lt;h2&gt;Target size matters (even on mouse-assisted devices)&lt;/h2&gt;

&lt;p&gt;After a magnetic resonance imaging (MRI) scan, some tests to discard neurological conditions, and other treatments that proved ineffective, I was prescribed Cinnarizine. &lt;/p&gt;

&lt;p&gt;Cinnarizine is a calcium channel blocker—to put it simply, it prevents the malfunctioning inner ear “accelerometer” from sending incorrect info to the brain. &lt;br /&gt;
And it worked wonders. After ten days of being barely able to get out of bed, I was finally getting something closer to my normal life. I would still feel dizzy all the time, with some peaks throughout the day, but for the most part, it was much easier. &lt;/p&gt;

&lt;p&gt;At this point, I was finally able to use the computer (but still unable to produce any code at all). To make the best of it, I set on a mission to self-experiment on accessibility for vestibular disorders. In testing, I found that one of the first things that struck me was that I would always miss targets (links and buttons).&lt;/p&gt;

&lt;p&gt;I’m from the generation that grew up with desktop computers, so using a mouse is second nature. The pointer is pretty much an extension of my mind, as it is for many who use it regularly. But while Cinnarizine helped with the dizziness, it has a common side effect of negatively impacting coordination and fine motor skills (it is recommended not to drive or operate machinery while under treatment). It was not a surprise when I realized it would be much harder to get the pointer to do what I intended. &lt;/p&gt;

&lt;p&gt;The common behavior would be: moving the pointer past the link I intended to click, clicking before reaching it at all, or having to try multiple times to click on smaller targets. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/WAI/WCAG21/Understanding/target-size.html"&gt;Success Criterion 2.5.5 Target Size (Level AAA)&lt;/a&gt; of the World Wide Web Consortium (W3C)’s WCAG recommends bigger target sizes so users can activate them easily. The obvious reason for this is that it’s harder to pinpoint targets on smaller screens with coarser inputs (i.e., touchscreens of mobile devices). A fairly common practice for developers is to set bigger target sizes for smaller viewport widths (assuming that control challenges are only touch-related), while neglecting the issue on big screens expected to be used with mouse input. I know I’m guilty of that myself.&lt;/p&gt;

&lt;p&gt;Instead of targeting this behavior for just smaller screen sizes, there are plenty of reasons to create larger target sizes on &lt;em&gt;all&lt;/em&gt; devices: it will benefit users with limited vision (when text is scaled up accordingly and colors are of sufficient contrast), users with mobility impairments such as hand tremors, and of course, users with difficulty with fine motor skills.&lt;/p&gt;

&lt;h2&gt;Font size and spacing&lt;/h2&gt;

&lt;p&gt;Even while “enjoying” the ease of symptoms provided by the treatment, reading &lt;em&gt;anything&lt;/em&gt; still proved to be a challenge for the following three weeks.&lt;/p&gt;

&lt;p&gt;I was completely unable to use mobile devices while suffering vertigo due to the smaller font sizes and spacing, so I was forced to use my desktop computer for everything. &lt;/p&gt;

&lt;p&gt;I can say I was experiencing something similar to users with mild forms of dyslexia or attention disorders: whenever I got to a website that didn’t follow good font styling, I would find myself reading the same line over and over again.&lt;/p&gt;

&lt;p&gt;This proves once again that accessibility is intersectional: when we improve things for a particular purpose it usually benefits users with other challenges as well. I used to believe recommendations on font styles were mostly intended for the nearsighted and those who have dyslexia. Turns out they are also critical for those with vertigo, and even for those with some cognitive differences. At the end of the day, everybody benefits from better readability. &lt;/p&gt;

&lt;p&gt;Some actions you can take to improve readability are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep line height to at least 1.5 times the font size (i.e., &lt;code&gt;line-height: 1.5&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Set the spacing between paragraphs to at least 2.0 times the font size. We can do this by adjusting the margins using relative units such as &lt;code&gt;em&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Letter spacing should be at least 0.12 times the font size. We can adjust this by using the &lt;code&gt;letter-spacing&lt;/code&gt; CSS property, perhaps setting it in a relative unit.&lt;/li&gt;
&lt;li&gt;Make sure to have good contrast between text and its background.&lt;/li&gt;
&lt;li&gt;Keep &lt;code&gt;font-weight&lt;/code&gt; at a reasonable level for the given &lt;code&gt;font-family&lt;/code&gt;. Some fonts have thin strokes that make them harder to read. When using thinner fonts, try to improve contrast and font size accordingly, even more than what WCAG would suggest.&lt;/li&gt;
&lt;li&gt;Choose fonts that are easy to read. There has been a large and still inconclusive debate on which font styles are better for users, but one thing I can say for sure is that popular fonts (as in fonts that the user might be already familiar with) are generally the least challenging for users with reading issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/WAI/WCAG21/Understanding/text-spacing.html"&gt;WCAG recommendations on text are fairly clear&lt;/a&gt; and fortunately are the most commonly implemented of recommendations, but even they can still fall short sometimes. So, better to follow &lt;a href="http://adrianroselli.com/2015/03/typefaces-for-dyslexia.html#Tips"&gt;specific guides on accessible text&lt;/a&gt; and your best judgement. &lt;a href="https://www.smashingmagazine.com/2018/09/importance-manual-accessibility-testing/"&gt;Passing automated tests does not guarantee actual accessibility.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another issue on which my experience with vertigo proved to be similar to that of people with dyslexia and attention disorders was how hard it was for me to keep my attention in just one place. In that sense&amp;#8230;&lt;/p&gt;

&lt;h2&gt;Animations are bad (and parallax is pure evil)&lt;/h2&gt;

&lt;p&gt;Val Head has already covered &lt;a href="https://alistapart.com/article/designing-safer-web-animation-for-motion-sensitivity"&gt;visually-triggered vestibular disorders&lt;/a&gt; in an outstanding article, so I would recommend giving it a good read if you haven’t already.&lt;/p&gt;

&lt;p&gt;To summarize, animations can trigger nausea, dizziness, and headaches in some users, so we should use them purposely and responsibly. &lt;/p&gt;

&lt;p&gt;While most animations did not trigger my symptoms, parallax scrolling did. I’d never been a fan of parallax to begin with, as I found it confusing. And when you’re experiencing vertigo, the issues introduced by parallax scrolling compound. &lt;/p&gt;

&lt;p&gt;Really, there are no words to describe just how bad a simple parallax effect, scrolljacking, or even &lt;code&gt;background-attachment: fixed&lt;/code&gt; would make me feel. I would rather jump on one of those 20-G centrifuges astronauts use than look at a website with parallax scrolling.&lt;/p&gt;

&lt;p&gt;Every time I encountered it, I would put the bucket beside me to good use and be forced to lie in bed for &lt;em&gt;hours&lt;/em&gt; as I felt the room spinning around me, and no meds could get me out of it. It was &lt;em&gt;THAT&lt;/em&gt; bad.&lt;/p&gt;

&lt;p&gt;Though normal animations did not trigger a reaction as severe, they still posed a big problem. The extreme, conscious, focused effort it took to read would make it such that anything moving on the screen would instantly break my focus, and force me to start the paragraph all over. And I mean &lt;em&gt;anything&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;I would constantly find myself reading a website only to have the typical collapsing navigation bar on scroll distract me just enough that I’d totally lose count of where I was at. Autoplaying carousels were &lt;em&gt;so&lt;/em&gt; annoying I would delete them using dev tools as soon as they showed up. Background videos would make me get out of the website desperately.&lt;/p&gt;

&lt;p&gt;Over time I started using mouse selection as a pointer; a visual indication of what I’d already read so I could get back to it whenever something distracted me. Then I tried custom stylesheets to disable transforms and animations whenever possible, but that also meant many websites having critical elements not appear at all, as they were implemented to start off-screen or otherwise invisible, and show up on scroll. &lt;/p&gt;

&lt;p&gt;Of course, deleting stuff via dev tools or using custom stylesheets is not something we can expect 99.99% of our users to even know about. &lt;/p&gt;

&lt;p&gt;So if anything, consider reducing animations to a minimum. Provide users with controls to turn off non-essential animations (&lt;a href="https://www.w3.org/WAI/WCAG21/Understanding/animation-from-interactions.html"&gt;WCAG 2.2.3 Animation from Interactions&lt;/a&gt;) and to pause, stop, or hide them (&lt;a href="https://www.w3.org/WAI/WCAG21/Understanding/pause-stop-hide.html"&gt;WCAG 2.2.2 Pause, Stop, Hide&lt;/a&gt;). Implement animations and transitions in such a way that if the user disables them, critical elements still display.&lt;/p&gt;

&lt;p&gt;And be extra careful with parallax: my recommendation is to, at the very least, try limiting its use to the header (“hero”) only, and be mindful of getting a smooth, realistic parallax experience. My vertigo self would have said, “&lt;em&gt;just don’t freaking use parallax. Never. EVER.&lt;/em&gt;” But I guess that might be a hard idea to sell to stakeholders and designers.&lt;/p&gt;

&lt;p&gt;Also consider learning how to use the &lt;code&gt;prefers-reduced-motion&lt;/code&gt; feature query. This is a newer addition to the specs (it’s part of the &lt;a href="https://drafts.csswg.org/mediaqueries-5/#descdef-media-prefers-reduced-motion"&gt;Media Queries Level 5 module&lt;/a&gt; , which is at an early Editor’s Draft stage) that allows authors to apply selective styling depending on whether the user has requested the system to minimize the use of animations. &lt;a href="https://caniuse.com/#search=prefers-reduced-motion"&gt;OS and browser support for it is still quite limited&lt;/a&gt;, but the day will come when we will set any moving thing inside a query for when the user has &lt;code&gt;no-preference&lt;/code&gt;, blocking animations from those who choose &lt;code&gt;reduce&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After about a week of wrestling websites to provide a static experience, I remembered something that would prove to be my biggest ally while the vertigo lasted: &lt;/p&gt;

&lt;h2&gt;Reader mode&lt;/h2&gt;

&lt;p&gt;Some browsers include a “reader mode” that strips the content from any styling choices, isolates it from any distraction, and provides a perfect WCAG compliant layout for the text to maximize readability. &lt;/p&gt;

&lt;p&gt;It is extremely helpful to provide a clear and consistent reading experience throughout multiple websites, especially for users with any kind of reading impairment. &lt;/p&gt;

&lt;p&gt;I have to confess: before experiencing my vestibular disorder, I had never used Reader Mode (the formal name varies in browsers) or even checked if my projects were compatible with it. I didn’t even think it was such a useful feature, as a quick search for “reader mode” actually returned quite a few threads by users asking how to disable it or how to take the button for it out of Firefox’s address bar. (It seems some people are unwittingly activating it…perhaps the icon is not clear enough.)&lt;/p&gt;

&lt;p&gt;Displaying the button to access Reader Mode is toggled by browser heuristics, which are based on the use (or not) of semantic tags in a page’s HTML. Unfortunately this meant not all websites provided such a “luxury.” &lt;/p&gt;

&lt;p&gt;I really wish I wouldn’t have to say this in 2019…but please, &lt;em&gt;please&lt;/em&gt; use semantic tags. Correct &lt;a href="https://alistapart.com/article/conversational-semantics"&gt;conversational semantics&lt;/a&gt; allow your website to be displayed in Reader Mode, and provide a better experience for users of screen readers. Again, accessibility is intersectional.&lt;/p&gt;

&lt;p&gt;Reader Mode proved to be extremely useful while my vertigo lasted. But there was something even better: &lt;/p&gt;

&lt;h2&gt;Dark color schemes&lt;/h2&gt;

&lt;p&gt;By the fourth week, I started feeling mostly fine. I opened Visual Studio Code to &lt;em&gt;try&lt;/em&gt; to get back to work. In doing so, it served me well to find one more revelation: a light-text-on-dark-background scheme was SO much easier for me to read. (Though I still was not able to return to work at this time.)&lt;/p&gt;

&lt;p&gt;I was quite surprised, as I had always preferred light mode with dark-text-on-light-background for reading, and dark mode, with light-text-on-dark for coding. I didn’t know at the time that I was suffering from &lt;i&gt;photophobia&lt;/i&gt; (which is a sensitivity to light), which was one of the reasons I found it hard to read on my desktop and to use my mobile device at all.&lt;/p&gt;

&lt;p&gt;As far as I know, photophobia is not a common symptom of &lt;i&gt;vestibular disorders&lt;/i&gt;, but there are many conditions that will trigger it, so it’s worth looking into for our projects’ accessibility. &lt;/p&gt;

&lt;p&gt;CSS is also planning a media query to switch color schemes. Known as &lt;code&gt;prefers-color-scheme&lt;/code&gt;, it allows applying styles based on the user’s stated preference for dark or light theming. It’s also part of the Media Queries Level 5 spec, and at the time of writing this article &lt;a href="https://caniuse.com/#search=prefers-color-scheme"&gt;it’s only available in Safari Technology Preview&lt;/a&gt;, with Mozilla planning to ship it in the upcoming Firefox 67. Luckily there’s a &lt;a href="https://github.com/csstools/css-prefers-color-scheme/blob/HEAD/README-POSTCSS.md"&gt;PostCSS plugin&lt;/a&gt; that allows us to use it in most modern browsers by turning &lt;code&gt;prefers-color-scheme&lt;/code&gt; queries into &lt;code&gt;color-index&lt;/code&gt; queries, which have much better support.&lt;/p&gt;

&lt;p&gt;If PostCSS is not your cup of tea, or for whatever reason you cannot use that approach to automate switching color schemes to a user’s preference, try at least to provide a theming option in your app’s configuration. Theming has become extremely simple since the release of CSS Custom Properties, so implementing this sort of switch is relatively easy and will greatly benefit anyone experiencing photophobia.&lt;/p&gt;

&lt;h2&gt;Moving on&lt;/h2&gt;

&lt;p&gt;After a month and some days, the vertigo disappeared completely, and I was able to return to work without needing any meds or further treatment. It should stay that way, as for most people it’s a once-in-a-lifetime occurrence. &lt;/p&gt;

&lt;p&gt;I went back to my &lt;em&gt;abled&lt;/em&gt; life, but the experience changed my mindset for good.&lt;/p&gt;

&lt;p&gt;As I said before, I always cared for making my projects compatible for people using keyboard navigation and screen readers. But I learned the hard way that there are plenty of “invisible conditions” that are just as important to take into consideration: vestibular disorders, &lt;a href="https://alistapart.com/article/designing-for-cognitive-differences"&gt;cognitive differences&lt;/a&gt;, dyslexia, and color blindness, just to name a few. I was totally neglecting those most of the time, barely addressing the issues in order to pass automated tests, which means I was unintentionally annoying some users by making websites inaccessible to them.&lt;/p&gt;

&lt;p&gt;After my experience with vertigo, I’ve turned to an &lt;a href="https://www.24a11y.com/2017/accessibility-first/"&gt;accessibility-first approach to design and development&lt;/a&gt;. Now I ask myself, “am I leaving anyone behind with this decision?,” before dropping a single line of code. Accessibility should never be an afterthought.&lt;/p&gt;

&lt;p&gt;Making sure my projects work from the start for those with difficulties also improves the experience for everyone else. Think about how improving text styles for users with dyslexia, vertigo, or visual problems improves readability for all users, or how being able to control animations or choose a color scheme can be critical for users with attention disorders and photophobia, respectively, while also a nice feature for everybody.&lt;/p&gt;

&lt;p&gt;It also turned my workflow into a much smoother development experience, as addressing accessibility issues from the beginning can mean a slower start, but it’s also much easier and faster than trying to fix broken accessibility afterwards.&lt;/p&gt;

&lt;p&gt;I hope that by sharing my personal experience with vertigo, I’ve illustrated how we can all design and develop a better web for everybody. Remember, &lt;a href="https://uxmag.com/articles/we-re-just-temporarily-abled"&gt;we’re all just temporarily abled&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/Zw7tx-r5WA0" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[User Experience, Accessibility
]]></dc:subject>
      <dc:date>2019-04-04T13:14:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/accessibility-for-vestibular</feedburner:origLink></item><item>
      <title><![CDATA[Responsible JavaScript: Part I]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/jeremy-wagner">Jeremy Wagner</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/No8RYIWCyvQ/responsible-javascript-part-1</link>
      <guid isPermaLink="false">http://alistapart.com/article/responsible-javascript-part-1</guid>
      <description>&lt;p&gt;By the numbers, &lt;a rel="noopener" href="https://httparchive.org/reports/state-of-javascript#bytesJs"&gt;JavaScript is a performance liability&lt;/a&gt;. If the trend persists, the median page will be shipping at least 400 KB of it before too long, and that’s merely what’s &lt;em&gt;transferred&lt;/em&gt;. Like other text-based resources, JavaScript is almost always served compressed—but that might be the only thing we’re getting consistently right in its delivery.&lt;/p&gt;

&lt;p&gt;Unfortunately, while reducing resource transfer time is a big part of that whole performance thing, compression has no effect on how long browsers take to process a script once it arrives in its entirety. If a server sends 400 KB of compressed JavaScript, the actual amount browsers have to process after decompression is north of a megabyte. How well devices cope with these heavy workloads depends, well, on the &lt;em&gt;device&lt;/em&gt;. &lt;a rel="noopener" href="https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4"&gt;Much has been written&lt;/a&gt; about how adept various devices are at processing lots of JavaScript, but the truth is, the amount of time it takes to process even a trivial amount of it varies greatly between devices.&lt;/p&gt;

&lt;p&gt;Take, for example, this &lt;a rel="noopener" href="https://devmode.jeremy.codes/"&gt;throwaway project of mine&lt;/a&gt;, which serves around 23 KB of uncompressed JavaScript. On a mid-2017 MacBook Pro, Chrome chews through this comparably tiny payload in about 25 ms. On a &lt;a rel="noopener" href="https://www.gsmarena.com/nokia_2-8513.php"&gt;Nokia 2 Android phone&lt;/a&gt;, however, that figure balloons to around 190 ms. That’s not an insignificant amount of time, but in either case, the page gets interactive reasonably fast.&lt;/p&gt;

&lt;p&gt;Now for the big question: how do you think that little Nokia 2 does on an average page? It chokes. Even on a fast connection, browsing the web on it is an exercise in patience as JavaScript-laden web pages brick it for considerable stretches of time.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/responsible-javascript-part-1/fig-01.png" alt="A performance timeline for a JavaScript-heavy website. Most of the timeline is JavaScript."&gt;
&lt;figcaption&gt;Figure 1. A performance timeline overview of a Nokia 2 Android phone browsing on a page where excessive JavaScript monopolizes the main thread.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;While devices and the networks they navigate the web on are largely improving, we’re eating those gains as trends suggest. We need to use JavaScript &lt;em&gt;responsibly&lt;/em&gt;. That begins with understanding &lt;em&gt;what&lt;/em&gt; we’re building as well as &lt;em&gt;how&lt;/em&gt; we’re building it.&lt;/p&gt;

&lt;h2&gt;The mindset of “sites” versus “apps”&lt;/h2&gt;

&lt;p&gt;Nomenclature can be strange in that we sometimes loosely identify things with terms that are inaccurate, yet their meanings are implicitly understood by everyone. Sometimes we overload the term “bee” to also mean “wasp”, even though the differences between bees and wasps are substantial. Those differences can motivate you to deal with each one differently. For instance, we’ll want to destroy a wasp nest, but because bees are highly beneficial and vulnerable insects, we may opt to relocate them.&lt;/p&gt;

&lt;p&gt;We can be just as fast and loose in interchanging the terms “website” and “web app”. The differences between them are less clear than those between yellowjackets and honeybees, but conflating them can bring about painful outcomes. The pain comes in the affordances we allow ourselves when something is merely a “web&lt;em&gt;site&lt;/em&gt;” versus a fully-featured “web app.” If you’re making an informational website for a business, you’re less likely to lean on a powerful framework to manage changes in the DOM or implement client-side routing—at least, I &lt;em&gt;hope&lt;/em&gt;. Using tools so ill-suited for the task would not only be a detriment to the people who use that site but arguably less productive.&lt;/p&gt;

&lt;p&gt;When we build a web &lt;em&gt;app&lt;/em&gt;, though, &lt;em&gt;look out&lt;/em&gt;. We’re installing packages which usher in hundreds—if not &lt;em&gt;thousands&lt;/em&gt;—of dependencies, &lt;a rel="noopener" href="https://snyk.io/blog/malicious-code-found-in-npm-package-event-stream/"&gt;some of which&lt;/a&gt; we’re not sure are even safe. We’re also writing complicated configurations for module bundlers. In this frenzied, yet ubiquitous, sort of dev environment, it takes knowledge and vigilance to ensure what gets built is fast and accessible. If you doubt this, run &lt;a rel="noopener" href="https://docs.npmjs.com/cli/ls.html#prod--production"&gt;&lt;code&gt;npm ls --prod&lt;/code&gt;&lt;/a&gt; in your project’s root directory and &lt;a rel="noopener" href="https://gist.github.com/malchata/dae0a011033846e2cb44d315b0496f0d"&gt;see if you recognize everything in that list&lt;/a&gt;. Even if you do, that doesn’t account for third party scripts—of which I’m sure your site has at least a few.&lt;/p&gt;

&lt;p&gt;What we tend to forget is that the environment websites and web apps occupy is one and the same. Both are subject to the &lt;em&gt;same environmental pressures&lt;/em&gt; that the large gradient of networks and devices impose. Those constraints don’t suddenly vanish when we decide to call what we build “apps”, nor do our users’ phones gain magical new powers when we do so.&lt;/p&gt;

&lt;p&gt;It’s our responsibility to evaluate who uses what we make, and accept that the conditions under which they access the internet can be different than what we’ve assumed. We need to know the purpose we’re trying to serve, and only &lt;em&gt;then&lt;/em&gt; can we build something that admirably serves that purpose—&lt;a rel="noopener" href="https://css-tricks.com/simple-boring/"&gt;even if it isn’t exciting to build&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That means reassessing our reliance on JavaScript and how the use of it—particularly to the exclusion of HTML and CSS—can tempt us to adopt unsustainable patterns which harm performance and accessibility.&lt;/p&gt;

&lt;h2&gt;Don’t let frameworks force you into unsustainable patterns&lt;/h2&gt;

&lt;p&gt;I’ve been witness to some strange discoveries in codebases when working with teams that depend on frameworks to help them be highly productive. One characteristic common among many of them is that poor accessibility and performance patterns often result. Take the React component below, for example:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;import React, { Component } from "react";
import { validateEmail } from "helpers/validation";

class SignupForm extends Component {
  constructor (props) {
    this.handleSubmit = this.handleSubmit.bind(this);
    this.updateEmail = this.updateEmail.bind(this);
    this.state.email = "";
  }

  updateEmail (event) {
    this.setState({
      email: event.target.value
    });
  }

  handleSubmit () {
    // If the email checks out, submit
    if (validateEmail(this.state.email)) {
      // ...
    }
  }

  render () {
    return (
      &amp;lt;div&amp;gt;
        &amp;lt;span class="email-label"&amp;gt;Enter your email:&amp;lt;/span&amp;gt;
        &amp;lt;input type="text" id="email" onChange={this.updateEmail} /&amp;gt;
        &amp;lt;button onClick={this.handleSubmit}&amp;gt;Sign Up&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are some notable accessibility issues here:&lt;/p&gt;

&lt;ol type="1"&gt;
&lt;li&gt;A form that doesn’t use a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element is &lt;em&gt;not&lt;/em&gt; a form. Indeed, you could paper over this by specifying &lt;a rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Form_Role"&gt;&lt;code&gt;role="form"&lt;/code&gt;&lt;/a&gt; in the parent &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, but if you’re building a form—and this &lt;em&gt;sure looks like one&lt;/em&gt;—use a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element with the proper &lt;code&gt;action&lt;/code&gt; and &lt;code&gt;method&lt;/code&gt; attributes. The &lt;code&gt;action&lt;/code&gt; attribute is crucial, as it ensures the form will still do &lt;em&gt;something&lt;/em&gt; in the absence of JavaScript—provided the component is server-rendered, of course.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; is not a substitute for a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; element, which provides accessibility benefits &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;s don’t.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; without &lt;code&gt;type="submit"&lt;/code&gt; is just a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; that only does what’s bound to it. If we intend to do something prior to submitting a form, then we should add &lt;code&gt;type="submit"&lt;/code&gt; and move the action bound to the &lt;code&gt;onClick&lt;/code&gt; handler to the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element’s &lt;code&gt;onSubmit&lt;/code&gt; handler.&lt;/li&gt;
&lt;li&gt;Incidentally, why use JavaScript to validate an email address when HTML5 offers form validation controls in almost every browser back to IE 10? There’s an opportunity here to rely on the browser and use an &lt;a rel="noopener" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email"&gt;appropriate input type&lt;/a&gt;, as well as the &lt;a rel="noopener" href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation#The_required_attribute"&gt;&lt;code&gt;required&lt;/code&gt;&lt;/a&gt; attribute—but be aware that getting this to work right with screen readers &lt;a rel="noopener" href="https://developer.paciellogroup.com/blog/2019/02/required-attribute-requirements/"&gt;takes a little know-how&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Knowing these things, we can refactor this component:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;import React, { Component } from "react";

class SignupForm extends Component {
  constructor (props) {
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit (event) {
    // Needed in case we're sending data to the server XHR-style
    // (but will still work if server-rendered with JS disabled).
    event.preventDefault();

    // Carry on&amp;#8230;
  }

  render () {
    return (
      &amp;lt;form method="POST" action="/signup" onSubmit={this.handleSubmit}&amp;gt;
        &amp;lt;label for="email" class="email-label"&amp;gt;Enter your email:&amp;lt;/label&amp;gt;
        &amp;lt;input type="email" id="email" required /&amp;gt;
        &amp;lt;button type="submit"&amp;gt;Sign Up&amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;
    );
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not only is this component now more accessible, but it also uses less JavaScript. In a world that’s drowning in JavaScript, deleting lines of it should feel downright therapeutic. &lt;a rel="noopener" href="https://alistapart.com/article/paint-the-picture-not-the-frame"&gt;The browser gives us so much for free&lt;/a&gt;, and we should try to take advantage of that as often as possible.&lt;/p&gt;

&lt;p&gt;This is not to say that inaccessible patterns occur &lt;em&gt;only&lt;/em&gt; when frameworks are used, but rather that a sole preference for JavaScript &lt;em&gt;will&lt;/em&gt; eventually surface gaps in our understanding of HTML and CSS. These knowledge gaps will often result in mistakes we may not even be aware of. Frameworks can be useful tools that increase our productivity, but continuing education in core web technologies is essential to creating &lt;em&gt;usable&lt;/em&gt; experiences, no matter what tools we choose to use.&lt;/p&gt;

&lt;h2&gt;Rely on the web platform and you’ll go far, fast&lt;/h2&gt;

&lt;p&gt;While we’re on the subject of frameworks, it must be said that the web platform is a formidable framework of its own. As the previous section showed, we’re better off when we can rely on established markup patterns and browser features. The alternative is to reinvent them, and invite all the pain such endeavors all but guarantee us, or worse: merely &lt;em&gt;assume&lt;/em&gt; that the author of every JavaScript package we install has solved the problem comprehensively and thoughtfully.&lt;/p&gt;

&lt;h3&gt;Single page applications&lt;/h3&gt;

&lt;p&gt;One of the tradeoffs developers are quick to make is to adopt the single page application (SPA) model, even if it’s not a fit for the project. Yes, you &lt;em&gt;do&lt;/em&gt; gain better perceived performance with the client-side routing of an SPA, but what do you &lt;em&gt;lose&lt;/em&gt;? The browser’s own navigation functionality—albeit synchronous—provides a slew of benefits. For one, history is managed according to &lt;a rel="noopener" href="https://html.spec.whatwg.org/#the-history-interface"&gt;a complex specification&lt;/a&gt;. Users without JavaScript—be it by &lt;a rel="noopener" href="https://kryogenix.org/code/browser/everyonehasjs.html"&gt;their own choice or not&lt;/a&gt;—won’t lose access altogether. For SPAs to remain available when JavaScript is not, server-side rendering suddenly becomes a thing you have to consider.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/responsible-javascript-part-1/fig2.png" alt="Two series of screenshots. On the left, we have a blank screen for several seconds until the app appears after 5.24s. On the right, the basic components appear at 4ms and the site is fully usable at 5.16s."&gt;
&lt;figcaption&gt;Figure 2. A comparison of an example app loading on a slow connection. The app on the left depends entirely upon JavaScript to render a page. The app on the right renders a response on the server, but then uses &lt;a rel="noopener" href="https://reactjs.org/docs/react-dom.html#hydrate"&gt;client-side hydration&lt;/a&gt; to attach components to the existing server-rendered markup.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Accessibility is also harmed if a client-side router fails to let people know what content on the page has changed. This can leave those reliant on assistive technology to suss out what changes have occurred on the page, which can be an arduous task.&lt;/p&gt;

&lt;p&gt;Then there’s our old nemesis: overhead. Some client-side routers are very small, but when you &lt;em&gt;start&lt;/em&gt; with &lt;a rel="noopener" href="https://bundlephobia.com/result?p=react-dom@16.8.2"&gt;React&lt;/a&gt;, &lt;a rel="noopener" href="https://bundlephobia.com/result?p=react-router@4.3.1"&gt;a compatible router&lt;/a&gt;, and possibly even &lt;a rel="noopener" href="https://bundlephobia.com/result?p=redux@4.0.1"&gt;a state management library&lt;/a&gt;, you’re accepting that there’s a certain amount of code you can never optimize away—approximately 135 KB in this case. Carefully consider what you’re building and whether a client side router is worth the tradeoffs you’ll inevitably make. Typically, you’re better off without one.&lt;/p&gt;

&lt;p&gt;If you’re concerned about the perceived navigation performance, you &lt;em&gt;could&lt;/em&gt; lean on &lt;a rel="noopener" href="https://www.w3.org/TR/resource-hints/#prefetch-link-relation-type"&gt;&lt;code&gt;rel=prefetch&lt;/code&gt;&lt;/a&gt; to speculatively fetch documents on the same origin. This has a dramatic effect on improving perceived loading performance of pages, as the document is immediately available in the cache. Because prefetches are done at a low priority, they’re also less likely to contend with critical resources for bandwidth.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/responsible-javascript-part-1/fig3.png" alt="Screenshot showing a list of assets loaded on a webpage. 'writing/' is labeled as prefetched on initial navigation. This asset is then loaded in 2ms when actually requested by the user."&gt;
&lt;figcaption&gt;Figure 3. The HTML for the writing/ URL is prefetched on the initial page. When the writing/ URL is requested by the user, the HTML for it is loaded instantaneously from the browser cache.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The primary drawback with link prefetching is that you need to be aware that it &lt;em&gt;can&lt;/em&gt; be potentially wasteful. &lt;a rel="noopener" href="https://github.com/GoogleChromeLabs/quicklink"&gt;Quicklink&lt;/a&gt;, a tiny link prefetching script from Google, mitigates this somewhat by checking if the current client is on a slow connection—or has &lt;a rel="noopener" href="https://support.google.com/chrome/answer/2392284?co=GENIE.Platform%3DAndroid&amp;amp;hl=en"&gt;data saver mode&lt;/a&gt; enabled—and avoids prefetching links on cross-origins by default.&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener" href="https://adactio.com/articles/13796"&gt;Service workers&lt;/a&gt; are also hugely beneficial to perceived performance for returning users, whether we use client side routing or not—&lt;a rel="noopener" href="https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#for_best_performance_bypass_the_network_for_navigations"&gt;provided you know the ropes&lt;/a&gt;. &lt;a rel="noopener" href="https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker"&gt;When we precache routes with a service worker&lt;/a&gt;, we get many of the same benefits as link prefetching, but with a much greater degree of control over requests and responses. Whether you think of your site as an “app” or not, adding a service worker to it is perhaps one of the most responsible uses of JavaScript that exists today.&lt;/p&gt;

&lt;h3&gt;JavaScript isn’t the solution to your layout woes&lt;/h3&gt;

&lt;p&gt;If we’re installing a package to solve a layout problem, proceed with caution and ask “what am I trying to accomplish?” CSS is &lt;a rel="noopener" href="https://twitter.com/rachelandrew/status/1088870059240505344"&gt;&lt;em&gt;designed to do this job&lt;/em&gt;&lt;/a&gt;, and requires no abstractions to use effectively. Most layout issues JavaScript packages attempt to solve, like &lt;a rel="noopener" href="https://www.npmjs.com/package/flexibility"&gt;box placement, alignment, and sizing&lt;/a&gt;, &lt;a rel="noopener" href="https://www.npmjs.com/package/shave"&gt;managing text overflow&lt;/a&gt;, and even &lt;a rel="noopener" href="https://www.npmjs.com/package/lost"&gt;entire layout systems&lt;/a&gt;, are solvable with CSS &lt;em&gt;today&lt;/em&gt;. Modern layout engines like Flexbox and Grid are supported well enough that we shouldn’t need to start a project with any layout framework. CSS &lt;em&gt;is&lt;/em&gt; the framework. When we have &lt;a rel="noopener" href="https://hacks.mozilla.org/2016/08/using-feature-queries-in-css/"&gt;feature queries&lt;/a&gt;, progressively enhancing layouts to adopt new layout engines is suddenly &lt;a rel="noopener" href="https://hacks.mozilla.org/2016/08/using-feature-queries-in-css/"&gt;not so hard&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-css"&gt;/* Your mobile-first, non-CSS grid styles goes here */

/* The @supports rule below is ignored by browsers that don't
   support CSS grid, _or_ don't support @supports. */
@supports (display: grid) {
  /* Larger screen layout */
  @media (min-width: 40em) {
    /* Your progressively enhanced grid layout styles go here */
  }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Using JavaScript solutions for layout and presentations problems is not new. It was something we did when we lied to ourselves in 2009 that every website had to look in IE6 exactly as it did in the more capable browsers of that time. If we’re still developing websites to look the same in every browser in 2019, we should reassess our development goals. There will &lt;em&gt;always&lt;/em&gt; be some browser we’ll have to support that can’t do everything those modern, evergreen browsers can. Total visual parity on all platforms is not only a pursuit made in vain, it’s the principal foe of &lt;a rel="noopener" href="https://alistapart.com/article/understandingprogressiveenhancement"&gt;progressive enhancement&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;I’m not here to kill JavaScript&lt;/h2&gt;

&lt;p&gt;Make no mistake, I have no ill will toward JavaScript. It’s given me a career and—if I’m being honest with myself—a source of enjoyment for over a decade. Like any long-term relationship, I learn more about it the more time I spend with it. It’s a mature, feature-rich language that only gets more capable and elegant with every passing year.&lt;/p&gt;

&lt;p&gt;Yet, there are times when I feel like JavaScript and I are at odds. I &lt;em&gt;am&lt;/em&gt; critical of JavaScript. Or maybe more accurately, I’m critical of how we’ve developed a tendency to view it as a first resort to building for the web. As I pick apart yet another bundle not unlike a tangled ball of Christmas tree lights, it’s become clear that the web is &lt;em&gt;drunk&lt;/em&gt; on JavaScript. We reach for it for almost everything, even when the occasion doesn’t call for it. Sometimes I wonder how vicious the hangover will be.&lt;/p&gt;

&lt;p&gt;In a series of articles to follow, I’ll be giving more practical advice to follow to stem the encroaching tide of excessive JavaScript and how we can wrangle it so that &lt;em&gt;what&lt;/em&gt; we build for the web is usable—or at least &lt;em&gt;more&lt;/em&gt; so—for everyone everywhere. Some of the advice will be preventative. Some will be mitigating “hair of the dog” measures. In either case, the outcomes will hopefully be the same. I believe that we all love the web and want to do right by it, but I want us to think about how to make it more resilient and inclusive for all.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/No8RYIWCyvQ" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Code, Application Development, JavaScript
]]></dc:subject>
      <dc:date>2019-03-28T13:07:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/responsible-javascript-part-1</feedburner:origLink></item><item>
      <title><![CDATA[Canary in a Coal Mine: How Tech Provides Platforms for Hate]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/tatianamac">Tatiana Mac</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/frLViehpDBk/canary-in-a-coal-mine-how-tech-provides-platforms-for-hate</link>
      <guid isPermaLink="false">http://alistapart.com/article/canary-in-a-coal-mine-how-tech-provides-platforms-for-hate</guid>
      <description>&lt;p&gt;As I write this, the world is sending its thoughts and prayers to our Muslim cousins. The Christchurch act of terrorism has once again reminded the world that white supremacy’s rise is very real, that its perpetrators are no longer on the fringes of society, but centered in our holiest places of worship. People are begging us to not share videos of the mass murder or the hateful manifesto that the white supremacist terrorist wrote. That’s what he wants: for his proverbial message of hate to be spread to the ends of the earth.&lt;/p&gt;

&lt;p&gt;We live in a time where you can stream a mass murder and hate crime from the &lt;em&gt;comfort of your home&lt;/em&gt;. Children can access these videos, too.&lt;/p&gt;

&lt;p&gt;As I work through the pure pain, unsurprised, observing the toll on Muslim communities (as a non-Muslim, who matters least in this event), I think of the imperative role that our industry plays in this story.&lt;/p&gt;

&lt;p&gt;At time of writing, YouTube has failed to ban and to remove this video. If you search for the video (which I strongly advise against), it still comes up with a mere content warning; the same content warning that appears for casually risqué content. You can bypass the warning and watch people get murdered. &lt;a href="https://afrotech.com/tech-companies-are-scrambling-to-remove-video-of-the-christchurch-shooting"&gt;Even when the video gets flagged and taken down, new ones get uploaded.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.theverge.com/2019/2/25/18229714/cognizant-facebook-content-moderator-interviews-trauma-working-conditions-arizona" rel="noopener"&gt;Human moderators have to relive watching this trauma over and over again&lt;/a&gt; for unlivable wages. News outlets are &lt;em&gt;embedding the video&lt;/em&gt; into their articles and publishing the hateful manifesto. Why? What does this accomplish?&lt;/p&gt;

&lt;p&gt;I was taught in journalism class that media (photos, video, infographics, etc.) should be additive (a progressive enhancement, if you will) and provide something to the story for the reader that words cannot.&lt;/p&gt;

&lt;p&gt;Is it necessary to show murder for our dear readers to understand the cruelty and finality of it? Do readers gain something more from watching fellow humans have their lives stolen from them? What psychological damage are we inflicting upon millions of people   and for what?&lt;/p&gt;

&lt;p&gt;Who benefits?&lt;/p&gt;

&lt;p&gt;The mass shooter(s) who had a message to accompany their mass murder. News outlets are thirsty for perverse clicks to garner more ad revenue. We, by way of our platforms, give agency and credence to these acts of violence, then pilfer profits from them. Tech is a money-making accomplice to these hate crimes.&lt;/p&gt;

&lt;p&gt;Christchurch is just one example in an endless array where the &lt;a href="https://www.sarawb.com/technically-wrong/" rel="noopener"&gt;tools and products we create are used as a vehicle for harm and for hate&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.theatlantic.com/politics/archive/2018/04/white-supremacy-is-still-americas-biggest-security-threat/557591/" rel="noopener"&gt;Facebook and the Cambridge Analytica scandal played a critical role in the outcome of the 2016 presidential election&lt;/a&gt;. The concept of “race realism,” which is essentially a term that white supremacists use to codify their false racist pseudo-science, was actively tested on Facebook’s platform to see how the term would sit with people who are ignorantly sitting on the fringes of white supremacy. Full-blown white supremacists don’t need this soft language. This is how radicalization works.&lt;/p&gt;

&lt;p&gt;The strategies articulated in the above article are not new. Racist propaganda predates social media platforms. What we have to be mindful with is that  we’re building smarter tools with power we don’t yet fully understand: you can now have an &lt;a href="https://www.theverge.com/tldr/2019/2/15/18226005/ai-generated-fake-people-portraits-thispersondoesnotexist-stylegan" rel="noopener"&gt;AI-generated human face&lt;/a&gt;. Our technology is accelerating at a frightening rate, a rate faster than our reflective understanding of its impact.&lt;/p&gt;

&lt;p&gt;Combine the time-tested methods of spreading white supremacy, the power to manipulate perception through technology, and the magnitude and reach that has become democratized and anonymized.&lt;/p&gt;

&lt;p&gt;We’re staring at our own reflection in the &lt;em&gt;Black Mirror&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;The right to speak versus the right to survive&lt;/h2&gt;

&lt;p&gt;Tech has proven time and time again that it voraciously protects first amendment rights above all else. (I will also take this opportunity to remind you that the first amendment of the United States offers protection to the people from the &lt;em&gt;government&lt;/em&gt; abolishing free speech, not from &lt;em&gt;private money-making corporations&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Evelyn Beatrice Hall writes in &lt;em&gt;The Friends of Voltaire&lt;/em&gt;, “I disapprove of what you say, but I will defend to the death your right to say it.” Fundamentally, Hall’s quote expresses that we must protect, possibly above all other freedoms, the freedom to say whatever we want to say. (Fun fact: The quote is often misattributed to Voltaire, but Hall actually wrote it to explain Voltaire’s ideologies.)&lt;/p&gt;

&lt;p&gt;And the logical anchor here is sound: We must grant everyone else the same rights that we would like for ourselves. Former &lt;em&gt;99u&lt;/em&gt; editor Sean Blanda wrote a thoughtful piece on the “&lt;a href="https://medium.com/@SeanBlanda/the-other-side-is-not-dumb-2670c1294063" rel="noopener"&gt;Other Side&lt;/a&gt;,” where he posits that we lack tolerance for people who don’t think like us, but that we must because we might one day be on the other side. I agree in theory.&lt;/p&gt;

&lt;p&gt;But, what happens when a portion of the rights we grant to one group (let’s say, free speech to white supremacists) means the active oppression another group’s right (let’s say, every person of color’s right to live)?&lt;/p&gt;

&lt;p&gt;James Baldwin expresses this idea with a clause, “We can disagree and still love each other unless your disagreement is rooted in my oppression and denial of my humanity and right to exist.”&lt;/p&gt;

&lt;p&gt;It would seem that we have a moral quandary where two sets of rights cannot coexist. Do we protect the privilege for all users to say what they want, or do we protect all users from hate? Because of this perceived moral quandary, tech has often opted out of this conversation altogether. Platforms like Twitter and Facebook, two of the biggest offenders, continue to allow hate speech to ensue with irregular to no regulation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.wired.com/story/jack-dorsey-twitters-role-free-speech-filter-bubbles/" rel="noopener"&gt;When explicitly asked about his platform&lt;/a&gt; as a free-speech platform and its consequence to privacy and safety, Twitter CEO Jack Dorsey said,&lt;/p&gt;

&lt;figure class="quote" id="figure1"&gt;
&lt;blockquote cite="https://www.wired.com/story/jack-dorsey-twitters-role-free-speech-filter-bubbles/"&gt;
&lt;p&gt;“So we believe that we can only serve the public conversation, we can only stand for freedom of expression if people feel safe to express themselves in the first place. We can only do that if they feel that they are not being silenced.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/figure&gt;

&lt;p&gt;Dorsey and Twitter are most concerned about protecting &lt;em&gt;expression&lt;/em&gt; and about not silencing people. In his mind, if he allows people to say whatever they want on his platform, he has succeeded. When asked about why he’s failed to implement AI to filter abuse like, say, Instagram had implemented, he said that he’s most concerned about being able to explain &lt;em&gt;why&lt;/em&gt; the AI flagged something as abusive. Again, Dorsey protects the freedom of speech (and thus, the perpetrators of abuse) before the &lt;em&gt;victims&lt;/em&gt; of abuse.&lt;/p&gt;

&lt;p&gt;But he’s inconsistent about it. In a &lt;a href="https://extremism.gwu.edu/sites/g/files/zaxdzs2191/f/downloads/Nazis%20v.%20ISIS.pdf" rel="noopener"&gt;study by George Washington University comparing white nationalists and ISIS social media usage&lt;/a&gt;, Twitter’s freedom of speech was not granted to ISIS. Twitter suspended 1,100 accounts related to ISIS whereas it suspended only seven accounts related to Nazis, white nationalism, and white supremacy, despite the accounts having more than seven times the followers, and tweeting 25 times more than the ISIS accounts. Twitter here made a moral judgment that the fewer, less active, and less influential ISIS accounts were somehow not welcome on their platform, whereas the prolific and burgeoning Nazi and white supremacy accounts were.&lt;/p&gt;

&lt;p&gt;So, Twitter has shown that it won’t protect free speech at &lt;em&gt;all&lt;/em&gt; costs or for &lt;em&gt;all&lt;/em&gt; users. We can only conclude that Twitter is either intentionally protecting white supremacy or simply doesn’t think it’s very dangerous. Regardless of which it is (I think I know), the outcome does not change the fact that white supremacy is running rampant on its platforms and many others.&lt;/p&gt;

&lt;p&gt;Let’s brainwash ourselves for a moment and pretend like Twitter does want to support freedom of speech equitably and stays neutral and fair to complete this logical exercise: Going back to the dichotomy of rights example I provided earlier, where either the right to free speech or the right to safety and survival prevail, the rights and the power will fall into the hands of the dominant group or ideologue.&lt;/p&gt;

&lt;p&gt;In case you are somehow unaware, the dominating ideologue, whether you’re a flagrant white supremacist or not, is white supremacy. White supremacy was baked into &lt;a href="https://www.theroot.com/to-be-clear-white-supremacy-is-the-foundation-of-our-c-1797990783" rel="noopener"&gt;founding principles of the United States&lt;/a&gt;, the country where the majority of these platforms were founded and exist. (I am not suggesting that white supremacy doesn’t exist globally, as it does, evidenced most recently by the terrorist attack in Christchurch. I’m centering the conversation intentionally around the United States as it is my lived experience and where most of these companies operate.)&lt;/p&gt;

&lt;p&gt;Facebook attempted to educate its team on white supremacy in order to address how to regulate free speech. A laugh-cry excerpt:&lt;/p&gt;

&lt;figure class="quote" id="figure2"&gt;
&lt;blockquote&gt;
&lt;p&gt;“White nationalism and calling for an exclusively white state is not a violation for our policy unless it explicitly excludes other PCs [protected characteristics].”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/figure&gt;

&lt;p&gt;White nationalism is a softened synonym for white supremacy so that racists-lite can feel more comfortable with their transition into hate. White nationalism (a.k.a. white supremacy) by definition explicitly seeks to eradicate all people of color. So, Facebook should see white nationalist speech as exclusionary, and therefore a violation of their policies.&lt;/p&gt;

&lt;p&gt;Regardless of what tech leaders like Dorsey or Facebook CEO Zuckerberg say or what mediocre and uninspired condolences they might offer, inaction is an action.&lt;/p&gt;

&lt;p&gt;Companies that use terms and conditions or acceptable use policies to defend their inaction around hate speech are enabling and perpetuating white supremacy. Policies are written by humans to protect that group of human’s ideals. The message they use might be that they are protecting free speech, but hate speech is a form of free speech. So effectively, they are protecting hate speech. Well, as long as it’s for white supremacy and not the Islamic State.&lt;/p&gt;

&lt;p&gt;Whether the motivation is fear (losing loyal Nazi customers and their sympathizers) or hate (because their CEO is a white supremacist), it does not change the impact: Hate speech is tolerated, enabled, and amplified by way of their platforms.&lt;/p&gt;

&lt;h2&gt;“That wasn’t our intent”&lt;/h2&gt;

&lt;p&gt;Product creators might be thinking, &lt;em&gt;Hey, look, I don’t intentionally create a platform for hate. The way these features were used was never our intent.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intent does not erase impact.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We cannot absolve ourselves of culpability merely because we failed to conceive such evil use cases when we built it. While we very well might not have created these platforms with the explicit intent to help Nazis or imagined it would be used to spread their hate, the reality is that our platforms &lt;em&gt;are&lt;/em&gt; being used in this way.&lt;/p&gt;

&lt;p&gt;As product creators, it is our responsibility to protect the safety of our users by stopping those that intend to or already cause them harm. Better yet, we ought to think of this &lt;em&gt;before&lt;/em&gt; we build the platforms to prevent this in the first place.&lt;/p&gt;

&lt;p&gt;The question to answer isn’t, “Have I made a place where people have the freedom to express themselves?” Instead we have to ask, “Have I made a place where everyone has the safety to exist?” If you have created a place where a dominant group can embroil and embolden hate against another group, you have failed to create a safe place. The foundations of hateful speech (beyond the psychological trauma of it) lead to events like Christchurch.&lt;/p&gt;

&lt;p&gt;We must protect safety over speech.&lt;/p&gt;

&lt;h2&gt;The Domino Effect&lt;/h2&gt;

&lt;p&gt;This week, &lt;a href="https://www.engadget.com/2019/03/14/slack-removed-28-accounts-with-ties-to-hate-groups/" rel="noopener"&gt;Slack banned 28 hate groups&lt;/a&gt;. What is most notable, to me, is that the groups did not break any parts of their Acceptable Use Policy. Slack issued a statement:&lt;/p&gt;

&lt;figure class="quote" id="figure3"&gt;
&lt;blockquote cite="https://slackhq.com/slack-statement-hate-groups"&gt;
&lt;p&gt;The use of Slack by hate groups runs counter to everything we believe in at Slack and is not welcome on our platform… Using Slack to encourage or incite hatred and violence against groups or individuals because of who they are is antithetical to our values and the very purpose of Slack.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/figure&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;It is not illegal for tech companies like Slack to ban groups from using their proprietary software because it is a private company that can regulate users if they do not align with their vision as a company. Think of it as the “no shoes, no socks, no service” model, but for tech. &lt;/p&gt;

&lt;p&gt;Slack simply decided that supporting the workplace collaboration of Nazis around efficient ways to evangelize white supremacy was probably not in line with their company directives around inclusion. I imagine Slack also considered how their employees of color most ill-affected by white supremacy would feel working for a company that supported it, actively or not.&lt;/p&gt;

&lt;p&gt;What makes the Slack example so notable is that they acted swiftly and on their own accord. Slack chose the safety of all their users over the speech of some.&lt;/p&gt;

&lt;p&gt;When caught with their enablement of white supremacy, some companies will only budge under pressure from activist groups, users, and employees.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.cbsnews.com/news/paypal-suspends-dozens-of-racist-groups-sites-altright-com/" rel="noopener"&gt;PayPal finally banned hate groups after Charlottesville&lt;/a&gt; and after Southern Poverty Law Center (SPLC) explicitly called them out for enabling hate. SPLC had identified this fact for three years prior. PayPal had ignored them for all three years.&lt;/p&gt;

&lt;p&gt;Unfortunately, taking these “stances” against something as clearly and viscerally wrong as white supremacy is rare for companies to do. The tech industry tolerates this inaction through unspoken agreements.&lt;/p&gt;

&lt;p&gt;If Facebook doesn’t do anything about racist political propaganda, &lt;a href="https://www.vox.com/2018/12/13/18136253/pewdiepie-vs-tseries-links-to-white-supremacist-alt-right-redpill" rel="noopener"&gt;YouTube doesn’t do anything about PewDiePie&lt;/a&gt;, and Twitter doesn’t do &lt;a href="https://tech.co/news/amnesty-study-misogyny-racism-twitter-2018-12" rel="noopener"&gt;anything about disproportionate abuse against Black women&lt;/a&gt;, it says to the smaller players in the industry that they don’t have to either.&lt;/p&gt;

&lt;p&gt;The tech industry reacts to its peers. When there is disruption, as was the case with Airbnb, who &lt;a href="https://slate.janrainsso.com//static/server.html?origin=http%3A%2F%2Fwww.slate.com%2Farticles%2Ftechnology%2Ftechnology%2F2017%2F08%2Fairbnb_s_ban_of_nazis_in_charlottesville_sets_an_important_standard_for.html" rel="noopener"&gt;screened and rejected any guests who they believed to be partaking in the Unite the Right Charlottesville rally&lt;/a&gt;, companies follow suit. &lt;a href="https://www.npr.org/sections/thetwo-way/2017/08/14/543360434/white-supremacist-site-is-banned-by-go-daddy-after-virginia-rally" rel="noopener"&gt;GoDaddy cancelled Daily Stormer’s domain registration&lt;/a&gt; and Google did the same when they attempted migration.&lt;/p&gt;

&lt;p&gt;If one company, like Slack or Airbnb, decides to do something about the role it’s going to play, it creates a perverse kind of FOMO for the rest: Fear of missing out of doing the right thing and standing on the right side of history.&lt;/p&gt;

&lt;h2&gt;Don’t have FOMO, do something&lt;/h2&gt;

&lt;p&gt;The type of activism at those companies all started with one individual. If you want to be part of the solution, I’ve gathered some places to start. The list is not exhaustive, and, as with all things, I recommend researching beyond this abridged summary.&lt;/p&gt;

&lt;ol type="1"&gt;
&lt;li&gt;
&lt;strong&gt;Understand how white supremacy impacts you as an individual.&lt;/strong&gt;&lt;br&gt;Now, if you are a person of color, queer, disabled, or trans, it’s likely that you know this very intimately.&lt;br&gt;&lt;br&gt;
If you are not any of those things, then you, as a majority person, need to understand how white supremacy protects you and works in your favor. It’s not easy work, it is uncomfortable and unfamiliar, but you have the most powerful tools to fix tech. The resources are aplenty, but my favorite abridged list:
&lt;ol type="a"&gt;
&lt;li&gt;&lt;a href="https://www.sceneonradio.org/seeing-white/" rel="noopener"&gt;Seeing White&lt;/a&gt; podcast&lt;/li&gt;
&lt;li&gt;Ijeoma Oluo’s &lt;em&gt;So you want to talk about race&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Reni Eddo-Lodge’s &lt;em&gt;Why I’m no longer talking to white people about race&lt;/em&gt; (Very key read for UK folks)&lt;/li&gt;
&lt;li&gt;Robin DiAngelo’s &lt;em&gt;White Fragility&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;See where your company stands: Read your company’s policies like accepted use and privacy policies and find your CEO’s stance on safety and free speech.&lt;/strong&gt;&lt;br&gt;While these policies are baseline (and in the Slack example, sort of irrelevant), it’s important to known your company&amp;#8217;s track record. As an employee, your actions and decisions either uphold the ideologies behind the company or they don’t. Ask yourself if the company’s ideologies are worth upholding and whether they align with your own. Education will help you to flag if something contradicts those policies, or if the policies themselves allow for unethical activity.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Examine everything you do critically on an ongoing basis.&lt;/strong&gt;&lt;br&gt;You may feel your role is small or that your company is immune—maybe you are responsible for the maintenance of one small algorithm. But consider how that algorithm or similar ones can be exploited. Some key questions I ask myself:&lt;/p&gt;&lt;ol type="a"&gt;
&lt;li&gt;Who benefits from this? Who is harmed?&lt;/li&gt;
&lt;li&gt;How could this be used for harm?&lt;/li&gt;
&lt;li&gt;Who does this exclude? Who is missing?&lt;/li&gt;
&lt;li&gt;What does this protect? For whom? Does it do so equitably?&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;See something? Say something.&lt;/strong&gt;&lt;br&gt;If you believe that your company is creating something that is or can be used for harm, it is your responsibility to say something. Now, I’m not naïve to the fact that there is inherent risk in this. You might fear ostracization or termination. You need to protect yourself first. But you also need to do something.&lt;/p&gt;&lt;ol type="a"&gt;
&lt;li&gt;Find someone who you trust who might be at less risk. Maybe if you’re a nonbinary person of color, find a white cis man who is willing to speak up. Maybe if you’re a white man who is new to the company, find a white man who has more seniority or tenure. But also, consider how you have so much more relative privilege compared to most other people and that you might be the safest option.&lt;/li&gt;
&lt;li&gt;Unionize. Find peers who might feel the same way and write a collective statement.&lt;/li&gt;
&lt;li&gt;Get someone influential outside of the company (if knowledge is public) to say something.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Listen to concerns, no matter how small, particularly if they’re coming from the most endangered groups.&lt;/strong&gt;&lt;br&gt;If your user or peer feels unsafe, you need to understand why. People often feel like small things can be overlooked, as their initial impact might be less, but it is in the smallest cracks that hate can grow. Allowing one insensitive comment about race is still allowing hate speech. If someone, particularly someone in a marginalized group, brings up a concern, you need to do your due diligence to listen to it and to understand its impact.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I cannot emphasize this last point enough.&lt;/p&gt;

&lt;p&gt;What I say today is not new. Versions of this article have been written before. Women of color like me have voiced similar concerns not only in writing, but in design reviews, in closed door meetings to key stakeholders, in Slack DMs. We’ve blown our whistles.&lt;/p&gt;

&lt;p&gt;But here is the power of white supremacy.&lt;/p&gt;

&lt;p&gt;White supremacy is so ingrained in every single aspect of how this nation was built, how our corporations function, and who is in control. If you are not convinced of this, you are not paying attention or intentionally ignoring the truth.&lt;/p&gt;

&lt;p&gt;Queer, Muslim, disabled, trans women and nonbinary folks of color — the marginalized groups most impacted by this — are the ones who are voicing these concerns most voraciously. Speaking up requires us to enter the spotlight and outside of safety—we take a risk and are not heard.&lt;/p&gt;

&lt;p&gt;The silencing of our voices is one of many effective tools of white supremacy. Our silencing lives within every microaggression, each time we’re talked over, or not invited to partake in key decisions.&lt;/p&gt;

&lt;p&gt;In tech, I feel I am a canary in a coal mine. I have sung my song to warn the miners of the toxicity. My sensitivity to it is heightened, because of my existence.&lt;/p&gt;

&lt;p&gt;But the miners look at me and tell me that my lived experience is false. It does not align with their narrative as humans. They don’t understand why I sing.&lt;/p&gt;

&lt;p&gt;If the people at the highest echelons of the tech industry—the white, male CEOs in power—fail to listen to its most marginalized people—the queer, disabled, trans, people of color—the fate of the canaries will too become the fate of the miners.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/frLViehpDBk" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Community, Industry
]]></dc:subject>
      <dc:date>2019-03-19T13:22:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/canary-in-a-coal-mine-how-tech-provides-platforms-for-hate</feedburner:origLink></item><item>
      <title><![CDATA[Semantics to Screen Readers]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/melanie-richards">Melanie Richards</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/2VWN4n_FhyE/semantics-to-screen-readers</link>
      <guid isPermaLink="false">http://alistapart.com/article/semantics-to-screen-readers</guid>
      <description>&lt;p&gt;&lt;b&gt;A note from the editors:&lt;/b&gt; We extended our &lt;a href="https://alistapart.com/article/from-url-to-interactive"&gt;From URL to Interactive series&lt;/a&gt; with this fifth installment to include what happens when screen readers access our page. In the illustration, our fisher has caught the fish and is now ready to weigh it.&lt;/p&gt;&lt;p&gt;As a child of the ’90s, one of my favorite movie quotes is from &lt;a href="https://www.imdb.com/title/tt0116493"&gt;&lt;cite&gt;Harriet the Spy&lt;/cite&gt;&lt;/a&gt;: “there are as many ways to live as there are people in this world, and each one deserves a closer look.” Likewise, there as many ways to browse the web as there are people online. We each bring unique context to our web experience based on our values, technologies, environments,&amp;nbsp; minds, and bodies.	&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Assistive technologies&lt;/i&gt; (ATs), which are hardware and software that help us perceive and interact with digital content, come in diverse forms. ATs can use a whole host of user input, ranging from clicks and keystrokes to minor muscle movements. ATs may also present digital content in a variety of forms, such as Braille displays, color-shifted views, and decluttered &lt;i&gt;user interfaces&lt;/i&gt; (UIs).&lt;/p&gt;

&lt;p&gt;One more commonly known type of AT is the screen reader. Programs such as JAWS, Narrator, NVDA, and VoiceOver can take digital content and present it to users through voice output, may display this output visually on the user’s screen, and can have Braille display and/or screen magnification capabilities built in.&lt;/p&gt;

&lt;p&gt;If you make websites, you may have tested your sites with a screen reader. But how do these and other assistive programs actually access your content? What information do they use? We’ll take a detailed step-by-step view of how the process works.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;(For simplicity we’ll continue to reference “browsers” and “screen readers” throughout this article. These are essentially shorthands for “browsers and other applications,” and “screen readers and other assistive technologies,” respectively.)&lt;/i&gt;&lt;/p&gt;

&lt;h2&gt;The semantics-to-screen-readers pipeline&lt;/h2&gt;

&lt;p&gt;Accessibility &lt;i&gt;application programming interfaces&lt;/i&gt; (APIs) create a useful link between user applications and the assistive technologies that wish to interact with them. Accessibility APIs facilitate communicating accessibility information about user interfaces (UIs) to the ATs. The API expects information to be structured in a certain way, so that whether a button is properly marked up in web content or is sitting inside a native app taskbar, a button is a button is a button as far as ATs are concerned. That said, screen readers and other ATs can do some app-specific handling if they wish.&lt;/p&gt;

&lt;p&gt;On the web specifically, there are some browser and screen reader combinations where accessibility API information is supplemented by access to DOM structures. For this article, we’ll focus specifically on accessibility APIs as a link between web content and the screen reader.&lt;/p&gt;

&lt;p&gt;Here’s the breakdown of how web content reaches screen readers via accessibility APIs:&lt;/p&gt;

&lt;p&gt;The &lt;b&gt;web developer&lt;/b&gt; uses host language markup (HTML, SVG, etc.), and potentially roles, states, and properties from the &lt;a href="https://rawgit.com/w3c/aria/master/"&gt;ARIA suite&lt;/a&gt; where needed to provide the semantics of their content. Semantic markup communicates what type an element is, what content it contains, what state it’s in, etc.&lt;/p&gt;

&lt;p&gt;The &lt;b&gt;browser rendering engine&lt;/b&gt; (alternatively referred to as a “user agent”) takes this information and maps it into an accessibility API. Different accessibility APIs are available on different operating systems, so a browser that is available on multiple platforms should support multiple accessibility APIs. Accessibility API mappings are maintained on a lower level than web platform APIs, so web developers don’t directly interact with accessibility APIs.&lt;/p&gt;

&lt;p&gt;The &lt;b&gt;accessibility API&lt;/b&gt; includes a collection of &lt;a href="https://en.wikipedia.org/wiki/Interface_(computing)"&gt;interfaces&lt;/a&gt; that browsers and other apps can plumb into, and generally acts as an intermediary between the browser and the screen reader. Accessibility APIs provide interfaces for representing the structure, relationships, semantics, and state of digital content, as well as means to surface dynamic changes to said content. Accessibility APIs also allow screen readers to retrieve and interact with content via the API.&lt;/p&gt;

&lt;p&gt;Again, web developers don’t interact with these APIs directly; the rendering engine handles translating web content into information useful to accessibility APIs.&lt;/p&gt;

&lt;h3&gt;Examples of accessibility APIs&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Windows:&lt;/b&gt; &lt;a href="https://docs.microsoft.com/en-us/windows/desktop/WinAuto/microsoft-active-accessibility"&gt;Microsoft Active Accessibility&lt;/a&gt; (MSAA), extended with another API called &lt;a href="https://wiki.linuxfoundation.org/accessibility/iaccessible2/start"&gt;IAccessible2&lt;/a&gt; (IA2)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Windows:&lt;/b&gt; &lt;a href="https://docs.microsoft.com/en-us/windows/desktop/WinAuto/entry-uiauto-win32"&gt;UI Automation&lt;/a&gt; (UIA), the Microsoft successor to MSAA. A browser on Windows can choose to support MSAA with IA2, UIA, or both.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MacOS:&lt;/b&gt; &lt;a href="https://developer.apple.com/documentation/appkit/nsaccessibility"&gt;NSAccessibility&lt;/a&gt; (AXAPI)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Linux/Gnome:&lt;/b&gt; &lt;a href="https://developer.gnome.org/atk/stable/"&gt;Accessibility Toolkit&lt;/a&gt; (ATK) and &lt;a href="https://developer.gnome.org/libatspi/stable/"&gt;Assistive Technology Service Provider Interface&lt;/a&gt; (AT-SPI). This case is a little different in that there are actually two separate APIs: one through which browsers and other applications pass information along to (ATK) and one that ATs then call from (AT-SPI).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;b&gt;screen reader&lt;/b&gt; uses client-side methods from these accessibility APIs to retrieve and handle information exposed by the browser. In browsers where direct access to the Document Object Model (DOM) is permitted, some screen readers may also take additional information from the DOM tree. A screen reader can also interact with apps that use differing accessibility APIs.&lt;/p&gt;

&lt;p&gt;No matter where they get their information, screen readers can dream up any interaction modes they want to provide to their users (I’ve provided links to screen reader commands at the end of this article). Testing by site creators can help identify content that feels awkward in a particular navigation mode, such as multiple links with the same text (“Learn more”), as one example.&lt;/p&gt;

&lt;h3&gt;Example of this pipeline: surfacing a button element to screen reader users&lt;/h3&gt;

&lt;p&gt;Let’s suppose for a moment that a screen reader wants to understand what object is next in the accessibility tree (which I’ll explain further in the next section), so it can surface that object to the user as they navigate to it. The flow will go a little something like this:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig1.png" alt="Diagram showing the client (screen reader) making a call to the accessibility API, which passes along the request to the provider (browser), which checks the content in the web document, which sends the information back up the chain"&gt;
&lt;figcaption&gt;Diagram illustrating the steps involved in presenting the next object in a document; detailed list follows&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ol&gt;
&lt;li&gt;The screen reader requests information from the API about the next accessible object, relative to the current object.&lt;/li&gt;
&lt;li&gt;The API (as an intermediary) passes along this request to the browser.&lt;/li&gt;
&lt;li&gt;At some point, the browser references DOM and style information, and discovers that the relevant element is a non-hidden button: &lt;code&gt;&amp;lt;button&amp;gt;Do a thing&amp;lt;/button&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The browser maps this HTML button into the format the API expects, such as an accessible object with various properties: &lt;b&gt;Name:&lt;/b&gt; Do a thing, &lt;b&gt;Role:&lt;/b&gt; Button.&lt;/li&gt;
&lt;li&gt;The API returns this information from the browser to the screen reader.&lt;/li&gt;
&lt;li&gt;The screen reader can then surface this object to the user, perhaps stating “Button, Do a thing.”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suppose that the screen reader user would now like to “click” this button. Here’s how their action flows all the way back to web content:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig2.png" alt="Diagram showing a user using a 'primary action' command to a client (screen reader), which passes the command to the accessibility API, which passes the command along to the provider (browser), which passes the command as a click event to the web document"&gt;
&lt;figcaption&gt;Diagram illustrating the steps involved in routing a screen reader click to web content; detailed list follows&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ol&gt;
&lt;li&gt;The user provides a particular screen reader command, such as a keystroke or gesture.&lt;/li&gt;
&lt;li&gt;The screen reader calls a method into the API to invoke the button.&lt;/li&gt;
&lt;li&gt;The API forwards this interaction to the browser.&lt;/li&gt;
&lt;li&gt;How a browser may respond to incoming interactions depends on the context, but in this case the browser can raise this as a “click” event through web APIs. The browser should give no indication that the click came from an assistive technology, as doing so would violate the user’s right to privacy.&lt;/li&gt;
&lt;li&gt;The web developer has registered a JavaScript event listener for clicks; their callback function is now executed as if the user clicked with a mouse.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we have a general sense of the pipeline, let’s go into a little more detail on the accessibility tree.&lt;/p&gt;

&lt;h2&gt;The accessibility tree&lt;/h2&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig3.png" alt="Screenshot showing the accessibility tools in Microsoft Edge"&gt;
&lt;figcaption&gt;Dev Tools in Microsoft Edge showing the DOM tree and accessibility tree side by side; there are more nodes in the DOM tree&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The &lt;i&gt;accessibility tree&lt;/i&gt; is a hierarchical representation of elements in a UI or document, as computed for an accessibility API. In modern browsers, the accessibility tree for a given document is a separate, parallel structure to the DOM tree. “Parallel” does not necessarily mean there is a 1:1 match between the nodes of these two trees. Some elements may be excluded from the accessibility tree, for example if they are hidden or are not semantically useful (think non-focusable wrapper &lt;code&gt;div&lt;/code&gt;s without any semantics added by a web developer).&lt;/p&gt;

&lt;p&gt;This idea of a hierarchical structure is somewhat of an abstraction. The definition of what exactly an accessibility tree is in practice has been debated and partially defined in multiple places, so implementations may differ in various ways.&lt;/p&gt;

&lt;p&gt;For example, it’s not actually necessary to generate accessible objects for every element in the DOM whenever the DOM tree is constructed. As a performance consideration, a browser could choose to deal with only a subset of objects and their relationships at a time—that is, however much is necessary to fulfill the requests coming from ATs. The rendering engine could make these computations during all user sessions, or only do so when assistive technologies are actively running.&lt;/p&gt;

&lt;p&gt;Generally speaking, modern web browsers wait until after style computation to build up any accessible objects. Browsers wait in part because generated content (such as &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt;) ƒcan contain text that can participate in calculation of the accessible object’s name. CSS styles can also impact accessible objects in other various ways: text styling can come through as attributes on accessible text ranges. Display property values can impact the computation of line text ranges. These are just a few ways in which style can impact accessibility semantics.&lt;/p&gt;

&lt;p&gt;Browsers may also use different structures as the basis for accessible object computation. One rendering engine may walk the DOM tree and cross-reference style computations to build up parallel tree structures; another engine may use only the nodes that are available in a style tree in order to build up their accessibility tree.&lt;/p&gt;

&lt;p&gt;User agent participants in the standards community are currently thinking through how we can better document our implementation details, and whether it might make sense to standardize more of these details further down the road.&lt;/p&gt;

&lt;p&gt;Let’s now focus on the branches of this tree, and explore how individual accessibility objects are computed.&lt;/p&gt;

&lt;h3&gt;Building up accessible objects&lt;/h3&gt;

&lt;p&gt;From API to API, an accessible object will generally include a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role&lt;/b&gt;, or the type of accessible object (for example, Button). The role tells a user how they can expect to interact with the control. It is typically presented when screen reader focus moves onto the accessible object, and it can be used to provide various other functionalities, such as skipping around content via one type of object.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Name&lt;/b&gt;, if specified. The name is an (ideally short) identifier that better helps the user identify and understand the purpose of an accessible object. The name is often presented when screen focus moves to the object (more on this later), can be used as an identifier when presenting a list of available objects, and can be used as a hook for functionalities such as voice commands.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Description and/or help text&lt;/b&gt;, if specified. We’ll use “Description” as a shorthand. The Description can be considered supplemental to the Name; it’s not the main identifier but can provide further information about the accessible object. Sometimes this is presented when moving focus to the accessible object, sometimes not; this variation depends on both the screen reader’s user experience design and the user’s chosen verbosity settings.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Properties and methods surfacing additional semantics.&lt;/b&gt; For simplicity’s sake, we won’t go through all of these. For your awareness, properties can include details like layout information or available interactions (such as invoking the element or modifying its value).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s walk through an example using markup for a simple mood tracker. We’ll use simplified property names and values, because these can differ between accessibility APIs.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig4.png" alt=""&gt;
&lt;/figure&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;&amp;lt;form&amp;gt;
  &amp;lt;label for="mood"&amp;gt;On a scale of 1–10, what is your mood today?&amp;lt;/label&amp;gt;
  &amp;lt;input id="mood" type="range"
       min="1" max="10" value="5"
       aria-describedby="helperText" /&amp;gt;
  &amp;lt;p id="helperText"&amp;gt;Some helpful pointers about how to rate your mood.&amp;lt;/p&amp;gt;
  &amp;lt;!-- Using a div with button role for the purposes of showing how the accessibility tree is created. Please use the button element! --&amp;gt;
  &amp;lt;div tabindex="0" role="button"&amp;gt;Log Mood&amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First up is our &lt;code&gt;form&lt;/code&gt; element. This form doesn’t have any attributes that would give it an accessible Name, and a form landmark without a Name isn’t very useful when jumping between landmarks. Therefore, &lt;a href="https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings"&gt;HTML mapping standards&lt;/a&gt; specify that it should be mapped as a group.&lt;/p&gt;

&lt;p&gt;Here’s the beginning of our tree:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Group&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up is the &lt;code&gt;label&lt;/code&gt;. This one doesn’t have an accessible Name either, so we’ll just nest it as an object of role “Label” underneath the form:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Group
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Label&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s add the range &lt;code&gt;input&lt;/code&gt;, which will map into various APIs as a “Slider.” Due to the relationship created by the &lt;code&gt;for&lt;/code&gt; attribute on the &lt;code&gt;label&lt;/code&gt; and &lt;code&gt;id&lt;/code&gt; attribute on the &lt;code&gt;input&lt;/code&gt;, this slider will take its Name from the label contents. The &lt;code&gt;aria-describedby&lt;/code&gt; attribute is another id reference and points to a paragraph with some text content, which will be used for the slider’s Description. The slider object’s properties will also store “labelledby” and “describedby” relationships pointing to these other elements. And it will specify the current, minimum, and maximum values of the slider. If one of these range values were not available, &lt;a href="https://www.w3.org/TR/wai-aria-1.2/#slider"&gt;ARIA standards specify what should be the default value&lt;/a&gt;. Our updated tree:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Group
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Label&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Slider&lt;br&gt;
&lt;b&gt;Name:&lt;/b&gt; On a scale of 1–10, what is your mood today?&lt;br&gt;
&lt;b&gt;Description:&lt;/b&gt; Some helpful pointers about how to rate your mood.&lt;br&gt;
&lt;b&gt;LabelledBy:&lt;/b&gt; mood&lt;br&gt;
&lt;b&gt;DescribedBy:&lt;/b&gt; helperText&lt;br&gt;
&lt;b&gt;ValueNow:&lt;/b&gt; 5&lt;br&gt;
&lt;b&gt;ValueMin:&lt;/b&gt; 1&lt;br&gt;
&lt;b&gt;ValueMax:&lt;/b&gt; 10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The paragraph will be added as a simple paragraph object (“Text” or “Group” in some APIs):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Group
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Label&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Slider&lt;br&gt;
&lt;b&gt;Name:&lt;/b&gt; On a scale of 1–10, what is your mood today?&lt;br&gt;
&lt;b&gt;Description:&lt;/b&gt; Some helpful pointers about how to rate your mood.&lt;br&gt;
&lt;b&gt;LabelledBy:&lt;/b&gt; mood&lt;br&gt;
&lt;b&gt;DescribedBy:&lt;/b&gt; helperText&lt;br&gt;
&lt;b&gt;ValueNow:&lt;/b&gt; 5&lt;br&gt;
&lt;b&gt;ValueMin:&lt;/b&gt; 1&lt;br&gt;
&lt;b&gt;ValueMax:&lt;/b&gt; 10&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Paragraph&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final element is an example of when role semantics are added via the ARIA &lt;code&gt;role&lt;/code&gt; attribute. This &lt;code&gt;div&lt;/code&gt; will map as a Button with the name “Log Mood,” as buttons can take their name from their children. This button will also be surfaced as “invokable” to screen readers and other ATs; special types of buttons could provide expand/collapse functionality (buttons with the &lt;code&gt;aria-expanded&lt;/code&gt; attribute), or toggle functionality (buttons with the &lt;code&gt;aria-pressed&lt;/code&gt; attribute). Here’s our tree now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Group
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Label&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Slider&lt;br&gt;
&lt;b&gt;Name:&lt;/b&gt; On a scale of 1–10, what is your mood today?&lt;br&gt;
&lt;b&gt;Description:&lt;/b&gt; Some helpful pointers about how to rate your mood.&lt;br&gt;
&lt;b&gt;LabelledBy:&lt;/b&gt; mood&lt;br&gt;
&lt;b&gt;DescribedBy:&lt;/b&gt; helperText&lt;br&gt;
&lt;b&gt;ValueNow:&lt;/b&gt; 5&lt;br&gt;
&lt;b&gt;ValueMin:&lt;/b&gt; 1&lt;br&gt;
&lt;b&gt;ValueMax:&lt;/b&gt; 10&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Paragraph&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Role:&lt;/b&gt; Button&lt;br&gt;
&lt;b&gt;Name:&lt;/b&gt; Log Mood&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;On choosing host language semantics&lt;/h3&gt;

&lt;p&gt;Our sample markup mentions that it is preferred to use the HTML-native &lt;code&gt;button&lt;/code&gt; element rather than a &lt;code&gt;div&lt;/code&gt; with a &lt;code&gt;role&lt;/code&gt; of “button.” Our buttonified &lt;code&gt;div&lt;/code&gt; can be operated as a button via accessibility APIs, as the ARIA attribute is doing what it should—conveying semantics. But there’s a lot you can get for free when you choose native elements. In the case of &lt;code&gt;button&lt;/code&gt;, that includes focus handling, user input handling, form submission, and basic styling.&lt;/p&gt;

&lt;p&gt;Aaron Gustafson has what he refers to as an &lt;a href="https://www.smashingmagazine.com/2016/05/developing-dependency-awareness/"&gt;“exhaustive treatise” on buttons&lt;/a&gt; in particular, but generally speaking it’s great to let the web platform do the heavy lifting of semantics and interaction for us when we can.&lt;/p&gt;

&lt;p&gt;ARIA roles, states, and properties are still a great tool to have in your toolbelt. Some good use cases for these are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;providing further semantics and relationships that are not naturally expressed in the host language;&lt;/li&gt;
&lt;li&gt;supplementing semantics in markup we perhaps don’t have complete control over;&lt;/li&gt;
&lt;li&gt;patching potential cross-browser inconsistencies;&lt;/li&gt;
&lt;li&gt;and making custom elements perceivable and operable to users of assistive technologies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Notes on inclusion or exclusion in the tree&lt;/h3&gt;

&lt;p&gt;Standards define some rules around when user agents should exclude elements from the accessibility tree. Excluded elements can include those hidden by CSS, or the &lt;code&gt;aria-hidden&lt;/code&gt; or &lt;code&gt;hidden&lt;/code&gt; attributes; their children would be excluded as well. Children of particular roles (like &lt;code&gt;checkbox&lt;/code&gt;) can also be excluded from the tree, unless they meet special exceptions. The full rules can be found in the &lt;a href="https://www.w3.org/TR/wai-aria-1.2/#accessibility_tree"&gt;“Accessibility Tree” section of the ARIA specification&lt;/a&gt;. That being said, there are still some differences between implementers, some of which include more &lt;code&gt;div&lt;/code&gt;s and &lt;code&gt;span&lt;/code&gt;s in the tree than others do.&lt;/p&gt;

&lt;h3&gt;Notes on name and description computation&lt;/h3&gt;

&lt;p&gt;How names and descriptions are computed can be a bit confusing. Some elements have special rules, and some ARIA roles allow name computation from the element’s contents, whereas others do not. Name and description computation could probably be its own article, so we won’t get into all the details here (refer to “Further reading and resources” for some links). Some short pointers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;aria-label&lt;/code&gt;, &lt;code&gt;aria-labelledby&lt;/code&gt;, and &lt;code&gt;aria-describedby&lt;/code&gt; take precedence over other means of calculating name and description.&lt;/li&gt;
&lt;li&gt;If you expect a particular HTML attribute to be used for the name, check the &lt;a href="https://w3c.github.io/html-aam/#accessible-name-and-description-computation"&gt;name computation rules for HTML elements&lt;/a&gt;. In your scenario, it may be used for the full description instead.&lt;/li&gt;
&lt;li&gt;Generated content (&lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt;) can participate in the accessible name when said name is taken from the element’s contents. That being said, &lt;a href="https://www.w3.org/WAI/WCAG21/Techniques/failures/F87"&gt;web developers should not rely on pseudo-elements for non-decorative content&lt;/a&gt;, as this content could be lost when a stylesheet fails to load or user styles are applied to the page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When in doubt, reach out to the community! Tag questions on social media with “#accessibility.” “#a11y” is a common shorthand; the “11” stands for “11 middle letters in the word ‘accessibility.’” If you find an inconsistency in a particular browser, file a bug! Bug tracker links are provided in “Further reading and resources.”&lt;/p&gt;

&lt;h2&gt;Not just accessible objects&lt;/h2&gt;

&lt;p&gt;Besides a hierarchical structure of objects, accessibility APIs also offer interfaces that allow ATs to interact with text. ATs can retrieve content text ranges, text selections, and a variety of text attributes that they can build experiences on top of. For example, if someone writes an email and uses color alone to highlight their added comments, the person reading the email could increase the verbosity of speech output in their screen reader to know when they’re encountering phrases with that styling. However, it would be better for the email author to include very brief text labels in this scenario.&lt;/p&gt;

&lt;p&gt;The big takeaway here for web developers is to keep in mind that the accessible name of an element may not always be surfaced in every &lt;a href="https://tink.uk/understanding-screen-reader-interaction-modes/"&gt;navigation mode&lt;/a&gt; in every screen reader. So if your &lt;code&gt;aria-label&lt;/code&gt; text isn’t being read out in a particular mode, the screen reader may be primarily using text interfaces and only conditionally stopping on objects. It may be worth your while to consider using text content—even if &lt;a href="https://a11yproject.com/posts/how-to-hide-content/"&gt;visually hidden&lt;/a&gt;—instead of text via an ARIA attribute. &lt;a href="https://developer.paciellogroup.com/blog/2017/07/short-note-on-aria-label-aria-labelledby-and-aria-describedby/"&gt;Read more thoughts on &lt;code&gt;aria-label&lt;/code&gt; and &lt;code&gt;aria-labelledby&lt;/code&gt;.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Accessibility API events&lt;/h2&gt;

&lt;p&gt;It is the responsibility of browsers to surface changes to content, structure, and user input. Browsers do this by sending the accessibility API notifications about various events, which screen readers can subscribe to; again, for performance reasons, browsers could choose to send notifications only when ATs are active.&lt;/p&gt;

&lt;p&gt;Let’s suppose that a screen reader wants to surface changes to a live region (an element with &lt;code&gt;role="alert"&lt;/code&gt; or &lt;code&gt;aria-live&lt;/code&gt;):&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig5.png" alt="Diagram showing a client (screen reader), which is already subscribed to live region events and can request more info about the live region, which receives a notification from the accessibility API, which gets a notification that a live region has changed from the provider (browser), which has a live region changed by the web document"&gt;
&lt;figcaption&gt;Diagram illustrating the steps involved in announcing a live region via a screen reader; detailed list follows&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;ol&gt;
&lt;li&gt;The screen reader subscribes to event notifications; it could subscribe to notifications of all types, or just certain types as categorized by the accessibility API. Let’s assume in our example that the screen reader is at least listening to live region change events.&lt;/li&gt;
&lt;li&gt;In the web content, the web developer changes the text content of a live region.&lt;/li&gt;
&lt;li&gt;The browser (provider) recognizes this as a live region change event, and sends the accessibility API a notification.&lt;/li&gt;
&lt;li&gt;The API passes this notification along to the screen reader.&lt;/li&gt;
&lt;li&gt;The screen reader can then use metadata from the notification to look up the relevant accessible objects via the accessibility API, and can surface the changes to the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ATs aren’t required to do anything with the information they retrieve. This can make it a bit trickier as a web developer to figure out why a screen reader isn’t announcing a change: it may be that notifications aren’t being raised (for example, because a browser is not sending notifications for a live region dynamically inserted into web content), or the AT is not subscribed or responding to that type of event.&lt;/p&gt;

&lt;h2&gt;Testing with screen readers and dev tools&lt;/h2&gt;

&lt;p&gt;While conformance checkers can help catch some basic accessibility issues, it’s ideal to walk through your content manually using a variety of contexts, such as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using a keyboard only;&lt;/li&gt;
&lt;li&gt;with various OS accessibility settings turned on;&lt;/li&gt;
&lt;li&gt;and at different zoom levels and text sizes, and so on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you do this, keep in mind the &lt;a href="https://www.w3.org/TR/WCAG21/"&gt;&lt;cite&gt;Web Content Accessibility Guidelines (WCAG 2.1)&lt;/cite&gt;&lt;/a&gt;, which give general guidelines around expectations for inclusive web content. If you can test with users after your own manual test passes, all the better!&lt;/p&gt;

&lt;p&gt;Robust accessibility testing could probably be its own series of articles. In this one, we’ll go over some tips for testing with screen readers, and catching accessibility errors as they are mapped into the accessibility API in a more general sense.&lt;/p&gt;

&lt;h3&gt;Screen reader testing&lt;/h3&gt;

&lt;p&gt;Screen readers exist in many forms: some are pre-installed on the operating system and others are separate applications that in some cases are free to download. The &lt;a href="https://webaim.org/projects/screenreadersurvey7/"&gt;WebAIM screen reader user survey&lt;/a&gt; provides a list of commonly used screen reader and browser combinations among survey participants. The “Further reading and resources” section at the end of this article includes full screen reader user docs, and Deque University has a great set of &lt;a href="https://dequeuniversity.com/resources/"&gt;screen reader command cheat sheets&lt;/a&gt; that you can refer to. Some actions you might take to test your content:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the next/previous item.&lt;/li&gt;
&lt;li&gt;Read the next/previous line.&lt;/li&gt;
&lt;li&gt;Read continuously from a particular point.&lt;/li&gt;
&lt;li&gt;Jump by headings, landmarks, and links.&lt;/li&gt;
&lt;li&gt;Tab around focusable elements only.&lt;/li&gt;
&lt;li&gt;Get a summary of all elements of a particular type within the page.&lt;/li&gt;
&lt;li&gt;Search the page for specific content.&lt;/li&gt;
&lt;li&gt;Use table-specific commands to interact with your tables.&lt;/li&gt;
&lt;li&gt;Jump around by form field; are field instructions discoverable in this navigational mode?&lt;/li&gt;
&lt;li&gt;Use keyboard commands to interact with all interactive elements. Are your JavaScript-driven interactions still operable with screen readers (which can intercept key input in certain modes)? &lt;a href="https://www.w3.org/TR/wai-aria-practices/#aria_ex"&gt;&lt;cite&gt;WAI-ARIA Authoring Practices 1.1&lt;/cite&gt;&lt;/a&gt; includes notes on expected keyboard interactions for various widgets.&lt;/li&gt;
&lt;li&gt;Try out anything that creates a content change or results in navigating elsewhere. Would it be obvious, via screen reader output, that a change occurred?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Tracking down the source of unexpected behavior&lt;/h3&gt;

&lt;p&gt;If a screen reader does not announce something as you’d expect, here are a few different checks you can run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Does this reproduce with the same screen reader in multiple browsers on this OS?&lt;/b&gt; It may be an issue with the screen reader or your expectation may not match the screen reader’s user experience design. For example, a screen reader may choose to not expose the accessible name of a static, non-interactive element. Checking the user docs or filing a screen reader issue with a simple test case would be a great place to start.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Does this reproduce with multiple screen readers in the same browser, but not in other browsers on this OS?&lt;/b&gt; The browser in question may have an issue, there may be compatibility differences between browsers (such as a browser doing extra helpful but non-standard computations), or a screen reader’s support for a specific accessibility API may vary. Filing a browser issue with a simple test case would be a great place to start; if it’s not a browser bug, the developer can route it to the right place or make a code suggestion.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Does this reproduce with multiple screen readers in multiple browsers?&lt;/b&gt; There may be something you can adjust in your code, or your expectations may differ from standards and common practices.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;How does this element’s accessibility properties and structure show up in browser dev tools?&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Inspecting accessibility trees and properties in dev tools&lt;/h3&gt;

&lt;p&gt;Major modern browsers provide dev tools to help you observe the structure of the accessibility tree as well as a given element’s accessibility properties. By observing which accessible objects are generated for your elements and which properties are exposed on a given element, you may be able to pinpoint issues that are occurring either in front-end code or in how the browser is mapping your content into the accessibility API.&lt;/p&gt;

&lt;p&gt;Let’s suppose that we are testing this piece of code in Microsoft Edge with a screen reader:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-markup"&gt;&amp;lt;div class="form-row"&amp;gt;
  &amp;lt;label&amp;gt;Favorite color&amp;lt;/label&amp;gt;
  &amp;lt;input id="myTextInput" type="text" /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We’re navigating the page by form field, and when we land on this text field, the screen reader just tells us this is an “edit” control—it doesn’t mention a name for this element. Let’s check the tools for the element’s accessible name.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;1. Inspect the element to bring up the dev tools.&lt;/b&gt;&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig6.png" alt="Screenshot showing the Microsoft Edge dev tools inspecting an input element"&gt;
&lt;figcaption&gt;The Microsoft Edge dev tools, with an input element highlighted in the DOM tree&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;b&gt;2. Bring up the accessibility tree for this page by clicking the accessibility tree button (a circle with two arrows) or pressing Ctrl+Shift+A (Windows).&lt;/b&gt;&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig7.png" alt="Screenshot showing the Microsoft Edge tools inspecting an input element with the Accessibility Tree panel open"&gt;
&lt;figcaption&gt;The accessibility tree button activated in the Microsoft Edge dev tools&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Reviewing the accessibility tree is an extra step for this particular flow but can be helpful to do.&lt;/p&gt;

&lt;p&gt;When the Accessibility Tree pane comes up, we notice there’s a tree node that just says “textbox:,” with nothing after the colon. That suggests there’s not a name for this element. (Also notice that the &lt;code&gt;div&lt;/code&gt; around our form input didn’t make it into the accessibility tree; it was not semantically useful).&lt;/p&gt;

&lt;p&gt;&lt;b&gt;3. Open the Accessibility Properties pane, which is a sibling of the Styles pane.&lt;/b&gt; If we scroll down to the Name property—aha! It’s blank. No name is provided to the accessibility API. (Side note: some other accessibility properties are filtered out of this list by default; toggle the filter button—which looks like a funnel—in the pane to get the full list).&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig8.png" alt="Screenshot showing the Microsoft Edge tools inspecting an input element with the Accessibility Tree panel open"&gt;
&lt;figcaption&gt;The Accessibility Properties pane open in Microsoft Edge dev tools, in the same area as the Styles pane&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;b&gt;4. Check the code.&lt;/b&gt; We realize that we didn’t associate the &lt;code&gt;label&lt;/code&gt; with the text field; that is one strategy for providing an &lt;a href="https://w3c.github.io/html-aam/#input-type-text-input-type-password-input-type-search-input-type-tel-input-type-url-and-textarea-element"&gt;accessible name for a text input&lt;/a&gt;. We add &lt;code&gt;for="myTextInput"&lt;/code&gt; to the label:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-markup"&gt;&amp;lt;div class="form-row"&amp;gt;
  &amp;lt;label for="myTextInput"&amp;gt;Favorite color&amp;lt;/label&amp;gt;
  &amp;lt;input id="myTextInput" type="text" /&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now the field has a name:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig9.png" alt="Screenshot showing the Microsoft Edge tools inspecting an input element with the Accessibility Tree panel open, where the input's Name attribute now has a value"&gt;
&lt;figcaption&gt;The accessible Name property set to the value of “Favorite color” inside Microsoft Edge dev tools&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;In another use case, we have a breadcrumb component, where the current page link is marked with &lt;code&gt;aria-current="page"&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-markup"&gt;&amp;lt;nav class="breadcrumb" aria-label="Breadcrumb"&amp;gt;
  &amp;lt;ol&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;a href="/cat/"&amp;gt;Category&amp;lt;/a&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;a href="/cat/sub/"&amp;gt;Sub-Category&amp;lt;/a&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;a aria-current="page" href="/cat/sub/page/"&amp;gt;Page&amp;lt;/a&amp;gt;
    &amp;lt;/li&amp;gt;
  &amp;lt;/ol&amp;gt;
&amp;lt;/nav&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When navigating onto the current page link, however, we don’t get any indication that this is the current page. We’re not exactly sure how this maps into accessibility properties, so we can reference a specification like &lt;cite&gt;Core Accessibility API Mappings 1.2&lt;/cite&gt; (Core-AAM). Under the “&lt;a href="https://w3c.github.io/core-aam/#mapping_state-property"&gt;State and Property Mapping&lt;/a&gt;” table, we find mappings for “&lt;code&gt;aria-current&lt;/code&gt; with non-&lt;code&gt;false&lt;/code&gt; allowed value.” We can check for these listed properties in the Accessibility Properties pane. Microsoft Edge, at the time of writing, maps into UIA (UI Automation), so when we check AriaProperties, we find that yes, “current=page” is included within this property value.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/semantics-to-screen-readers/fig10.png" alt="Screenshot showing the Microsoft Edge tools inspecting an input element with the Accessibility Tree panel open, where the input's AriaProperties attribute now has a value of current=page"&gt;
&lt;figcaption&gt;The accessible Name property set to the value of “Favorite color” inside Microsoft Edge dev tools&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Now we know that the value is presented correctly to the accessibility API, but the particular screen reader is not using the information.&lt;/p&gt;

&lt;p&gt;As a side note, Microsoft Edge’s current dev tools expose these accessibility API properties quite literally. Other browsers’ dev tools may simplify property names and values to make them easier to read, particularly if they support more than one accessibility API. The important bit is to find if there’s a property with roughly the name you expect and whether its value is what you expect. You can also use this method of checking through the property names and values if mapping specs, like Core-AAM, are a bit intimidating!&lt;/p&gt;

&lt;h3&gt;Advanced accessibility tools&lt;/h3&gt;

&lt;p&gt;While browser dev tools can tell us a lot about the accessibility semantics of our markup, they don’t generally include representations of text ranges or event notifications. On Windows, the &lt;a href="https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk"&gt;Windows SDK&lt;/a&gt; includes advanced tools that can help debug these parts of MSAA or UIA mappings: &lt;a href="https://docs.microsoft.com/en-us/windows/desktop/winauto/inspect-objects"&gt;Inspect&lt;/a&gt; and &lt;a href="https://docs.microsoft.com/en-us/windows/desktop/winauto/accessible-event-watcher"&gt;AccEvent&lt;/a&gt; (Accessible Event Watcher). Using these tools presumes knowledge of the Windows accessibility APIs, so if this is too granular for you and you’re stuck on an issue, please reach out to the relevant browser team!&lt;/p&gt;

&lt;p&gt;There is also an Accessibility Inspector in Xcode on MacOS, with which you can inspect web content in Safari. This tool can be accessed by going to &lt;b&gt;Xcode &gt; Open Developer Tool &gt; Accessibility Inspector&lt;/b&gt;.&lt;/p&gt;

&lt;h2&gt;Diversity of experience&lt;/h2&gt;

&lt;p&gt;Equipped with an accessibility tree, detailed object information, event notifications, and methods for interacting with accessible objects, screen readers can craft a browsing experience tailored to their audiences. In this article, we’ve used the term “screen readers” as a proxy for a whole host of tools that may use accessibility APIs to provide the best user experience possible. Assistive technologies can use the APIs to augment presentation or support varying types of user input. Examples of other ATs include screen magnifiers, cognitive support tools, speech command programs, and some brilliant new app that hasn’t been dreamed up yet. Further, assistive technologies of the same “type” may differ in how they present information, and users who share the same tool may further adjust settings to their liking.&lt;/p&gt;

&lt;p&gt;As web developers, we don’t necessarily need to make sure that each instance surfaces information identically, because each user’s preferences will not be exactly the same. Our aim is to ensure that no matter how a user chooses to explore our sites, content is &lt;a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/intro.html#introduction-fourprincs-head"&gt;perceivable, operable, understandable, and robust&lt;/a&gt;. By testing with a variety of assistive technologies—including but not limited to screen readers—we can help create a better web for all the many people who use it.&lt;/p&gt;

&lt;h2&gt;Further reading and resources&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://webaim.org/projects/lowvisionsurvey2/"&gt;WebAIM “Survey of Users with Low Vision”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webaim.org/projects/screenreadersurvey7/"&gt;WebAIM “Screen Reader User Survey”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;W3C developer guides
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/WAI/roles/"&gt;W3C Web Accessibility Initiative (WAI) resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/WCAG21/"&gt;&lt;cite&gt;Web Content Accessibility Guidelines (WCAG) 2.1&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/wai-aria-practices-1.1/"&gt;&lt;cite&gt;WAI-ARIA Authoring Practices 1.1&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/html-aria/"&gt;&lt;cite&gt;ARIA in HTML&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/using-aria/"&gt;&lt;cite&gt;Using ARIA&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;W3C specifications: The docs below are known as “AAMs.” They detail how content maps into various accessibility APIs and may be less relevant to web developers’ day-to-day work. However, some have notes on how specific elements’ names and descriptions are meant to be calculated:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/core-aam-1.1/"&gt;&lt;cite&gt;Core Accessibility API Mappings 1.1&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/graphics-aam-1.0/"&gt;&lt;cite&gt;Graphics Accessibility API Mappings&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/html-aam-1.0/"&gt;&lt;cite&gt;HTML Accessibility API Mappings 1.0&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/svg-aam-1.0/"&gt;&lt;cite&gt;SVG Accessibility API Mappings&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://inclusive-components.design/"&gt;&lt;cite&gt;Inclusive Components&lt;/cite&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://alistapart.com/topic/accessibility"&gt;&lt;cite&gt;A List Apart&lt;/cite&gt; articles on accessibility&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://alistapart.com/article/conversational-semantics"&gt;“Conversational Semantics”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://alistapart.com/column/wai-finding-with-aria-landmark-roles"&gt;“WAI-finding with ARIA Landmark Roles”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.smashingmagazine.com/2018/09/importance-manual-accessibility-testing/"&gt;“The Importance of Manual Accessibility Testing”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dequeuniversity.com/resources/"&gt;Deque University screen reader shortcuts references&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Screen reader user docs (commands)&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.freedomscientific.com/products/blindness/jawsdocumentation"&gt;JAWS user docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.microsoft.com/en-us/help/22798/windows-10-complete-guide-to-narrator"&gt;Narrator user docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nvaccess.org/files/nvda/documentation/userGuide.html"&gt;NVDA user docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://help.apple.com/voiceover/mac/10.14/"&gt;VoiceOver user docs (VoiceOver command charts)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://help.apple.com/iphone/10/#/iph3e2e415f"&gt;iOS VoiceOver user docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Browser rendering engine bug trackers&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bugs.chromium.org/p/chromium/issues/list"&gt;Chrome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugzilla.mozilla.org/describecomponents.cgi?product=Core"&gt;Firefox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://issues.microsoftedge.com/"&gt;Microsoft Edge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugs.webkit.org/query.cgi?format=specific&amp;amp;product=WebKit"&gt;Safari&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/2VWN4n_FhyE" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Browsers, Accessibility
]]></dc:subject>
      <dc:date>2019-02-28T13:37:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/semantics-to-screen-readers</feedburner:origLink></item><item>
      <title><![CDATA[Designing for Conversions]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/brandongregory">Brandon Gregory</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/PpJ7Dft25AM/designing-for-conversions</link>
      <guid isPermaLink="false">http://alistapart.com/article/designing-for-conversions</guid>
      <description>&lt;p&gt;What makes creative successful? Creative work often lives in the land of feeling—we can say we like something, point to how happy the client is, or talk about how delighted users will be, but can’t objectively measure feelings. Measuring the success of creative work doesn’t have to stop with feeling. In fact, we can assign it numbers, do math with it, and track improvement to show clients objectively how well our creative is working for them.&lt;/p&gt;

&lt;p&gt;David Ogilvy once said, “If it doesn’t sell, it isn’t creative.” While success may not be a tangible metric for us, it is for our clients. They have hard numbers to meet, and as designers, we owe it to them to think about how our work can meet those goals. We can track sales, sure, but websites are ripe with other opportunities for measuring improvements. Designing for conversions will not only make you a more effective designer or copywriter, it will make you much more valuable to your clients, and that’s something we should all seek out.&lt;/p&gt;

&lt;h2&gt;Wait—what’s a conversion?&lt;/h2&gt;

&lt;p&gt;Before designing for conversions, let’s establish a baseline for what, exactly, we’re talking about. A &lt;i&gt;conversion&lt;/i&gt; is an action taken by the user that accomplishes a business goal. If your site sells things, a conversion would be a sale. If you collect user information to achieve your business goals, like lead aggregation, it would be a form submission. Conversions can also be things like newsletter sign-ups or even hits on a page containing important information that you need users to read. You need some tangible action to measure the success of your site—that’s your conversion.&lt;/p&gt;

&lt;p&gt;Through analytics, you know how many people are coming to your site. You can use this to measure what percentage of users are converting. This number is your &lt;i&gt;conversion rate&lt;/i&gt;, and it’s the single greatest metric for measuring the success of a creative change. In your analytics, you can set up goals and conversion funnels to track this for you (more on conversion funnels shortly). It doesn’t matter how slick that new form looks or how clever that headline is—if the conversion rate drops, it’s not a success. In fact, once you start measuring success by conversion rate, you’ll be surprised to see how even the cleverest designs applied in the wrong places can fail to achieve your goals.&lt;/p&gt;

&lt;p&gt;Conversions aren’t always a one-step process. Many of us have multi-step forms or long check-out processes where it can be very useful to track how far a user gets. It’s possible to set up multiple goals along the way so your analytics can give you this data. This is called a &lt;i&gt;conversion funnel&lt;/i&gt;. Ideally, you’ll coordinate with the rest of your organization to get data beyond the website as well. For instance, changing button copy may lead to increased form submissions but a drop in conversions from lead to sale afterward. In this case, the button copy update probably confused users rather than selling them on the product. A good conversion funnel will safeguard against false positives like that.&lt;/p&gt;

&lt;p&gt;It’s also important to track the &lt;i&gt;bounce rate&lt;/i&gt;, which is the percentage of  users that hit a page and leave without converting or navigating to other pages. A higher bounce rate is an indication that there’s a mismatch between the user’s expectations when landing on your site and what they find once landing there. Bounce rate is really a part of the conversion funnel, and reducing bounce rate can be just as important as improving conversion rate.&lt;/p&gt;

&lt;h2&gt;Great. So how do we do that?&lt;/h2&gt;

&lt;p&gt;When I was first getting started in conversion-driven design, it honestly felt a little weird. It feels shady to focus obsessively on getting the user to complete an action. But this focus is in no way about tricking the user into doing something they don’t want to do—that’s a bad business model. As Gerry McGovern has commented, if business goals don’t align with customer goals, your business has no future. So if we’re not tricking users, what &lt;em&gt;are&lt;/em&gt; we doing?&lt;/p&gt;

&lt;p&gt;Users come to your site with a problem, and they’re looking for a solution. The goal is to find users whose problems will be solved by choosing your product. With that in mind, improving the conversion rate doesn’t mean tricking users into doing something—it means showing the &lt;em&gt;right&lt;/em&gt; users how to solve their problem. That means making two things clear: that your product will solve the user’s problem, and what the user must do to proceed.&lt;/p&gt;

&lt;p&gt;The first of these two points is the &lt;i&gt;value proposition&lt;/i&gt;. This is how the user determines whether your product can solve his or her problem. It can be a simple description of the benefits, customer testimonials, or just a statement about what the product will do for the user. A page is not limited to one value proposition—it’s good to have several. (Hint: the page’s headline should almost always be a value proposition!) The user should be able to determine quickly why your product will be helpful in solving their problem. Once the value of your product has been made clear, you need to direct the user to convert with a call to action.&lt;/p&gt;

&lt;p&gt;A &lt;i&gt;call to action&lt;/i&gt; tells the user what they must do to solve their problem—which, in your case, means to convert. Most buttons and links should be calls to action, but a bit of copy directly following a value proposition is a good place too. Users should never have to look around to find out what the next step is—it should be easy to spot and clear in its intention. Also, ease of access is a big success factor here. My team’s testing found that replacing a Request Information button (that pointed to a form page) with an actual form on every page significantly boosted the conversion rate. If you’re also trying to get information from a user, consider a big form at the top of the page so users can’t miss it. When they scroll down the page and are ready to convert, they remember the form and have no question as to what they have to do.&lt;/p&gt;

&lt;p&gt;So improving conversion rate (and, to some degree, decreasing bounce rate) is largely about adding clarity around the value proposition and call to action. There are other factors as well, like decreasing friction in the conversion process and improving performance, but these two things are where the magic happens, and conversion problems are usually problems with one of them.&lt;/p&gt;

&lt;h2&gt;So, value propositions…how do I do those?&lt;/h2&gt;

&lt;p&gt;The number one thing to remember when crafting a value proposition is that you’re not selling a product—you’re selling a solution. Value propositions begin with the user’s problem and focus on that. Users don’t care about the history of your company, how many awards you’ve won, or what clever puns you’ve come up with—they care about whether your product will solve their problem. If they don’t get the impression that it can do that, they will leave and go to a competitor.&lt;/p&gt;

&lt;p&gt;In my work with landing pages for career schools, we initially included pictures of people in graduation gowns and caps. We assumed that the most exciting part of going back to school was graduating. Data showed us that we were wrong. Our testing showed that photos of people doing the jobs they would be training for performed much better. In short, our assumption was that showing the product (the school) was more important than showing the benefit (a new career). The problem users were trying to solve wasn’t a diploma—it was a career, and focusing on the user showed a significant improvement in conversion rate.&lt;/p&gt;

&lt;p&gt;We had some clients that insisted on using their branding on the landing pages, including one school that wanted to use an eagle as their hero image because their main website had eagles everywhere. This absolutely bombed in conversions. No matter how strong or consistent your branding is, it will not outperform talking about users and their problems.&lt;/p&gt;

&lt;p&gt;Websites that get paid for clicks have mastered writing headlines this way. Clickbait headlines get a groan from copywriters—especially since they often use their powers for evil and not good—but there are some important lessons we can learn from them. Take this headline, for instance:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Get an Associate’s degree in nursing&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Just like in the example above with the college graduates, we’re selling the product—not the benefit. This doesn’t necessarily show that we understand the user’s problem, and it does nothing to get them excited about our program. Compare that headline to this one:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Is your job stuck in a rut? Get trained for a new career in nursing in only 18 months!&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;In this case, we lead with the user’s problem. That immediately gets users’ attention. We then skip to a benefit: a quick turnaround. No time is wasted talking about the product—we save that for the body copy. The headline focuses entirely on the user.&lt;/p&gt;

&lt;p&gt;In your sign-up or check-out process, always lead with the information the user is most interested in. In our case, letting the user first select their school campus and area of study showed a significant improvement over leading with contact information. Similarly, put the less-exciting content last. In our testing, users were least excited about sharing their telephone number. Moving that field to be the last one in the form decreased form abandonment and improved conversions.&lt;/p&gt;

&lt;p&gt;As designers, be cognizant of what your copywriters are doing. If the headline is the primary value proposition (as it should be), make sure the headline is the focal point of your design. Ensure the messaging behind your design is in line with the messaging in the content. If there’s a disagreement in what the user’s problem is or how your product will solve that problem, the conversion rate will suffer.&lt;/p&gt;

&lt;p&gt;Once the value proposition has been clearly defined and stated, it’s time to focus on the call to action.&lt;/p&gt;

&lt;h2&gt;What about the call to action?&lt;/h2&gt;

&lt;p&gt;For conversion-driven sites, a good call to action is the most important component. If a user is ready to convert and has insufficient direction on how to do so, you lose a sale at 90 percent completion. It needs to be abundantly clear to the user how to proceed, and that’s where the call to action steps in.&lt;/p&gt;

&lt;p&gt;When crafting a call to action, don’t be shy. Buttons should be large, forms should be hard to miss, and language should be imperative. A call to action should be one of the first things the user notices on the page, even if he or she won’t be thinking about it again until after doing some research on the page. Having the next step right in front of the user vastly increases the chance of conversion, so users need to know that it’s there waiting.&lt;/p&gt;

&lt;p&gt;That said, a call to action should never get in the way of a value proposition. I see this all the time: a modal window shows as soon as I get to a site, asking me to subscribe to their mailing list before I have an inkling of the value the site can give me. I dismiss these without looking, and that call to action is completely missed. Make it clear &lt;em&gt;how&lt;/em&gt; to convert, and make it easy, but don’t ask for a conversion before the user is ready. For situations like the one above, a better strategy might be asking me to subscribe as I exit the site; marketing to visitors who are leaving &lt;a href="https://beeketing.com/blog/best-exit-intent-coupon-pop-ups/"&gt;has been shown to be effective&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In my former team’s tests, there were some design choices that could improve calls to action. For instance, picking a bright color that stood out from the rest of the site for the submit button did show an improvement in conversions, and &lt;a href="https://www.ironpaper.com/webintel/articles/content-analytics/"&gt;reducing clutter around the call to action improved conversion rates by 232%&lt;/a&gt;. But most of the gains here were in either layout or copy; don’t get so caught up in minor design changes that you ignore more significant changes like these.&lt;/p&gt;

&lt;p&gt;Ease of access is another huge factor to consider. As mentioned above, when my team was getting started, we had a Request Information link in the main navigation and a button somewhere on the page that would lead the user to the form. The single biggest positive change we saw involved putting a form at the top of every page. For longer forms, we would break this form up into two or three steps, but having that first step in sight was a huge improvement, even if one click doesn’t seem like a lot of effort.&lt;/p&gt;

&lt;p&gt;Another important element is headings. Form headings should ask the user to do something. It’s one thing to label a form “Request Information”; it’s another to ask them to “Request Information Now.” Simply adding &lt;a href="https://blog.wishpond.com/post/103290853633/the-25-best-words-to-use-in-your-call-to-action"&gt;action words&lt;/a&gt;, like “now” or “today,” can change a description into an imperative action and improve conversion rates.&lt;/p&gt;

&lt;p&gt;With submit buttons, always take the opportunity to communicate value. The worst thing you can put on a submit button is the word “Submit.” We found that switching this button copy out with “Request Information” showed a significant improvement. Think about the implied direction of the interaction. “Submit” implies the user is giving something to us; “Request Information” implies we’re giving something to the user. The user is already apprehensive about handing over their information—communicate to them that they’re getting something out of the deal.&lt;/p&gt;

&lt;p&gt;Changing phrasing to be more personal to the user can also be very effective. One study showed that writing button copy in first person—for instance, “Create My Account” versus “Create Your Account”—&lt;a href="https://unbounce.com/a-b-testing/failed-ab-test-results/"&gt;showed a significant boost in conversions&lt;/a&gt;, boosting click-through rates by 90%.&lt;/p&gt;

&lt;p&gt;Users today are fearful that their information will be used for nefarious purposes. Make it a point to reassure them that their data is safe. Our testing showed that the best way to do this is to add a link to the privacy policy (“Your information is secure!”) with a little lock icon right next to the submit button. Users will often skip right over a small text link, so that lock icon is essential—so essential, in fact, that it may be more important than the privacy policy itself. I’m somewhat ashamed to admit this, but I once forgot to create a page for the privacy policy linked to from a landing page, so that little lock icon linked out to a 404. I expected a small boost in conversions when I finally uploaded the privacy policy, but nope—nobody noticed. Reassurance is a powerful thing.&lt;/p&gt;

&lt;h2&gt;Measure, measure, measure&lt;/h2&gt;

&lt;p&gt;One of the worst things you can do is push out a creative change, assume it’s great, and move on to the next task. &lt;a href="https://alistapart.com/article/a-primer-on-a-b-testing"&gt;A/B testing&lt;/a&gt; is ideal and will allow you to test a creative change directly against the old creative, eliminating other variables like time, media coverage, and anything else you might not be thinking of. Creative changes should be applied methodically and scientifically—just because two or three changes together show an improvement in conversion rate doesn’t mean that one of them wouldn’t perform better alone.&lt;/p&gt;

&lt;p&gt;Measuring tangible things like conversion rate not only helps your client or business, but can also give new purpose to your designs and creative decisions. It’s a lot easier to push for your creative decisions when you have hard data to back up why they’re the best choice for the client or project. Having this data on hand will give you more authority in dealing with clients or marketing folks, which is good for your creative and your career. If my time in the design world has taught me anything, it’s that, in the realm of creativity, certainty can be hard to come by. So, perhaps most importantly, objective measures of success give you, and your client, the reassurance that you’re doing the right thing.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/PpJ7Dft25AM" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Design, Business
]]></dc:subject>
      <dc:date>2019-02-14T15:30:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/designing-for-conversions</feedburner:origLink></item><item>
      <title><![CDATA[Paint the Picture, Not the Frame: How Browsers Provide Everything Users Need]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/ericbailey">Eric Bailey</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/2DiF9aUHrmA/paint-the-picture-not-the-frame</link>
      <guid isPermaLink="false">http://alistapart.com/article/paint-the-picture-not-the-frame</guid>
      <description>&lt;p&gt;Kip Williams, professor of psychology sciences at Purdue University, conducted &lt;a href="https://en.m.wikipedia.org/wiki/Social_rejection#Ball_toss_/_cyberball_experiments"&gt;a fascinating experiment&lt;/a&gt; called “cyberball.” In his experiment, a test subject and two other participants played a computer game of catch. At a predetermined time, the test subject was excluded from the game, forcing them to only observe as the clock ran down.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/paint-the-picture-not-the-frame/cyberball.jpg" alt="From the cyberball game, three outlined figures playing catch. Player 1 is mid-throw to Player 3."&gt;	
&lt;/figure&gt;

&lt;p&gt;The experience showed increases in self-reported levels of anger and sadness, as well as lowering levels of &lt;a href="https://the-mouse-trap.com/2017/09/09/the-four-needs-for-meaning/"&gt;the four needs&lt;/a&gt;. The digital version of the experiment created results that matched the results of &lt;a href="https://psycnet.apa.org/record/1999-10159-002"&gt;the original physical one&lt;/a&gt;, meaning that these feelings occurred regardless of context.&lt;/p&gt;

&lt;p&gt;After the game was concluded, the test subject was told that the other participants were robots, not other human participants. Interestingly, the reveal of automated competitors did not lessen the negative feelings reported. In fact, it &lt;em&gt;increased&lt;/em&gt; feelings of anger, while also decreasing participants’ sense of willpower and/or self-regulation.&lt;/p&gt;

&lt;p&gt;In other words: people who feel they are rejected by a digital system will feel hurt and have their sense of autonomy reduced, even when they believe there isn’t another human directly responsible.&lt;/p&gt;

&lt;h2&gt;So, what does this have to with browsers?&lt;/h2&gt;

&lt;p&gt;Every adjustment to the appearance and behavior of the features browsers let you manipulate is a roll of the dice, gambling on the delight of some at the expense of alienating others.&lt;/p&gt;

&lt;p&gt;When using a browser to navigate the web, there’s &lt;a href="https://louderthanten.com/coax/design-machines"&gt;a lot of sameness&lt;/a&gt;, until there isn&amp;#8217;t. Most of the time we’re hopping from page-to-page and site-to-site, clicking links, pressing buttons, watching videos, filling out forms, writing messages, etc. But every once in awhile we stumble across something new and novel that makes us pause to figure out what’s going on.&lt;/p&gt;

&lt;p&gt;Every website and web app is its own self-contained experience, with its own ideas of how things should look and behave. Some are closer to others, but each one requires learning how to operate the interface to a certain degree.&lt;/p&gt;

&lt;p&gt;Some browsers can also have parts of their functionality and appearance altered, meaning that as with websites, there can be unexpected discrepancies. We’ll unpack some of the nuance behind some of these features, and more importantly, why most of them are better off left alone.&lt;/p&gt;

&lt;h2&gt;Scroll-to-top&lt;/h2&gt;

&lt;p&gt;All the major desktop browsers allow you to hit the &lt;kbd&gt;Home&lt;/kbd&gt; key on the keyboard to jump to the top of the page. Some scrollbar implementations allow you to click on the top of the scrollbar area to do the same. Some browsers allow you to type &lt;kbd&gt;Command+Up&lt;/kbd&gt; (macOS) / &lt;kbd&gt;Ctrl+Up&lt;/kbd&gt; (Windows), as well. People who use assistive technology like screen readers can use things like &lt;a href="https://www.w3.org/TR/wai-aria-practices/examples/landmarks/"&gt;banner landmarks&lt;/a&gt; to navigate the same way (provided they are correctly declared in the site’s HTML).&lt;/p&gt;

&lt;p&gt;However, not every device has an easily discoverable way to invoke this functionality: many laptops don’t have a &lt;kbd&gt;Home&lt;/kbd&gt; key on their keyboard. The &lt;a href="https://9to5mac.com/2018/03/02/how-to-jump-top-of-webpages-twitter-facebook-iphone/"&gt;tap-the-clock-to-jump-to-the-top&lt;/a&gt; functionality on iOS is difficult to discover, and can be surprising and frustrating if accidentally activated. You need &lt;a href="https://matatk.agrip.org.uk/landmarks/"&gt;specialized browser extensions&lt;/a&gt; to recreate screen reader landmark navigation techniques.&lt;/p&gt;

&lt;p&gt;One commonly implemented UI solution for longer pages is the scroll-to-top button. It’s often fixed to the bottom-right corner of the screen. Activating this control will take the user to the top of the page, regardless of how far down they’ve scrolled.&lt;/p&gt;

&lt;p&gt;If your site features a large amount of content per page, it may be worth investigating this UI pattern. Try looking at analytics and/or conducting user tests to see where and how often this feature is used. The caveat being if it’s used too often, it might be worth taking a long, hard look at your information architecture and content strategy.&lt;/p&gt;

&lt;p&gt;Three things I like about the scroll-to-top pattern are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Its functionality is pretty obvious (especially if properly labeled).&lt;/li&gt;
&lt;li&gt;Provided it is designed well, it can provide a decent-sized touch target in &lt;a href="https://usabilla.com/blog/designing-thumbs-thumb-zone/"&gt;a thumb-friendly area&lt;/a&gt;. For &lt;a href="https://webaim.org/articles/motor/motordisabilities"&gt;motor control considerations&lt;/a&gt;, its touch target can be superior to narrow scroll or status bars, which can make for frustratingly small targets to hit.&lt;/li&gt;
&lt;li&gt;It does not alter or remove existing scroll behavior, augmenting it instead. If somebody is used to one way of scrolling to the top, you’re not overriding it or interrupting it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re implementing this sort of functionality, I have four requests to help make the experience work for everyone (I find the &lt;a href="https://github.com/cferdinandi/smooth-scroll"&gt;Smooth Scroll&lt;/a&gt; library to be a helpful starting place):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Honor user requests for &lt;a href="https://css-tricks.com/introduction-reduced-motion-media-query/"&gt;reduced motion&lt;/a&gt;. The dramatic scrolling effect of whipping from the bottom of the page to the top may be a &lt;a href="http://reverttosaved.com/2018/10/16/trying-to-explain-reduce-motion-to-designers-who-dont-have-a-vestibular-disorder/"&gt;vestibular trigger&lt;/a&gt;, a situation where the system that controls your body’s sense of physical position and orientation in the world is disrupted, causing things like headaches, nausea, vertigo, migraines, and hearing loss.&lt;/li&gt;
&lt;li&gt;Ensure keyboard focus is moved to the top of the document, mirroring what occurs visually. Applying this practice will improve &lt;em&gt;all&lt;/em&gt; users’ experiences. Otherwise, hitting &lt;kbd&gt;Tab&lt;/kbd&gt; after scrolling to the top would send the user down to the first interactive element that follows where the focus had been before they activated the scroll button.&lt;/li&gt;
&lt;li&gt;Ensure the button does not make other content unusable by obscuring it. Be sure to account for when the browser is in a zoomed-in state, not just in its default state.&lt;/li&gt;
&lt;li&gt;Be mindful of other fixed-position elements. I’ve seen my fair share of websites that also have a chatbot or &lt;a href="https://material.io/design/components/buttons-floating-action-button.html"&gt;floating action button&lt;/a&gt; competing to live in the same space.&lt;/li&gt;
&lt;/ul&gt;

&lt;figure&gt;
&lt;img src="/d/paint-the-picture-not-the-frame/floating-button.jpg" alt="A red chat icon overlaps with a corner of the scroll to top icon, obscuring a portion of the arrow."&gt;
&lt;/figure&gt;

&lt;h2&gt;Scrollbars&lt;/h2&gt;

&lt;p&gt;If you’re old enough to remember, it was once considered fashionable to style your website scrollbars. Internet Explorer allowed this customization via &lt;a href="https://www.hongkiat.com/blog/css-scroll-bar/"&gt;a series of vendor-specific properties&lt;/a&gt;. At best, they looked great! If the designer and developer were both skilled and detail-oriented, you’d get something that looked like a natural extension of the rest of the website. &lt;/p&gt;

&lt;p&gt;However, the stakes for a quality design were pretty high: scrollbars are part of an application’s interface, not a website’s. In inclusive design, it’s part of what we call &lt;a href="https://developer.paciellogroup.com/blog/2017/08/inclusive-design-principle-be-consistent/#culturalconsistency"&gt;&lt;em&gt;external consistency&lt;/em&gt;&lt;/a&gt;. External consistency is the idea that an object’s functionality is informed and reinforced by similar implementations elsewhere. It’s why you can flip a wall switch in most houses and be guaranteed the lights come on instead of flushing the toilet.&lt;/p&gt;

&lt;p&gt;While scrollbars have some minor visual differences between operating systems (and &lt;a href="https://imgur.com/a/q7nojaU"&gt;operating system versions&lt;/a&gt;), they’re consistent externally in function. Scrollbars are also consistent internally, in that every window and program on the OS that requires scrolling has the same scrollbar treatment.&lt;/p&gt;

&lt;p&gt;If you customize your website&amp;#8217;s scrollbar colors, for less technologically literate people, yet another aspect of the interface has changed without warning or instruction on how to change it back. If the user is  already confused about how things on the screen work, it’s one less familiar thing for them to cling to as stable and reliable. &lt;/p&gt;

&lt;p&gt;You might be rolling your eyes reading this, but I’d ask you to check out &lt;a href="https://jboriss.wordpress.com/2011/07/06/user-testing-in-the-wild-joes-first-computer-encounter/"&gt;this incredible article by Jennifer Morrow&lt;/a&gt; instead. In it, she describes conducting a guerilla user test at a mall, only to have the session completely derailed when she discovers someone who has never used a computer before.&lt;/p&gt;

&lt;p&gt;What she discovers is as important as it is shocking. The gist of it is that some people (even those who have used a computer before) don’t understand the nuance of the various “layers” you navigate through to operate a computer: the hardware, the OS, the browser installed on the OS, the website the browser is displaying, the website’s modals and disclosure statements, etc. To them, the experience is flat. &lt;/p&gt;

&lt;p&gt;We should not expect these users to juggle this kind of cognitive overhead. These kinds of abstractions are crafted to be &lt;a href="https://uxplanet.org/radio-buttons-ux-design-588e5c0a50dc#6500"&gt;analogous to real-world objects&lt;/a&gt;, specifically so people can get what they want from a digital system without having to be programmers. Adding unnecessary complexity weakens these metaphors and gives users one less reference point to rely on. &lt;/p&gt;

&lt;p&gt;Remember the cyberball experiment. When a user is already in a distressed emotional state, our poorly-designed custom scrollbar might be the death-by-a-thousand-paper-cuts moment where they give up on trying to get what they want and reject the system entirely.&lt;/p&gt;

&lt;p&gt;While Morrow’s article was written in 2011, it’s just as relevant now as it was then. More and more people are using the internet globally, and more and more services integral to living daily life are getting digitized. It’s up to us as responsible designers and developers to be sure we make everyone, regardless of device, circumstance, or ability feel welcome.&lt;/p&gt;

&lt;p&gt;In addition to unnecessarily abandoning external consistency, there is the issue of custom scrollbar styling potentially not having &lt;a href="https://a11yproject.com/posts/what-is-color-contrast/"&gt;sufficient color contrast&lt;/a&gt;. The too-light colors can create a situation where a person experiencing low-vision conditions won’t be able to perceive, and therefore operate, a website’s scrolling mechanism.&lt;/p&gt;

&lt;p&gt;This article won’t even begin to unpack the issues involved with custom implementations of scrollbars, where instead of theming the OS’s native scrollbars with CSS, one instead replaces them with a JavaScript solution. Trust me when I say I have yet to see one implemented in a way that could successfully and reliably recreate all features and functionality across all &lt;a href="https://manuals.playstation.net/document/en/ps4/browser/browse.html"&gt;devices&lt;/a&gt;, OSes, browsers, and &lt;a href="https://medium.com/@mandy.michael/building-websites-for-safari-reader-mode-and-other-reading-apps-1562913c86c9"&gt;browsing modes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In my opinion? Don’t alter the default appearance of an OS’s scrollbars. Use that time to work on something else instead, say, checking for and fixing color contrast problems.&lt;/p&gt;

&lt;h2&gt;Scrolling&lt;/h2&gt;

&lt;p&gt;The main concern about altering scrolling behavior is one of consent: it’s taking an externally consistent, system-wide behavior and suddenly altering it without permission. The term &lt;em&gt;scrolljacking&lt;/em&gt; has been coined to describe this practice. It is not to be confused with &lt;a href="https://pudding.cool/process/how-to-implement-scrollytelling/"&gt;&lt;em&gt;scrollytelling&lt;/em&gt;&lt;/a&gt;, a more considerate treatment of scrolling behavior that honors the OS’s scrolling settings.&lt;/p&gt;

&lt;p&gt;Altering the scrolling behavior on your website or web app can fly in the face of someone’s specific, expressed preferences. For some people, it’s simply an annoyance. For people with motor control concerns, it could make moving through a site difficult. In some extreme cases, the unannounced discrepancy between the amount of scrolling and the distance traveled can also be vestibular triggers. Another consideration is if your modified scrolling behavior &lt;a href="https://www.sitepoint.com/scrolljacking-accessibility/"&gt;accidentally locks out people&lt;/a&gt; who don’t use mice, touch, or trackpads to scroll. &lt;/p&gt;

&lt;p&gt;All in all, I think &lt;a href="https://robinrendle.com/notes/scrolljacking/"&gt;Robin Rendle said it best&lt;/a&gt;:&lt;/p&gt;

&lt;figure class="quote"&gt;
	&lt;blockquote&gt;Scrolljacking, as I shall now refer to it both sarcastically and honestly, is a failure of the web designer’s first objective; it attacks a standardised pattern and greedily assumes control over the user’s input.&lt;/blockquote&gt;
&lt;/figure&gt;

&lt;h2&gt;Highlighting&lt;/h2&gt;

&lt;p&gt;Another OS feature we’re permitted to style in the browser is highlighted text. Much like scrollbars, this is an interface element that is shared by all apps on the OS, not just the browser. &lt;/p&gt;

&lt;p&gt;Breaking the external consistency of the OS’s highlighting color has a lot of the same concerns as styled scrollbars, namely altering the expected behavior of something that functions reliably everywhere else. It’s potentially disorienting and alienating, and may deny someone’s expressed preferences.&lt;/p&gt;

&lt;p&gt;Some people highlight text as they read. If your custom highlight style has a low contrast ratio between the highlighted text color and the highlighted text’s background color, the person reading your website or web app may be unable to perceive the text they’re highlighting. The effect will cause the text to seemingly disappear as they try to read. &lt;/p&gt;

&lt;p&gt;Other people just may not care for your aesthetic sensibilities. Both macOS and Windows allow you to specify a custom highlight color. In a scenario where someone has deliberately set a preference other than the system default, a styled highlight color may override their stated specifications. &lt;/p&gt;

&lt;p&gt;For me, the potential risks far outweigh the vanity of a bespoke highlight style—better to just leave it be.&lt;/p&gt;

&lt;h2&gt;Text resizing&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://medium.com/@vamptvo/pixels-vs-ems-users-do-change-font-size-5cfb20831773"&gt;Lots of people change text size&lt;/a&gt; to suit their needs. And that’s a good thing. We want people to be able to read our content and act upon it, regardless of whatever circumstances they may be experiencing. &lt;/p&gt;

&lt;p&gt;For the problem of too-small text, some designers turn to text resizing widgets, a custom UI pattern that lets a person cycle through a number of preset CSS &lt;code&gt;font-size&lt;/code&gt; values. Commonly found in places with heavy text content, text resizing widgets are often paired with complex, multicolumn designs. News sites are a common example.&lt;/p&gt;

&lt;p&gt;Before I dive into my concerns with text resizing widgets, I want to ask: if you find that your site needs a specialized widget to manage your text size, why not just take the simpler route and &lt;a href="https://cushionapp.com/journal/improving-readability"&gt;increase your base text size&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Like many &lt;a href="https://thatcrazycrippledchick.blogspot.com/2013/12/this-is-what-disability-binarism-looks.html"&gt;accessibility concerns&lt;/a&gt;, a request for a larger font size isn’t necessarily indicative of &lt;a href="https://medium.com/@mosaicofminds/a-disability-is-a-mismatch-between-a-persons-abilities-and-their-environment-cc39e29e8e74"&gt;a permanent disability condition&lt;/a&gt;. It’s often circumstantial, such as a situation where you’re showing a website on your office’s crappy projector.&lt;/p&gt;

&lt;p&gt;Browsers allow users to change their preferred default font size, resizing text across websites accordingly. Browsers excel at handling this setting when you write CSS that takes advantage of &lt;a href="https://allthingssmitty.com/2017/01/30/nope-nope-nope-line-height-is-unitless/"&gt;unitless &lt;code&gt;line-height&lt;/code&gt; values&lt;/a&gt; and &lt;a href="https://thecssworkshop.com/lessons/relative-units"&gt;relative &lt;code&gt;font-size&lt;/code&gt; units&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Some designers may feel that granting this liberty to users somehow detracts from their intended branding. Good designers understand that there’s more to branding than just how something looks. It’s about implementing the initial design in the browser, then &lt;a href="https://css-tricks.com/building-resizeable-components-relative-css-units/"&gt;working &lt;em&gt;with&lt;/em&gt; the browser’s capabilities&lt;/a&gt; to best serve the person using it. Even if things like the font size are adjusted, a strong brand will still shine through with the ease of your user flows, quality of your typography and palette, strength of your copywriting, etc.&lt;/p&gt;

&lt;p&gt;Unfortunately, custom browser text resizing widgets lack a universal approach. If you rely on browser text settings, it just works—consistently, with the same controls, gestures, and keyboard shortcuts, for every page on every website, even in &lt;a href="https://kryogenix.org/code/browser/everyonehasjs.html"&gt;less-than-ideal conditions&lt;/a&gt;. You don’t have to write and maintain extra code, test for regressions, or write copy instructing the user on where to find your site’s text resizing widget and how to use it.&lt;/p&gt;

&lt;p&gt;Behavioral consistency is incredibly important. Browser text resizing is applied to all text on the page proportionately every time the setting is changed. These settings are also retained for the next time you visit. Not every custom text resizing widget does this, nor will it resize all content to &lt;a href="https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-scale.html"&gt;the degree stipulated by the Web Content Accessibility Guidelines&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;High-contrast themes&lt;/h2&gt;

&lt;p&gt;When I say high-contrast themes, I’m not talking about things like a &lt;a href="https://paulmillr.com/posts/using-dark-mode-in-css/"&gt;dark mode&lt;/a&gt;. I’m talking about a response to people reporting that they need to &lt;a href="https://accessibility.blog.gov.uk/2017/03/27/how-users-change-colours-on-websites/"&gt;change your website or web app’s colors&lt;/a&gt; to be more visually accessible to them.&lt;/p&gt;

&lt;p&gt;Much like text resizing controls, themes that are designed to provide higher contrast color values are perplexing: if you’re taking the time to make one, why not just fix the insufficient contrast values in your regular CSS? Effectively &lt;a href="https://csswizardry.com/2016/10/pragmatic-practical-progressive-theming-with-custom-properties/"&gt;managing themes in CSS&lt;/a&gt; is a complicated, resource-intensive affair, even under ideal situations. &lt;/p&gt;

&lt;p&gt;Most site-provided high-contrast themes are static in that the designer or developer made decisions about which color values to use, which can be a problem. Too much contrast has been known to be a trigger for things like migraines, as well as potentially making it difficult to focus for users with some forms of attention-deficit hyperactivity disorder (ADHD).&lt;/p&gt;

&lt;p&gt;The contrast conundrum leads us to a difficult thing to come to terms with when it comes to accessibility: what works for one person may actually inhibit another. Because of this, it’s important to make things open and interoperable. Leave ultimate control up to the end user so they may decide how to best interact with content.&lt;/p&gt;

&lt;p&gt;If you are going to follow through on providing this kind of feature, some advice: &lt;a href="https://support.microsoft.com/en-us/help/13862/windows-use-high-contrast-mode"&gt;model it after the Windows High Contrast mode&lt;/a&gt;. It’s a specialized Windows feature that allows a person to force a high color palette onto all aspects of the OS’s UI, including anything the browser displays. It offers four themes out of the box but also allows a user to suit their individual needs by specifying their own colors. &lt;/p&gt;

&lt;p&gt;Your high contrast mode feature should do the same. Offer a range of themes with different palettes, and let the user pick colors that work best for them—it will guarantee that if your offerings fail, people still have the ability to self-select.&lt;/p&gt;

&lt;h2&gt;Moving focus&lt;/h2&gt;

&lt;p&gt;Keyboard focus is how people who rely on input such as keyboards, switch controls, voice inputs, eye tracking, and &lt;a href="https://webaim.org/articles/motor/assistive"&gt;other forms of assistive technology&lt;/a&gt; navigate and operate digital interfaces. While you can do things like use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autofocus"&gt;the &lt;code&gt;autofocus&lt;/code&gt; attribute&lt;/a&gt; to move keyboard focus to the first input on a page after it loads, it is not recommended. &lt;/p&gt;

&lt;p&gt;For people experiencing low- and no-vision conditions, it is equivalent to being abruptly and instantaneously moved to a new location. It’s a confusing and disorienting experience—there’s a reason why there’s a trope in sci-fi movies of people vomiting after being teleported for the first time. &lt;/p&gt;

&lt;p&gt;For people with motor control concerns, moving focus without their permission means they may be transported to a place where they didn’t intend to go. Digging themselves out of this location becomes annoying at best and effort-intensive at worst. Websites without &lt;a href="https://webdesign.tutsplus.com/articles/the-importance-of-heading-levels-for-assistive-technology--cms-31753"&gt;heading elements&lt;/a&gt; or document landmarks to serve as navigational aids can worsen this effect.&lt;/p&gt;

&lt;p&gt;This is all about consent. Moving focus is fine so long as a person deliberately initiates an action that requires it (&lt;a href="https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/"&gt;shifting focus to an opened modal&lt;/a&gt;, for example). I don’t come to your house and force you to click on things, so don’t move my keyboard focus unless I specifically ask you to.&lt;/p&gt;

&lt;p&gt;Let the browser handle keyboard focus. Provided you use semantic markup, browsers do this well. Some tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;a href="https://developer.paciellogroup.com/blog/2014/08/using-the-tabindex-attribute/"&gt;the &lt;code&gt;tabindex&lt;/code&gt; attribute&lt;/a&gt; with care and discretion.&lt;/li&gt;
&lt;li&gt;Don’t declare &lt;code&gt;tabindex&lt;/code&gt; on interactive elements (&lt;code&gt;a&lt;/code&gt;, &lt;code&gt;button&lt;/code&gt;, &lt;code&gt;input&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt;, &lt;code&gt;summary&lt;/code&gt;, and &lt;code&gt;textarea&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Don’t use &lt;a href="http://www.karlgroves.com/2018/11/13/why-using-tabindex-values-greater-than-0-is-bad/"&gt;a manually curated &lt;code&gt;tabindex&lt;/code&gt; order&lt;/a&gt; that runs parallel to what you’d expect a user to click on. Instead, author your HTML in such a way that the resulting DOM &lt;a href="https://www.w3.org/TR/WCAG20-TECHS/C27.html"&gt;matches the visual order of the page&lt;/a&gt;. Taking a &lt;a href="https://www.levelaccess.com/what-does-responsive-web-design-have-to-do-with-accessibility/"&gt;responsive, mobile first approach&lt;/a&gt; helps out a lot here.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The clipboard and browser history&lt;/h2&gt;

&lt;p&gt;The clipboard is sacred space. Don’t prevent people from copying things to it, and don’t append extra content to what they copy. The same goes for browser history and back and forward buttons. Don’t mess around with time travel, and just let the browser do its job.&lt;/p&gt;

&lt;h2&gt;Wrapping up&lt;/h2&gt;

&lt;p&gt;In the game part of cyberball, the fun comes from being able to participate with others, passing the ball back and forth. With the web, fun comes from being able to navigate through it. In both situations, fun stops when people get locked out, forced to watch passively from the sidelines. &lt;/p&gt;

&lt;p&gt;Fortunately, the web doesn’t have to be one long cyberball experiment. While altering the powerful, assistive technology-friendly features of browsers can enhance the experience for some users, it carries a great risk of alienating others if changes are made with ignorance about exactly how much will be affected. &lt;/p&gt;

&lt;p&gt;Remember that this is all in the service of what ultimately matters: creating robust experiences that allow people to successfully use your website or web app regardless of their ability or circumstance. Sometimes the best strategy is to let things be.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/2DiF9aUHrmA" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[User Experience, Accessibility
]]></dc:subject>
      <dc:date>2019-02-07T14:50:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/paint-the-picture-not-the-frame</feedburner:origLink></item><item>
      <title><![CDATA[UX in the Age of Personalization]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/colineagan">Colin Eagan</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/6NWTbQuZ19M/emerging-ux-role-in-personalization</link>
      <guid isPermaLink="false">http://alistapart.com/article/emerging-ux-role-in-personalization</guid>
      <description>&lt;p&gt;If you listened to episode 180 of &lt;a href="http://5by5.tv/bigwebshow/180"&gt;&lt;cite&gt;The Big Web Show&lt;/cite&gt;&lt;/a&gt;, you heard two key themes: 1) personalization is now woven into much of the fabric of our digital technology, and 2) designers need to be &lt;strong&gt;much&lt;/strong&gt; more involved in its creation and deployment. In my &lt;a href="https://alistapart.com/article/approaching-content-strategy-for-personalized-websites"&gt;previous article&lt;/a&gt; we took a broad look at the first topic: the practice of harvesting user data to personalize web content, including the rewards (this website &lt;em&gt;gets&lt;/em&gt; me!) and risks (creepy!). In this piece, we will take a more detailed look at the UX practitioner’s emerging role in personalization design: from influencing technology selection, to data modeling, to page-level implementation. And it’s high time we did.&lt;/p&gt;

&lt;h2&gt;A call to arms&lt;/h2&gt;

&lt;p&gt;Just as UX people took up the torch around &lt;a href="https://alistapart.com/topic/content-strategy"&gt;content strategy&lt;/a&gt; years ago, there is a watershed moment quickly approaching for personalization strategy. Simply put, the technology in this space is far outpacing the design practice. For example, while “personalized” emails have been around forever (“Dear COOLIN, …”), it’s now estimated that some &lt;a href="https://www.evergage.com/wp-content/uploads/2018/04/Evergage-2018-Trends-in-Personalization-Survey.pdf"&gt;45% of organizations [PDF]&lt;/a&gt; have attempted to personalize their homepage. If that scares you, it should: the same report indicated that fewer than a third think it’s actually working.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/ux-of-personalization/fig-1.jpg" alt="A bar chart showing the most commonly personalized experiences (in order of highest ranking to lowest): Email content at 71%, Home page at 45%, Landing pages at 37%, Interior pages at 28%, Product detail pages at 27%, Blog at 20%, Navigation at 18%, Search at 17%, Pricing at 14%, and App screens at 13%."&gt;
&lt;figcaption&gt;While good old “mail merge” personalization has been around forever, more organizations are now personalizing their website content. Source: Researchscape International survey of 300 marketing professionals from five countries, conducted February 22 to March 28, 2018.&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;p&gt;As &lt;a href="https://jeffmacintyre.com/"&gt;Jeff MacIntyre&lt;/a&gt; points out, “personalization failures are typically design failures.” Indeed, many personalization programs are still driven primarily out of marketing and IT departments, a holdover from the legacy of the inbound, “creepy” targeted ad. Fixing that model will require the same paradigm shift we’ve used to tackle other challenges in our field: intentionally moving design “upstream,” in this case to technology selection, data collection, and page-level implementation.&lt;/p&gt;

&lt;p&gt;That’s where you come in. In fact, if you’re anything like me, you’ve been doing this, quietly, already. Here are just a few examples of UX-specific tasks I’ve completed on recent design projects that had personalization aspects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;aligning personalization to the &lt;strong&gt;core content strategy&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;working with the marketing team to understand &lt;strong&gt;goals and objectives&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;identifying &lt;strong&gt;user segments&lt;/strong&gt; (personas) that may benefit from personalized content;&lt;/li&gt;
&lt;li&gt;drafting personalization &lt;strong&gt;use cases&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;assisting the technical team with &lt;strong&gt;product selection&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;helping to define the user &lt;strong&gt;data model&lt;/strong&gt;, including first- and third-party sources;&lt;/li&gt;
&lt;li&gt;wireframing &lt;strong&gt;personalized components&lt;/strong&gt; in the information architecture;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;taking inventory&lt;/strong&gt; of existing content to repurpose for personalization;&lt;/li&gt;
&lt;li&gt;writing or editing new &lt;strong&gt;personalized copy&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;working with the design team to create &lt;strong&gt;personalized images&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;developing a personalization &lt;strong&gt;editorial calendar&lt;/strong&gt; and governance model;&lt;/li&gt;
&lt;li&gt;helping to set up and monitor results from a personalization &lt;strong&gt;pilot&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;partnering with the analytics team to make &lt;strong&gt;iterative improvements&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;being a voice for the personalization program’s &lt;strong&gt;ethical standards&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;and monitoring &lt;strong&gt;customer feedback&lt;/strong&gt; to make sure people aren’t freaking the f* out.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sound familiar? Many of these are simply variants on the same, user-centered tactics you’ve relied on for years. The difference now is that personalization creates a “third dimension” of complexity relative to audience and content. We’ll define that complexity further in two parts: technical design and information design. (We should note again that the focus of this article is personalizing &lt;em&gt;web content&lt;/em&gt;, although many of the same principles also apply to email and native applications.)&lt;/p&gt;

&lt;h2&gt;Part 1: Personalization technical design&lt;/h2&gt;

&lt;h3&gt;Influencing technology decisions&lt;/h3&gt;

&lt;p&gt;When clients or internal stakeholders come to you with a desire to “do personalization,” the first thing to ask is what does that mean. As you’ve likely noticed, the technology landscape has now matured to the point where you can “personalize” a digital experience based on just about anything, from basic geolocation to complex machine learning algorithms. What’s more, such features are increasingly baked into your own CMS or readily available from third-party plugins (see chart below). So defining what personalization is—and isn’t—is a critical first step. &lt;/p&gt;

&lt;p&gt;To accomplish this, I suggest asking two questions: 1) What &lt;strong&gt;data&lt;/strong&gt; can you ethically collect on your users, and 2) which &lt;strong&gt;tactics&lt;/strong&gt; best complement this data. Some capabilities may already exist in your current systems; some you may need to build into your future technology roadmap. The following is by no means an exhaustive list but highlights a few of the popular tactics out there today, and tools that support them:&lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col"&gt;Tactic&lt;/th&gt;
&lt;th scope="col"&gt;Definition&lt;/th&gt;
&lt;th scope="col"&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th data-title="Tactics" scope="row"&gt;Geolocation&lt;/th&gt;
&lt;td data-title="Definition"&gt;
Personalizing based on the physical location of the user, via a geolocation-enabled device or a web browser IP address (which can triangulate your position based on nearby wifi devices).
&lt;/td&gt;
&lt;td data-title="Examples"&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; If I’m in Washington, DC, show me promotions for DC. If I’m in Paris, show me promotions for Paris, in French.&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Sample Tools:&lt;/strong&gt; MaxMind, HTML5 API
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Tactics" scope="row"&gt;Quizzes and Profile Info&lt;/th&gt;
&lt;td data-title="Definition"&gt;
A simple, cost-effective way to gather first-party user data by asking basic questions to help assign someone to a segment. Often done as a layover “intercept” when the user arrives, which can then be modified based on a cookied profile. Generally must be exceptionally brief to be effective.
&lt;/td&gt;
&lt;td data-title="Examples"&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; Are you interested in our service for home use or business use? Are you in the market to buy or sell a house?
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Tactics" scope="row"&gt;Campaign Source&lt;/th&gt;
&lt;td data-title="Definition"&gt;
One of the most popular methods of personalization, it directs a user to a customized landing page based on incoming campaign data. Can be used for everything from passing a unique discount code to personalizing content on the entire site.
&lt;/td&gt;
&lt;td data-title="Examples"&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; Customize landing page based on incoming email campaigns, social media campaigns, and paid search campaigns.
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Tactics" scope="row"&gt;Clicks or Pages Viewed&lt;/th&gt;
&lt;td data-title="Definition"&gt;
Slightly more advanced approach to personalizing based on behavior; common on ecommerce.
&lt;/td&gt;
&lt;td data-title="Examples"&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; Products you previously viewed; suggested content you’ve recently been looking at.&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Sample Tools:&lt;/strong&gt; Dynamic Yield, Optimizely
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Tactics" scope="row"&gt;SIC and NAICS Codes&lt;/th&gt;
&lt;td data-title="Definition"&gt;
Standard Industrial Classification (SIC) and North American Industry Classification System (NAICS) for classifying industries based on a universal four-digit code, e.g., Manufacturing 2000–3999. Helpful for determining who is visiting you from a business location, based on incoming IP address.
&lt;/td&gt;
&lt;td data-title="Examples"&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; Show me a different message if I work in the fashion industry vs. hog farming.&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Sample Tools:&lt;/strong&gt; Marketo, Oracle (BlueKai), Demandbase
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Tactics" scope="row"&gt;Geofencing&lt;/th&gt;
&lt;td data-title="Definition"&gt;
Contextual personalization within a “virtual perimeter.” Establishes a fixed geographical boundary based on your device location, typically through RFID or GPS. Your device can then take an action when you enter or leave the location.
&lt;/td&gt;
&lt;td data-title="Examples"&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; Show me my boarding pass when I’m at the airport. Remind me about unused gift cards when I enter the store.&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Sample Tools:&lt;/strong&gt; Simpli.fi, Thinknear, Google Geofencing API.
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Tactics" scope="row"&gt;Behavioral Profiling&lt;/th&gt;
&lt;td data-title="Definition"&gt;
Add a user to a segment based on similar users who fall into that segment. Often combined with machine learning to identify new segments that humans wouldn’t be able to predict.
&lt;/td&gt;
&lt;td data-title="Examples"&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; Sitecore pattern cards, e.g., impulse purchaser, buys in bulk, bargain hunter; expedites shipping.
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Tactics" scope="row"&gt;Machine Learning&lt;/th&gt;
&lt;td data-title="Definition"&gt;
Identify patterns across large sets of data (often across channels) to better predict what a user will want. In theory, improves over time as algorithms “learn” from thousands of interactions. (Obvious downside: your site will need to support thousands of interactions.)
&lt;/td&gt;
&lt;td data-title="Examples"&gt;
&lt;strong&gt;Examples:&lt;/strong&gt; Azure Machine Learning Studio, BloomReach (Hippo), Sitecore (xConnect, Cortex), Adobe Sensei.
&lt;/td&gt;
&lt;/tr&gt;

&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;As you can see, the best tactic(s) can vary dramatically based on your audience and how they interact with you. For example, if you’re a high-volume, B2C ecommerce site, you may have enough click-stream data to support useful personalized product recommendations. Conversely, if you’re a B2B business with a qualified lead model and fewer unique visitors, you may be better served by third-party data to help you tailor your message based on industry type (NAICS code) or geography. To help illustrate this idea, let’s do a quick mapping of tactics relative to visitor volume and session time:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/ux-of-personalization/fig-2.jpg" alt="A quadrant chart with Number of Visitors for the Y-Axis and Session Time for the X-Axis. In the top left quadrant (titled Advanced Segmentation) lie Geo-Fencing and Clicks or Pages Viewed. Directly between the top left and top right quadrant lies Behavioral Profiling. In the top right quadrant (titled Big Data 1-to-1) lies Machine Learning. In the bottom left quadrant (titled Basic Segmentation) lies Campaign Source, SIC/NASIC Codes, and Geo-Location. And finally in the bottom right quadrant (titled Basic Self Selection) lies Quizzes and Profile Info."&gt;
&lt;figcaption&gt;To find your personalization “sweet spot,” consider your audience in terms of volume (number of visits) and average attention span (time on site).&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;p&gt;The good news here is that you needn’t have a massive data platform in place; you can begin to build audience profiles simply by asking users to self-identify via quizzes or profile info. But in either scenario, your goal is the same: help guide the technology decision toward a personalization approach that provides actual value to your audience, &lt;em&gt;not&lt;/em&gt; “because we can.”&lt;/p&gt;

&lt;h2&gt;Part 2: Personalization information design&lt;/h2&gt;

&lt;h3&gt;Personalization deliverables&lt;/h3&gt;

&lt;p&gt;Once you have a sense of the technical possibilities, it’s time to determine how the personalized experience will look. Let’s pretend we’re designing for a venture several of you inquired about in my &lt;a href="https://alistapart.com/article/approaching-content-strategy-for-personalized-websites"&gt;previous article&lt;/a&gt;: &lt;strong&gt;Reindeer Hugs International&lt;/strong&gt;. As the name implies, this is a nonprofit that provides hugs to reindeer. RHI recently set new business goals and wants to personalize the website to help achieve them.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/ux-of-personalization/fig-3.jpg" alt="The very reputable-looking logo of Reindeer Hugs International. It seems legit." style="max-width: 400px; height: auto;"&gt;
&lt;figcaption&gt;Seems reputable.&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;p&gt;To address this goal, we propose four &lt;strong&gt;UX-specific deliverables&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;segments worksheet;&lt;/li&gt;
&lt;li&gt;campaigns worksheet;&lt;/li&gt;
&lt;li&gt;personalization wireframes;&lt;/li&gt;
&lt;li&gt;and personalization copy deck.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Following the technical model we discussed earlier, the first thing we do is define our audience based on existing site interaction patterns. We discover that RHI doesn’t get a ton of organic traffic, but they do have a reasonably active set of authenticated users (existing members) as well as some paid social media campaigns. Working with the marketing team, we propose personalizing the site for three &lt;strong&gt;high-potential segments&lt;/strong&gt;, as follows:&lt;/p&gt;

&lt;h3&gt;Segments worksheet&lt;/h3&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col"&gt;Segment&lt;/th&gt;
&lt;th scope="col"&gt;How to Identify&lt;/th&gt;
&lt;th scope="col"&gt;Personalization Goal&lt;/th&gt;
&lt;th scope="col"&gt;Messaging Strategy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;

&lt;tr&gt;
&lt;th data-title="Segment" scope="row"&gt;Current Members&lt;/th&gt;
&lt;td data-title="How to Identify"&gt;Logged in or made guest contribution (track via cookie)&lt;/td&gt;
&lt;td data-title="Personalization Goal"&gt;Improve engagement with current members by 10%&lt;/td&gt;
&lt;td data-title="Messaging Strategy"&gt;You’re a hugging rock star, but you can hug it out even more.&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Segment" scope="row"&gt;Non-member Males&lt;/th&gt;
&lt;td data-title="How to Identify"&gt;Inbound Facebook and Instagram campaigns&lt;/td&gt;
&lt;td data-title="Personalization Goal"&gt;Improve conversion with non-member males age 25–34 by 5%&lt;/td&gt;
&lt;td data-title="Messaging Strategy"&gt;Make reindeer hugging manly again.&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;th data-title="Segment" scope="row"&gt;Non-member Parents&lt;/th&gt;
&lt;td data-title="How to Identify"&gt;Inbound Facebook and Instagram campaigns&lt;/td&gt;
&lt;td data-title="Personalization Goal"&gt;Improve conversion with non-member parents age 31–49 by 5%&lt;/td&gt;
&lt;td data-title="Messaging Strategy"&gt;Reindeer hugging is great for the kids.&lt;/td&gt;
&lt;/tr&gt;

&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;Next, let’s determine the &lt;em&gt;specific value&lt;/em&gt; we could add for these segments when they come to the site. To do this, we’ll revisit a model that we looked at previously for the &lt;a href="https://alistapart.com/article/approaching-content-strategy-for-personalized-websites#section7"&gt;four personalization content types&lt;/a&gt;. This will help us organize the collective content or “campaign” we show each segment based on a specific personalization goal:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/ux-of-personalization/fig-4.png" alt="The four contrasting tasks at hand: Alert, Make Easier, Cross-Sell, and Enrich" style="max-width: 400px; height: auto;"&gt;
&lt;figcaption&gt;A Personalization Content Model showing four flavors of personalized content.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;For example, current members who are logged in might benefit from a “Make Easier” campaign of links to members-only content. Conversely, &lt;em&gt;each&lt;/em&gt; of our three segments could benefit from a personalized “Cross-Sell” campaign to help generate awareness. Let’s capture our ideas like this:&lt;/p&gt;

&lt;h3&gt;Campaigns worksheet&lt;/h3&gt;

&lt;figure&gt;
&lt;table class="multirow-span"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col"&gt;Segment&lt;/th&gt;
&lt;th scope="col"&gt;Alert&lt;/th&gt;
&lt;th scope="col"&gt;Make Easier&lt;/th&gt;
&lt;th scope="col"&gt;Cross-Sell&lt;/th&gt;
&lt;th scope="col"&gt;Enrich&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td data-title="Segment"&gt;Current Members&lt;/td&gt;
&lt;td data-title="Alert" rowspan="3" style="vertical-align: middle;"&gt;&lt;strong&gt;Geolocation Banner&lt;/strong&gt;&lt;br /&gt;
Hugs needed in your area (displays to any user with location data).&lt;/td&gt;
&lt;td data-title="Make Easier"&gt;&lt;strong&gt;Links for members&lt;/strong&gt; who are logged in, such as to profile information, a member directory, and reindeer friends catalog.&lt;/td&gt;
&lt;td data-title="Cross-Sell" rowspan="3" style="vertical-align: middle;"&gt;&lt;strong&gt;Capital Campaign&lt;/strong&gt;&lt;br /&gt;
Generate awareness by audience (minimum three distinct messages).&lt;/td&gt;
&lt;td data-title="Enrich"&gt;&lt;strong&gt;Current Member Blog&lt;/strong&gt;&lt;br /&gt;
Invest in creating original, hug-provoking content to further our brand.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td data-title="Segment"&gt;Non-member Males Age 25–34&lt;/td&gt;
&lt;td data-title="Make Easier" rowspan="2" style="vertical-align: middle;"&gt;&lt;strong&gt;Non-Member CTA&lt;/strong&gt; In the non-member experience, this will be replaced by a CTA.&lt;/td&gt;
&lt;td data-title="Enrich" rowspan="2" style="vertical-align: middle;"&gt;&lt;strong&gt;Thought Leadership&lt;/strong&gt;&lt;br /&gt;
Demonstrate that we are the definitive source for reindeer hugs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td data-title="Segment"&gt;Non-member Parents Age 28–39&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;style&gt;.multirow-span th, .multirow-span td { background: none !important; border-right: 1px solid #bfbfbf; border-bottom: 1px solid #bfbfbf; } .multirow-span thead th:last-child, .multirow-span td:last-child { border-right: none; }&lt;/style&gt;
&lt;/figure&gt;

&lt;h3&gt;Personalization wireframes&lt;/h3&gt;

&lt;p&gt;Now let’s decide where on the site we want to run these personalized campaigns. This isn’t too dissimilar from the work you already do around templates and components, with the addition that we can now have &lt;strong&gt;personalized zones&lt;/strong&gt;. You can think of these as blocks where the CMS (or third-party plugin) will be running a series of calculations to determine the user segment in real-time (or based on a previously cached profile). To get the most coverage, these are typically dropped in at the template level. Here are examples for our home page template and interior page template:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/ux-of-personalization/fig-5.jpg" alt="Two separate wireframes with corresponding colored boxes showing which portions of the page relate to each type of personalization."&gt;
&lt;figcaption&gt;Showing component-level “zoning” on homepage and landing page templates. The colors correspond to the personalization content type.&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;p&gt;Everything in white is the non-personalized, or “static,” content, which never changes, regardless of who you are. The personalized zones themselves (color-coded based on our content model) will also have an underlying &lt;strong&gt;default or &lt;em&gt;canonical&lt;/em&gt; content set&lt;/strong&gt; that appears if the system doesn’t get a personalized match. (Note: this is also the version of the content that is typically indexed by search engines.) &lt;/p&gt;

&lt;p&gt;As you can see, an important rule of thumb is to personalize &lt;em&gt;around&lt;/em&gt; the main content, not the entire page. There are a variety of reasons for this, including the risk of getting the audience wrong, effects on search indexing, and what’s known as the &lt;strong&gt;&lt;em&gt;infinite content problem&lt;/em&gt;&lt;/strong&gt;, i.e., can you realistically create content for every single audience on every single component? (Hint: no.) &lt;/p&gt;

&lt;p&gt;OK, we’re getting close! Finally, let’s look at what specifically we want the system to show in these slots. Based on our campaigns worksheet, we know how many permutations of content we need. We sit down with the creative team to design our targeted messages, including the copy, images, and calls to action. Here’s what the capital campaign (the blue zone) might look like for our three audiences:&lt;/p&gt;

&lt;h3&gt;Personalization copy deck&lt;/h3&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;caption&gt;Reindeer Hugs International: Capital Campaign (Cross-Sell)&lt;/caption&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col"&gt;Element&lt;/th&gt;
&lt;th scope="col"&gt;Definition&lt;/th&gt;
&lt;th scope="col"&gt;Asset&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;

&lt;tr&gt;
&lt;td data-title="Element"&gt;
&lt;strong&gt;Message A:&lt;/strong&gt;&lt;br /&gt;
Current Member
&lt;/td&gt;
&lt;td data-title="Definition"&gt;
&lt;strong&gt;Headline:&lt;/strong&gt; Take Your Hugs to the Next Level
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Copy:&lt;/strong&gt; You’re a hugging expert. But did you know you could hug two reindeers at once?
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Primary CTA:&lt;/strong&gt; Sign up for our Two-for-One Hugs
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Secondary CTA:&lt;/strong&gt; Learn More
&lt;/td&gt;
&lt;td data-title="Asset"&gt;
&lt;img src="/d/ux-of-personalization/table-img1.jpg" alt="A young woman hugging a very handsome reindeer."&gt;&lt;br /&gt;
Source: Current-Member.jpg&lt;br /&gt;
Full-size render: 900x450&lt;br /&gt;
Thumbnail render: 300x200
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td data-title="Element"&gt;
&lt;strong&gt;Message B:&lt;/strong&gt;&lt;br /&gt;
Real Men Hug
&lt;/td&gt;
&lt;td data-title="Definition"&gt;
&lt;strong&gt;Headline:&lt;/strong&gt; Real Men Hug Reindeer
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Copy:&lt;/strong&gt; Are you a real man?
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Primary CTA:&lt;/strong&gt; Prove It
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Secondary CTA:&lt;/strong&gt; [None]
&lt;/td&gt;
&lt;td data-title="Asset"&gt;
&lt;img src="/d/ux-of-personalization/table-img2.jpg" alt="A bearded man hugging another handsome reindeer."&gt;&lt;br /&gt;
Source: Man-Hug.jpg&lt;br /&gt;
Full-size render: 900x450&lt;br /&gt;
Thumbnail render: 300x200
&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td data-title="Element"&gt;
&lt;strong&gt;Message C:&lt;/strong&gt;&lt;br /&gt;
Parents with Young Kids
&lt;/td&gt;
&lt;td data-title="Definition"&gt;
&lt;strong&gt;Headline:&lt;/strong&gt; Looking for a fun activity to do with the kids?
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Copy:&lt;/strong&gt; Reindeer hugs are 100% kid-friendly and 200% environmentally-friendly.
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Primary CTA:&lt;/strong&gt; Shop Our Family Plan
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Secondary CTA:&lt;/strong&gt; Learn More
&lt;/td&gt;
&lt;td data-title="Asset"&gt;
&lt;img src="/d/ux-of-personalization/table-img3.jpg" alt="A young child happily hugging a cute, unthreatening reindeer"&gt;&lt;br /&gt;
Source: Parents-Kids.jpg&lt;br /&gt;
Full-size render: 900x450&lt;br /&gt;
Thumbnail render: 300x200
&lt;/td&gt;
&lt;/tr&gt;

&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;That’s a pretty good start. We would want to follow a similar approach to detail our other three content campaigns, including alerts (e.g., hugs needed in your area), make easier (e.g., member shortcuts), and enrichment content (e.g., blog articles on latest reindeer fashions). When all the campaigns are up and running, we might expect the homepage to look something like this when seen by two different audiences, simultaneously, in real-time, in different browser sessions:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/ux-of-personalization/fig-9.jpg" alt="Two more detailed wireframes that show what the home page might look. On the left, one block has member links and info and another section has a members-only blog post. On the right, one block has a CTA on benefits that members get and a more general blog post."&gt;
&lt;figcaption&gt;Wireframes illustrating the anticipated homepage delivery to two distinct audiences: Current Member (left) and Non-Member Male 25–34 (right). If the system did not get an audience match, a default or non-personalized set of content would be shown.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2&gt;Part 3: Advanced personalization techniques&lt;/h2&gt;

&lt;h3&gt;Digital Experience Platforms&lt;/h3&gt;

&lt;p&gt;Of course, all of that work was fairly manual. If you are lucky enough to be working with an advanced &lt;strong&gt;DMP&lt;/strong&gt; (Data Management Platform) or integrated &lt;strong&gt;DXP&lt;/strong&gt; (&lt;a href="https://www.gartner.com/reviews/market/horizontal-portals"&gt;Digital Experience Platform&lt;/a&gt;) then you have even more possibilities at your disposal. For example, &lt;strong&gt;machine learning&lt;/strong&gt; and &lt;strong&gt;behavior profiling&lt;/strong&gt; can help you discover segments over time that you might never have dreamed of (the study we referenced earlier showed that 26% of marketing programs have tried some form of algorithmic one-to-one approach; 68% still use rules-based targeting to segments). This can be enhanced via &lt;strong&gt;parametric scoring&lt;/strong&gt;, where actioning off of multiple data inputs can help you create blends of audience types (in our example, a thirty-three-year-old dad might get 60 percent Parent and 40 percent Real Man … or whatever). Likewise, on the content side, &lt;strong&gt;content scoring&lt;/strong&gt; can help you deliver more nuanced content. (For example, we might tag an article with 20 percent Reindeer Advocacy and 80 percent Hug Best Practices.) Platforms like Sitecore can even illustrate these metrics, like in this example of a pattern card:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/ux-of-personalization/fig-10.jpg" alt="Examples of a hexagonally shaped behavior diagram with the following personality traits at each corner clockwise from the top left: research, impulse purchase, returns merchandise, expedites shipping, bargain hunting, and buys in bulk."&gt;
&lt;figcaption&gt;The diagram at left shows how a particular user scores (some combination of research and returns merchandise). This most closely correlates to the “Neurotic Shopper” card, so we might show this user content on our free-returns policy. Source: &lt;a href="https://www.berndtgroup.net/"&gt;The Berndt Group&lt;/a&gt;.&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;h3&gt;Cult of the complex&lt;/h3&gt;

&lt;p&gt;While all of that is super cool, even the most tech-savvy among us will benefit from starting out “simple,” lest you fall prey to the &lt;a href="https://alistapart.com/article/cult-of-the-complex"&gt;cult of the complex&lt;/a&gt;. The manual process of identifying your target audience and use cases, for example, is foundational to building an extensible personalization program, regardless of your tech stack. At a minimum, this approach will help you get buy-in from your team and organization vs. just telling everyone the site will be personalized in a “black box” somewhere. And even &lt;em&gt;with&lt;/em&gt; the best-in-class products, I have yet to find seamless “one-click” personalization, where the system somehow magically does everything from finding audiences to pumping out content, all in real time. We’ll get there one day, perhaps. &lt;/p&gt;

&lt;p&gt;But, in the meantime, it’s up to you.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/6NWTbQuZ19M" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[User Experience, Content Strategy, Web Strategy
]]></dc:subject>
      <dc:date>2019-01-17T14:55:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/emerging-ux-role-in-personalization</feedburner:origLink></item><item>
      <title><![CDATA[Conversations with Robots: Voice, Smart Agents &amp; the Case for Structured Content]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/andyfitzgerald">Andy Fitzgerald</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/kr5tkl-hL5o/conversations-with-robots</link>
      <guid isPermaLink="false">http://alistapart.com/article/conversations-with-robots</guid>
      <description>&lt;p&gt;In late 2016, &lt;a href="https://www.gartner.com/smarterwithgartner/gartner-predicts-a-virtual-world-of-exponential-change/"&gt;Gartner predicted&lt;/a&gt; that 30 percent of web browsing sessions would be done without a screen by 2020. Earlier the same year, &lt;a href="https://www.campaignlive.co.uk/article/just-say-it-future-search-voice-personal-digital-assistants/1392459"&gt;Comscore had predicted&lt;/a&gt; that half of all searches would be voice searches by 2020. Though there’s &lt;a href="https://econsultancy.com/the-state-of-mobile-voice-search-in-2018/"&gt;recent evidence&lt;/a&gt; to suggest that the 2020 picture may be more complicated than these broad-strokes projections imply, we’re already seeing the impact that voice search, artificial intelligence, and smart software agents like Alexa and Google Assistant are making on the way information is found and consumed on the web. &lt;/p&gt;

&lt;p&gt;In addition to the indexing function that traditional search engines perform, smart agents and AI-powered search algorithms are now bringing into the mainstream two additional modes of accessing information: aggregation and inference. As a result, design efforts that focus on creating visually effective pages are no longer sufficient to ensure the integrity or accuracy of content published on the web. Rather, by focusing on providing access to information in a structured, systematic way that is legible to both humans and machines, content publishers can ensure that their content is both accessible and accurate in these new contexts, whether or not they’re producing chatbots or tapping into AI directly. In this article, we’ll look at the forms and impact of structured content, and we’ll close with a set of resources that can help you get started with a structured content approach to information design.&lt;/p&gt;

&lt;h2&gt;The role of structured content&lt;/h2&gt;

&lt;p&gt;In their recent book, &lt;a href="https://www.oreilly.com/library/view/designing-connected-content/9780134764061/"&gt;&lt;cite&gt;Designing Connected Content&lt;/cite&gt;&lt;/a&gt;, Carrie Hane and Mike Atherton define structured content as content that is “planned, developed, and connected outside an interface so that it’s ready for any interface.” A structured content design approach frames content resources—like articles, recipes, product descriptions, how-tos, profiles, etc.—not as pages to be found and read, but as packages composed of small chunks of content data that all relate to one another in meaningful ways. &lt;/p&gt;

&lt;p&gt;In a structured content design process, the relationships between content chunks are explicitly defined and described. This makes both the content chunks and the relationships between them legible to algorithms. Algorithms can then interpret a content package as the “page” I’m looking for—or remix and adapt that same content to give me a list of instructions, the number of stars on a review, the amount of time left until an office closes, and any number of other concise answers to specific questions. &lt;/p&gt;

&lt;p&gt;Structured content is already a mainstay of many types of information on the web. Recipe listings, for instance, have been based on structured content for years. When I search, for example, “bouillabaisse recipe” on Google, I’m provided with a standard list of links to recipes, as well as an overview of recipe steps, an image, and a set of tags describing one example recipe:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig1-a.jpg" alt="Google search results page for a bouillabaisse recipe including an image, numbered directions, and tags."&gt;
&lt;figcaption&gt;A “featured snippet” for allrecipes.com on the Google results page.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig1-b.jpg" alt="Google Structured Data Testing tool showing the markup for a bouillabaisse recipe website on the left half of the screen and the structured data attributes and values for structured content on the right half of the screen."&gt;
&lt;figcaption&gt;The same allrecipes.com page viewed in &lt;a href="https://search.google.com/structured-data/testing-tool/"&gt;Google’s Structured Data Testing Tool&lt;/a&gt;. The pane on the right shows the machine-readable values.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This “featured snippet” view is possible because the content publisher, allrecipes.com, has broken this recipe into the smallest meaningful chunks appropriate for this subject matter and audience, and then expressed information about those chunks and the relationships between them in a machine-readable way. In this example, allrecipes.com has used both semantic HTML and &lt;a href="http://linkeddata.org/faq"&gt;linked data&lt;/a&gt; to make this content not merely a page, but also legible, accessible data that can be accurately interpreted, adapted, and remixed by algorithms and smart agents. Let’s look at each of these elements in turn to see how they work together across indexing, aggregation, and inference contexts.&lt;/p&gt;

&lt;h2&gt;Software agent search and semantic HTML&lt;/h2&gt;

&lt;p&gt;Semantic HTML is markup that communicates information about the meaningful relationships between document elements, as opposed to simply describing how they should look on screen. Semantic elements such as heading tags and list tags, for instance, indicate that the text they enclose is a heading (&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;) for the set of list items (&lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;) in the ordered list (&lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;) that follows.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig2.jpg" alt="A combined HTML code editor and preview window showing markup and results for heading, ordered list, and list item HTML tags."&gt;
&lt;/figure&gt;

&lt;p&gt;HTML structured in this way is both presentational and semantic because people know what headings and lists look like and mean, and algorithms can recognize them as elements with defined, interpretable relationships.&lt;/p&gt;

&lt;p&gt;HTML markup that focuses only on the &lt;em&gt;presentational&lt;/em&gt; aspects of a “page” may look perfectly fine to a human reader but be completely illegible to an algorithm. Take, for example, the &lt;a href="https://www.boston.gov/"&gt;City of Boston&lt;/a&gt; website, redesigned a few years ago in collaboration with top-tier design and development partners. If I want to find information about how to pay a parking ticket, a link from the home page takes me directly to the “How to Pay a Parking Ticket” screen (scrolled to show detail):&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig3.jpg" alt="The City of Boston website's “How to Pay a Parking Ticket” page, showing a tabbed view of ways to pay and instructions for the first of those ways, paying online."&gt;
&lt;/figure&gt;

&lt;p&gt;As a human reading this page, I easily understand what my options are for paying: I can pay online, in person, by mail, or over the phone. If I ask Google Assistant how to pay a parking ticket in Boston, however, things get a bit confusing:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig4.jpg" alt="Google Assistant app on iPhone with the results of a “how do I pay a parking ticket in Boston” query, showing results only weakly related to the intended content."&gt;
&lt;/figure&gt;

&lt;p&gt;None of the links provided in the Google Assistant results take me directly to the “How to Pay a Parking Ticket” page, nor do the descriptions clearly let me know I’m on the right track. (I didn’t ask about requesting a hearing.) This is because the content on the City of Boston parking ticket page is styled to communicate content relationships visually to human readers but is not structured semantically in a way that also communicates those relationships to inquisitive algorithms.&lt;/p&gt;

&lt;p&gt;The City of Seattle’s “Pay My Ticket” page, though it lacks the polished visual style of Boston’s site, also communicates parking ticket payment options clearly to human visitors:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig5.jpg" alt="The City of Seattle website‘s “Pay My Ticket” page, showing four methods to pay a parking ticket in a simple, all-text layout."&gt;
&lt;/figure&gt;

&lt;p&gt;The equivalent Google Assistant search, however, offers a much more helpful result than we see with Boston. In this case, the Google Assistant result links directly to the “Pay My Ticket” page and also lists several ways I can pay my ticket: online, by mail, and in person.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig6.jpg" alt="Google Assistant app on iPhone with the results of a “how do I pay a parking ticket in Seattle” query, showing nearly the same results as on the desktop web page referenced above."&gt;
&lt;/figure&gt;

&lt;p&gt;Despite the visual simplicity of the City of Seattle parking ticket page, it more effectively ensures the integrity of its content across contexts because it’s composed of structured content that is marked up semantically. “Pay My Ticket” is a level-one heading (&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;), and each of the options below it are level-two headings (&lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;), which indicate that they are subordinate to the level-one element.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig7.jpg" alt="The City of Seattle website’s “Pay My Ticket” page, with the HTML heading elements outlined and labeled for illustration."&gt;
&lt;/figure&gt;

&lt;p&gt;These elements, when designed well, communicate information hierarchy and relationships visually to readers, and semantically to algorithms. This structure allows Google Assistant to reasonably surmise that the text in these &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; headings represents payment options under the &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; heading “Pay My Ticket.”&lt;/p&gt;

&lt;p&gt;While this use of semantic HTML offers distinct advantages over the “page display” styling we saw on the City of Boston’s site, the Seattle page also shows a weakness that is typical of manual approaches to semantic HTML. You’ll notice that, in the Google Assistant results, the “Pay by Phone” option we saw on the web page was not listed. If we look at the markup of this page, we can see that while the three options found by Google Assistant are wrapped in both &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; tags, “Pay by Phone” is only marked up with an &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;. This irregularity in semantic structure may be what’s causing Google Assistant to omit this option from its results.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig8.jpg" alt="The City of Seattle website’s 'Pay My Ticket' page, with two HTML heading elements outlined and labeled for illustration, and an open inspector panel, where we can see that the headings look the same to viewers but are marked up differently in the code."&gt;
&lt;/figure&gt;

&lt;p&gt;Although each of these elements would look the same to a sighted human creating this page, the machine interpreting it reads a difference. While WYSIWYG text entry fields can theoretically support semantic HTML, in practice they all too often fall prey to the idiosyncrasies of even the most well-intentioned content authors. By making meaningful content structure a core element of a site’s content management system, organizations can create semantically correct HTML for every element, every time. This is also the foundation that makes it possible to capitalize on the rich relationship descriptions afforded by linked data.&lt;/p&gt;

&lt;h2&gt;Linked data and content aggregation&lt;/h2&gt;

&lt;p&gt;In addition to finding and excerpting information, such as recipe steps or parking ticket payment options, search and software agent algorithms also now aggregate content from multiple sources by using linked data.&lt;/p&gt;

&lt;p&gt;In its most basic form, &lt;em&gt;linked data&lt;/em&gt; is “&lt;a href="http://linkeddata.org/faq"&gt;a set of best practices for connecting structured data on the web&lt;/a&gt;.” Linked data extends the basic capabilities of semantic HTML by describing not only what kind of thing a page element is (“Pay My Ticket” is an &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;), but also the real-world concept that thing represents: this &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; represents a “pay action,” which inherits the structural characteristics of “trade actions” (the exchange of goods and services for money) and “actions” (activities carried out by an agent upon an object). Linked data creates a richer, more nuanced description of the relationship between page elements, and it provides the structural and conceptual information that algorithms need to meaningfully bring data together from disparate sources. &lt;/p&gt;

&lt;p&gt;Say, for example, that I want to gather more information about two recommendations I’ve been given for orthopedic surgeons. A search for a first recommendation, Scott Ruhlman, MD, brings up a set of links as well as a &lt;a href="https://en.wikipedia.org/wiki/Knowledge_Graph"&gt;Knowledge Graph&lt;/a&gt; info box containing a photo, location, hours, phone number, and reviews from the web. &lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig9.jpg" alt="Google search results page for Scott Ruhlman, MD, showing a list of standard links and an info box with an image, a map, ratings, an address, and reviews information."&gt;
&lt;/figure&gt;

&lt;p&gt;If we run Dr. Ruhlman’s Swedish Hospital profile page through Google’s &lt;a href="https://search.google.com/structured-data/testing-tool"&gt;Structured Data Testing Tool&lt;/a&gt;, we can see that content about him is structured as small, discrete elements, each of which is marked up with descriptive types and attributes that communicate both the meaning of those attributes’ values and the way they fit together as a whole—all in a machine-readable format.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig10.jpg" alt="Google Structured Data Testing tool, showing the markup for Dr. Ruhlman's profile page on the left half of the screen, and the structured data attributes and values for the structured content on that page on the right half of the screen."&gt;
&lt;/figure&gt;

&lt;p&gt;In this example, Dr. Ruhlman’s profile is marked up with microdata based on the &lt;a href="https://schema.org/"&gt;schema.org&lt;/a&gt; vocabulary. Schema.org is a collaborative effort backed by Google, Yahoo, Bing, and Yandex that aims to create a common language for digital resources on the web. This structured content foundation provides the semantic base on which additional content relationships can be built. The Knowledge Graph info box, for instance, includes Google reviews, which are not part of Dr. Ruhlman’s profile, but which have been aggregated into this overview. The overview also includes an interactive map, made possible because Dr. Ruhlman’s office location is machine-readable.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig11.jpg" alt="Google search results info box for Dr. Ruhlman, showing an photo; a map; ratings; an address; reviews; buttons to ask a question, leave a review, and add a photo; and other people searched for."&gt;
&lt;/figure&gt;

&lt;p&gt;The search for a second recommendation, Stacey Donion, MD, provides a very different experience. Like the City of Boston site above, Dr. Donion’s profile on the Kaiser Permanente website is perfectly intelligible to a sighted human reader. But because its markup is entirely presentational, its content is virtually invisible to software agents.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig12.jpg" alt="Google search results page for Dr. Donion, showing a list of standard links for Dr. Donion, and a 'Did you mean: Dr Stacy Donlon MD' link at the top. There is a Google info box, as with the previous search results page example. But in this case the box does not display information about the doctor we searched for, Dr. Donion, but rather for 'Kaiser Permanente Orthopedics: Morris Joseph MD.'"&gt;
&lt;/figure&gt;

&lt;p&gt;In this example, we can see that Google is able to find plenty of links to Dr. Donion in its standard index results, but it isn’t able to “understand” the information about those sources well enough to present an aggregated result. In this case, the Knowledge Graph knows Dr. Donion is a Kaiser Permanente physician, but it pulls in the wrong location and the wrong physician’s name in its attempt to build a Knowledge Graph display. &lt;/p&gt;

&lt;p&gt;You’ll also notice that while Dr. Stacey Donion is an exact match in all of the listed search results—which are numerous enough to fill the first results page—we’re shown a “did you mean” link for a different doctor. Stacy Donlon, MD, is a neurologist who practices at MultiCare Neuroscience Center, which is not affiliated with Kaiser Permanente. Multicare does, however, provide semantic and linked data-rich profiles for their physicians. &lt;/p&gt;

&lt;h2&gt;Voice queries and content inference&lt;/h2&gt;

&lt;p&gt;The increasing prevalence of voice as a mode of access to information makes providing structured, machine-intelligible content all the more important. Voice and smart software agents are not just freeing users from their keyboards, they’re changing user behavior. According to &lt;a href="http://www.lsainsider.com/how-voice-search-queries-differ-from-non-voice-queries/archives"&gt;LSA Insider&lt;/a&gt;, there are several important differences between voice queries and typed queries. Voice queries tend to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;longer;&lt;/li&gt;
&lt;li&gt;more likely to ask who, what, and where;&lt;/li&gt;
&lt;li&gt;more conversational;&lt;/li&gt;
&lt;li&gt;and more specific.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to tailor results to these more specifically formulated queries, software agents have begun inferring intent and then using the linked data at their disposal to assemble a targeted, concise response. If I ask Google Assistant what time Dr. Ruhlman’s office closes, for instance, it responds, “Dr. Ruhlman’s office closes at 5 p.m.,” and displays this result: &lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig13.jpg" alt="Google Assistant app on iPhone with the results of a “what time does dr. ruhlman office close” query. The results displayed include a card with “8:30AM–5:00PM” and the label, “Dr. Ruhlman Scott MD, Tuesday hours,” as well as links to call the office, search on Google, get directions, and visit a website. Additionally, there are four buttons labeled with the words “directions,” “phone number,” and “address,” and a thumbs-up emoji."&gt;
&lt;/figure&gt;

&lt;p&gt;These results are not only aggregated from disparate sources, but are interpreted and remixed to provide a customized response to my specific question. Getting directions, placing a phone call, and accessing Dr. Ruhlman’s profile page on swedish.org are all at the tips of my fingers. &lt;/p&gt;

&lt;p&gt;When I ask Google Assistant what time Dr. Donion’s office closes, the result is not only less helpful but actually points me in the wrong direction. Instead of a targeted selection of focused actions to follow up on my query, I’m presented with the hours of operation and contact information for MultiCare Neuroscience Center.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/convo-w-robots/fig14.jpg" alt="Google Assistant app on iPhone with the results of a “what time does Doc Dr Stacey donion office close” query. The results displayed include a card with “8AM–5PM” and the label “MulitCare Neuroscience Center, Monday hours,” as well as links to call the office, search on Google, get directions, or visit a website."&gt;
&lt;/figure&gt;

&lt;p&gt;MultiCare Neuroscience Center, you’ll recall, is where Dr. Donlon—the neuroscientist Google thinks I may be looking for, not the orthopedic surgeon I’m actually looking for—practices. Dr. Donlon’s profile page, much like Dr. Ruhlman’s, is semantically structured and marked up with linked data. &lt;/p&gt;

&lt;p&gt;To be fair, subsequent trials of this search did produce the generic (and partially incorrect) practice location for Dr. Donion (“Kaiser Permanente Orthopedics: Morris Joseph MD”). It is possible that through repeated exposure to the search term “Dr. Stacey Donion,” Google Assistant fine-tuned the responses it provided. The initial result, however, suggests that smart agents may be at least partially susceptible to the same &lt;a href="https://en.wikipedia.org/wiki/Availability_heuristic"&gt;availability heuristic&lt;/a&gt; that affects humans, wherein the information that is easiest to recall often seems the most correct.&lt;/p&gt;

&lt;p&gt;There’s not enough evidence in this small sample to support a broad claim that algorithms have “cognitive” bias, but even when we allow for potentially confounding variables, we can see the compounding problems we risk by ignoring structured content. “Donlon,” for example, may well be a more common name than “Donion” and may be easily mistyped on a QWERTY keyboard. Regardless, the Kaiser Permanente result we’re given above for Dr. Donion is for the wrong physician. Furthermore, in the Google Assistant voice search, the interaction format doesn’t verify whether we meant Dr. Donlon; it just provides us with her facility’s contact information. In these cases, providing clear, machine-readable content can only work to our advantage.&lt;/p&gt;

&lt;h2&gt;The business case for structured content design&lt;/h2&gt;

&lt;p&gt;In 2012, content strategist Karen McGrane wrote that “you don’t get to decide which platform or device your customers use to access your content: &lt;em&gt;they&lt;/em&gt; do.”&lt;/p&gt;

&lt;p&gt;This statement was intended to help designers, strategists, and businesses prepare for the imminent rise of mobile. It continues to ring true for the era of linked data. With the growing prevalence of smart assistants and voice-based queries, an organization’s website is less and less likely to be a potential visitor’s first encounter with rich content. In many cases—such as finding location information, hours, phone numbers, and ratings—this pre-visit engagement may be a user’s only interaction with an information source. &lt;/p&gt;

&lt;p&gt;These kinds of quick interactions, however, are only one small piece of a much larger issue: linked data is increasingly key to maintaining the integrity of content online. The organizations I’ve used as examples, like the hospitals, government agencies, and colleges I’ve consulted with for years, don’t measure the success of their communications efforts in page views or ad clicks. Success for them means connecting patients, constituents, and community members with services and accurate information about the organization, wherever that information might be found. This communication-based definition of success readily applies to virtually any type of organization working to further its business goals on the web.&lt;/p&gt;

&lt;p&gt;The model of building pages and then expecting users to discover and parse those pages to answer questions, though time-tested in the pre-voice era, is quickly becoming insufficient for effective communication. It precludes organizations from participating in emergent patterns of information seeking and discovery. And—as we saw in the case of searching for information about physicians—it may lead software agents to make inferences based on insufficient or erroneous information, potentially routing customers to competitors who communicate more effectively. &lt;/p&gt;

&lt;p&gt;By communicating clearly in a digital context that now includes aggregation and inference, organizations are more effectively able to speak to their users where users actually are, be it on a website, a search engine results page, or a voice-controlled digital assistant. They are also able to maintain greater control over the accuracy of their messages by ensuring that the correct content can be found and communicated across contexts. &lt;/p&gt;

&lt;h2&gt;Getting started: who and how&lt;/h2&gt;

&lt;p&gt;Design practices that build bridges between user needs and technology requirements to meet business goals are crucial to making this vision a reality. Information architects, content strategists, developers, and experience designers all have a role to play in designing and delivering effective structured content solutions. &lt;/p&gt;

&lt;p&gt;Practitioners from across the design community have shared a wealth of resources in recent years on creating content systems that work for humans and algorithms alike. To learn more about implementing a structured content approach for your organization, these books and articles are a great place to start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://rosenfeldmedia.com/books/content-everywhere/"&gt;&lt;cite&gt;Content Everywhere&lt;/cite&gt;&lt;/a&gt;, Sara Wachter-Boettcher&lt;/li&gt;
&lt;li&gt;“&lt;a href="https://alistapart.com/article/content-modelling-a-master-skill"&gt;Content Modelling: A Master Skill&lt;/a&gt;,” Rachel Lovinger&lt;/li&gt;
&lt;li&gt;&lt;a href="https://abookapart.com/products/content-strategy-for-mobile"&gt;&lt;cite&gt;Content Strategy for Mobile&lt;/cite&gt;&lt;/a&gt;, Karen McGrane&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/designing-connected-content/9780134764061/"&gt;&lt;cite&gt;Designing Connected Content&lt;/cite&gt;&lt;/a&gt;, Carrie Hane and Mike Atherton&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/kr5tkl-hL5o" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[HTML, Content Strategy, Information Architecture
]]></dc:subject>
      <dc:date>2019-01-10T14:55:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/conversations-with-robots</feedburner:origLink></item><item>
      <title><![CDATA[Taming Data with JavaScript]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/briangreig">Brian Greig</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/iLSufDjBylw/taming-data-with-javascript</link>
      <guid isPermaLink="false">http://alistapart.com/article/taming-data-with-javascript</guid>
      <description>&lt;p&gt;I love data. I also love JavaScript. Yet, data and client-side JavaScript are often considered mutually exclusive. The industry typically sees data processing and aggregation as a back-end function, while JavaScript is just for displaying the pre-aggregated data. Bandwidth and processing time are seen as huge bottlenecks for dealing with data on the client side. And, for the most part, I agree. But there are situations where processing data in the browser makes perfect sense. In those use cases, how can we be successful?&lt;/p&gt;

&lt;h2&gt;Think about the data&lt;/h2&gt;

&lt;p&gt;Working with data in JavaScript requires both complete data and an understanding of the tools available without having to make unnecessary server calls. It helps to draw a distinction between trilateral data and summarized data.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Trilateral data&lt;/i&gt; consists of raw, transactional data. This is the low-level detail that, by itself, is nearly impossible to analyze. On the other side of the spectrum you have your &lt;i&gt;summarized data&lt;/i&gt;. This is the data that can be presented in a meaningful and thoughtful manner. We’ll call this our &lt;i&gt;composed data&lt;/i&gt;. Most important to developers are the data structures that reside between our transactional details and our fully composed data. This is our “sweet spot.” These datasets are aggregated but contain more than what we need for the final presentation. They are multidimensional in that they have two or more different dimensions (and multiple measures) that provide flexibility for how the data can be presented. These datasets allow your end users to shape the data and extract information for further analysis. They are small and performant, but offer enough detail to allow for insights that you, as the author, may not have anticipated.&lt;/p&gt;

&lt;p&gt;Getting your data into perfect form so you can avoid any and all manipulation in the front end doesn’t need to be the goal. Instead, get the data reduced to a multidimensional dataset. Define several key dimensions (e.g., people, products, places, and time) and measures (e.g., sum, count, average, minimum, and maximum) that your client would be interested in. Finally, present the data on the page with form elements that can slice the data in a way that allows for deeper analysis.&lt;/p&gt;

&lt;p&gt;Creating datasets is a delicate balance. You’ll want to have enough data to make your analytics meaningful without putting too much stress on the client machine. This means coming up with clear, concise requirements. Depending on how wide your dataset is, you might need to include a lot of different dimensions and metrics. A few things to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the variety of content an edge case or something that will be used frequently? Go with the 80/20 rule: 80% of users generally need 20% of what’s available.&lt;/li&gt;
&lt;li&gt;Is each dimension finite? Dimensions should always have a predetermined set of values. For example, an ever-increasing product inventory might be too overwhelming, whereas product categories might work nicely.&lt;/li&gt;
&lt;li&gt;When possible, aggregate the data—dates especially. If you can get away with aggregating by years, do it. If you need to go down to quarters or months, you can, but avoid anything deeper.&lt;/li&gt;
&lt;li&gt;Less is more. A dimension that has fewer values is better for performance. For instance, take a dataset with 200 rows. If you add another dimension that has four possible values, the most it will grow is 200 * 4 = 800 rows. If you add a dimension that has 50 values, it’ll grow 200 * 50 = 10,000 rows. This will be compounded with each dimension you add.&lt;/li&gt;
&lt;li&gt;In multidimensional datasets, avoid summarizing measures that need to be recalculated every time the dataset changes. For instance, if you plan to show averages, you should include the total and the count. Calculate averages dynamically. This way, if you are summarizing the data, you can recalculate averages using the summarized values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure you understand the data you’re working with before attempting any of the above. You could make some wrong assumptions that lead to misinformed decisions. Data quality is always a top priority. This applies to the data you are both querying and manufacturing.&lt;/p&gt;

&lt;p&gt;Never take a dataset and make assumptions about a dimension or a measure. Don’t be afraid to ask for &lt;a href="http://library.ucmerced.edu/node/10249"&gt;data dictionaries&lt;/a&gt; or other documentation about the data to help you understand what you are looking at. Data analysis is not something that you guess. There could be business rules applied, or data could be filtered out beforehand. If you don’t have this information in front of you, you can easily end up composing datasets and visualizations that are meaningless or—even worse—completely misleading.&lt;/p&gt;

&lt;p&gt;The following code example will help explain this further. &lt;a href="https://github.com/ignoreintuition/tamingData"&gt;Full code for this example can be found on GitHub.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Our use case&lt;/h2&gt;

&lt;p&gt;For our example we will use &lt;a href="https://github.com/BuzzFeedNews/2015-11-refugees-in-the-united-states"&gt;BuzzFeed’s dataset&lt;/a&gt; from “Where U.S. Refugees Come From—and Go—in Charts.” We’ll build a small app that shows us the number of refugees arriving in a selected state for a selected year. Specifically, we will show one of the following depending on the user’s request:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;total arrivals for a state in a given year;&lt;/li&gt;
&lt;li&gt;total arrivals for all years for a given state;&lt;/li&gt;
&lt;li&gt;and total arrivals for all states in a given year.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The UI for selecting your state and year would be a simple form:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/taming-data-with-javascript/fig1.png" alt="Our UI for our data input"&gt;
&lt;/figure&gt;

&lt;p&gt;The code will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Send a request for the data.&lt;/li&gt;
&lt;li&gt;Convert the results to JSON.&lt;/li&gt;
&lt;li&gt;Process the data.&lt;/li&gt;
&lt;li&gt;Log any errors to the console. (&lt;i&gt;Note: To ensure that step 3 does not execute until after the complete dataset is retrieved, we use the then method and do all of our data processing within that block.&lt;/i&gt;)&lt;/li&gt;
&lt;li&gt;Display results back to the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We do not want to pass excessively large datasets over the wire to browsers for two main reasons: bandwidth and CPU considerations. Instead, we’ll aggregate the data on the server with Node.js. &lt;/p&gt;

&lt;p&gt;&lt;b&gt;Source data:&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;[{"year":2005,"origin":"Afghanistan","dest_state":"Alabama","dest_city":"Mobile","arrivals":0},
{"year":2006,"origin":"Afghanistan","dest_state":"Alabama","dest_city":"Mobile","arrivals":0},
... ]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Multidimensional Data:&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;[{"year": 2005, "state": "Alabama","total": 1386}, 
 {"year": 2005, "state": "Alaska", "total": 989}, 
... ]&lt;/code&gt;&lt;/pre&gt;

&lt;figure&gt;
&lt;img src="/d/taming-data-with-javascript/fig2.png" alt="Transactional Details show several items with Year, Origin, Destination, City, and Arrivals. This is filtered through semi-aggregate data: By Year, By State, and Total. In the final column, we see a table with the fully composed data resulting from running the Transactional Details through the semi-aggregate data."&gt;
&lt;/figure&gt;

&lt;h2&gt;How to get your data structure into place&lt;/h2&gt;

&lt;h3&gt;AJAX and the Fetch API&lt;/h3&gt;

&lt;p&gt;There are a number of ways with JavaScript to retrieve data from an external source. Historically you would use an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest"&gt;XHR request&lt;/a&gt;. XHR is widely supported but is also fairly complex and requires several different methods. There are also libraries like &lt;a href="https://github.com/axios/axios"&gt;Axios&lt;/a&gt; or &lt;a href="https://api.jquery.com/jquery.ajax/"&gt;jQuery’s AJAX API&lt;/a&gt;. These can be helpful to reduce complexity and provide cross-browser support. These might be an option if you are already using these libraries, but we want to opt for native solutions whenever possible. Lastly, there is the more recent &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API"&gt;Fetch API&lt;/a&gt;. This is &lt;a href="https://caniuse.com/#search=fetch"&gt;less widely supported&lt;/a&gt;, but it is straightforward and chainable. And if you are using a transpiler (e.g., &lt;a href="https://babeljs.io/"&gt;Babel&lt;/a&gt;), it will convert your code to a more widely supported equivalent. &lt;/p&gt;

&lt;p&gt;For our use case, we’ll use the Fetch API to pull the data into our application:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;window.fetchData = window.fetchData || {};
  fetch('./data/aggregate.json')
  .then(response =&gt; {
      // when the fetch executes we will convert the response
      // to json format and pass it to .then()
      return response.json();
  }).then(jsonData =&gt; {
      // take the resulting dataset and assign to a global object
      window.fetchData.jsonData = jsonData;
  }).catch(err =&gt; {
      console.log("Fetch process failed", err);
  });&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This code is a snippet from the main.js in the GitHub repo&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;fetch()&lt;/code&gt; method sends a request for the data, and we convert the results to JSON. To ensure that the next statement doesn’t execute until after the complete dataset is retrieved, we use the &lt;code&gt;then()&lt;/code&gt; method and do all our data processing within that block. Lastly, we &lt;code&gt;console.log()&lt;/code&gt; any errors.&lt;/p&gt;

&lt;p&gt;Our goal here is to identify the key dimensions we need for reporting—year and state—before we aggregate the number of arrivals for those dimensions, removing country of origin and destination city. You can refer to the Node.js script &lt;code&gt;/preprocess/index.js&lt;/code&gt; from the GitHub repo for more details on how we accomplished this. It generates the &lt;code&gt;aggregate.json&lt;/code&gt; file loaded by &lt;code&gt;fetch()&lt;/code&gt; above.&lt;/p&gt;

&lt;h3&gt;Multidimensional data&lt;/h3&gt;

&lt;p&gt;The goal of multidimensional formatting is flexibility: data detailed enough that the user doesn’t need to send a query back to the server every time they want to answer a different question, but summarized so that your application isn’t churning through the entire dataset with every new slice of data. You need to anticipate the questions and provide data that formulates the answers. Clients want to be able to do some analysis without feeling constrained or completely overwhelmed.&lt;/p&gt;

&lt;p&gt;As with most APIs, we’ll be working with JSON data. &lt;a href="http://json.org/"&gt;JSON&lt;/a&gt; is a standard that is used by most APIs to send data to applications as objects consisting of name and value pairs. Before we get back to our use case, let’s look at a sample multidimensional dataset:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;const ds = [{
  "year": 2005,
  "state": "Alabama",
  "total": 1386,
  "priorYear": 1201
}, {
  "year": 2005,
  "state": "Alaska",
  "total": 811,
  "priorYear": 1541
}, {
  "year": 2006,
  "state": "Alabama",
  "total": 989,
  "priorYear": 1386
}];&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With your dataset properly aggregated, we can use JavaScript to further analyze it. Let’s take a look at some of JavaScript’s native array methods for composing data.&lt;/p&gt;

&lt;h2&gt;How to work effectively with your data via JavaScript&lt;/h2&gt;

&lt;h3&gt;&lt;code&gt;Array.filter()&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;filter()&lt;/code&gt; method of the &lt;code&gt;Array&lt;/code&gt; prototype (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter"&gt;&lt;code&gt;Array.prototype.filter()&lt;/code&gt;&lt;/a&gt;) takes a function that tests every item in the array, returning another array containing only the values that passed the test. It allows you to create meaningful subsets of the data based on select dropdown or text filters. Provided you included meaningful, discrete dimensions for your multidimensional dataset, your user will be able to gain insight by viewing individual slices of data.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;ds.filter(d =&gt; d.state === "Alabama");

// Result
[{
  state: "Alabama",
  total: 1386,
  year: 2005,
  priorYear: 1201
},{
  state: "Alabama",
  total: 989,
  year: 2006,
  priorYear: 1386
}]&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;&lt;code&gt;Array.map()&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;map()&lt;/code&gt; method of the &lt;code&gt;Array&lt;/code&gt; prototype (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map"&gt;&lt;code&gt;Array.prototype.map()&lt;/code&gt;&lt;/a&gt;) takes a function and runs every array item through it, returning a new array with an equal number of elements. Mapping data gives you the ability to create related datasets. One use case for this is to map ambiguous data to more meaningful, descriptive data. Another is to take metrics and perform calculations on them to allow for more in-depth analysis.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Use case #1—map data to more meaningful data:&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;ds.map(d =&gt; (d.state.indexOf("Alaska")) ? "Contiguous US" : "Continental US");

// Result
[
  "Contiguous US", 
  "Continental US", 
  "Contiguous US"
]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Use case #2—map data to calculated results:&lt;/b&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;ds.map(d =&gt; Math.round(((d.priorYear - d.total) / d.total) * 100));

// Result
[-13, 56, 40]&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;&lt;code&gt;Array.reduce()&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;reduce()&lt;/code&gt; method of the &lt;code&gt;Array&lt;/code&gt; prototype (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce"&gt;&lt;code&gt;Array.prototype.reduce()&lt;/code&gt;&lt;/a&gt;) takes a function and runs every array item through it, returning an aggregated result. It’s most commonly used to do math, like to add or multiply every number in an array, although it can also be used to concatenate strings or do many other things. I have always found this one tricky; it’s best learned through example.&lt;/p&gt;

&lt;p&gt;When presenting data, you want to make sure it is summarized in a way that gives insight to your users. Even though you have done some general-level summarizing of the data server-side, this is where you allow for further aggregation based on the specific needs of the consumer. For our app we want to add up the total for every entry and show the aggregated result. We’ll do this by using &lt;code&gt;reduce()&lt;/code&gt; to iterate through every record and add the current value to the accumulator. The final result will be the sum of all values (total) for the array.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;ds.reduce((accumulator, currentValue) =&gt; 
accumulator + currentValue.total, 0);

// Result
3364&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Applying these functions to our use case&lt;/h3&gt;

&lt;p&gt;Once we have our data, we will assign  an event to the “Get the Data” button that will present the appropriate subset of our data. Remember that we have several hundred items in our JSON data. The code for binding data via our button is in our main.js:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt; document.getElementById("submitBtn").onclick =
  function(e){
      e.preventDefault();
      let state = document.getElementById("stateInput").value || "All"
      let year = document.getElementById("yearInput").value || "All"
      let subset = window.fetchData.filterData(year, state);
      if (subset.length == 0  )
        subset.push({'state': 'N/A', 'year': 'N/A', 'total': 'N/A'})
      document.getElementById("output").innerHTML =
      `&amp;lt;table class="table"&amp;gt;
        &amp;lt;thead&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;th scope="col"&amp;gt;State&amp;lt;/th&amp;gt;
            &amp;lt;th scope="col"&amp;gt;Year&amp;lt;/th&amp;gt;
            &amp;lt;th scope="col"&amp;gt;Arrivals&amp;lt;/th&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/thead&amp;gt;
        &amp;lt;tbody&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;${subset[0].state}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;${subset[0].year}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;${subset[0].total}&amp;lt;/td&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/tbody&amp;gt;
      &amp;lt;/table&amp;gt;`
  }&lt;/code&gt;&lt;/pre&gt;

&lt;figure&gt;
&lt;img src="/d/taming-data-with-javascript/fig3.png?asdf" alt="The final output once our code is applied"&gt;
&lt;/figure&gt;

&lt;p&gt;If you leave either the state or year blank, that field will default to “All.” The following code is available in &lt;code&gt;/js/main.js&lt;/code&gt;. You’ll want to look at the &lt;code&gt;filterData()&lt;/code&gt; function, which is where we keep the lion’s share of the functionality for aggregation and filtering.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-javascript"&gt;// with our data returned from our fetch call, we are going to 
// filter the data on the values entered in the text boxes
fetchData.filterData = function(yr, state) {
  // if "All" is entered for the year, we will filter on state 
  // and reduce the years to get a total of all years
  if (yr === "All") {
    let total = this.jsonData.filter(
      // return all the data where state
      // is equal to the input box
      dState =&gt; (dState.state === state)
        .reduce((accumulator, currentValue) =&gt; {
          // aggregate the totals for every row that has 
          // the matched value
          return accumulator + currentValue.total;
        }, 0);

    return [{'year': 'All', 'state': state, 'total': total}];
  }

  ...

  // if a specific year and state are supplied, simply
  // return the filtered subset for year and state based 
  // on the supplied values by chaining the two function
  // calls together 
  let subset = this.jsonData.filter(dYr =&gt; dYr.year === yr)
    .filter(dSt =&gt; dSt.state === state);

  return subset; 
};

// code that displays the data in the HTML table follows this. See main.js.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When a state or a year is blank, it will default to “All” and we will filter down our dataset to that particular dimension, and summarize the metric for all rows in that dimension. When both a year and a state are entered, we simply filter on the values.&lt;/p&gt;

&lt;p&gt;We now have a working example where we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with a raw, transactional dataset;&lt;/li&gt;
&lt;li&gt;Create a semi-aggregated, multidimensional dataset;&lt;/li&gt;
&lt;li&gt;And dynamically build a fully composed result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that once the data is pulled down by the client, we can manipulate the data in a number of different ways without having to make subsequent calls to the server. This is especially useful because if the user loses connectivity, they do not lose the ability to manipulate the data. This is useful if you are creating a progressive web app (PWA) that needs to be available offline. (If you are not sure if your web app should be a PWA, &lt;a href="https://alistapart.com/article/yes-that-web-project-should-be-a-pwa"&gt;this article&lt;/a&gt; can help.)&lt;/p&gt;

&lt;p&gt;Once you get a firm handle on these three methods, you can create just about any analysis that you want on a dataset. Map a dimension in your dataset to a broader category and summarize using reduce. Combined with &lt;a href="https://d3js.org/"&gt;a library like D3&lt;/a&gt;, you can map this data into charts and graphs to allow a fully customizable data visualization.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This article gives a better sense of what is possible in JavaScript when working with data. As I mentioned, client-side JavaScript is in no way a substitute for translating and transforming data on the server, where the heavy lifting should be done. But by the same token, it also shouldn’t be completely ruled out when datasets are treated properly.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/iLSufDjBylw" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Code, JavaScript
]]></dc:subject>
      <dc:date>2018-12-20T14:55:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/taming-data-with-javascript</feedburner:origLink></item><item>
      <title><![CDATA[Designing for Interaction Modes]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/andrewgrimes">Andrew Grimes</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/yU_aKmJHuYM/designing-for-interaction-modes</link>
      <guid isPermaLink="false">http://alistapart.com/article/designing-for-interaction-modes</guid>
      <description>&lt;p&gt;We humans have developed ways of coping with digital interfaces. We have tactics. We accept shortcomings. We make do. &lt;/p&gt;

&lt;p&gt;But why is it still so hard (on most of the internet) to avoid uphill struggles? Often, for example, a quality reading experience is only fully available via a hack, using &lt;a href="https://www.howtogeek.com/326430/how-to-automatically-open-articles-in-safaris-reader-mode/"&gt;Safari’s reader view&lt;/a&gt; or a browser plug-in. I use Instapaper to send articles to my Kindle—a device that’s devoted to reading mode—because reading is not just about getting the job done. The experience itself is also important. &lt;/p&gt;

&lt;p&gt;The best experiences result from designers matching the way the computer behaves with the way our users are thinking, feeling, and interacting. This is what user experience design is all about. And yet, because of pressures, competing priorities, and industry trends, interaction modes are often an afterthought.&lt;/p&gt;

&lt;h2&gt;Prioritizing interaction modes&lt;/h2&gt;

&lt;p&gt;A while back I created a persona for Cambridge University Press named Rachel Research Gatherer. The Rachel bit, I now understand, was irrelevant (&lt;a href="https://medium.com/@indiyoung/describing-personas-af992e3fc527"&gt;unhelpful, even&lt;/a&gt;). But naming the research gatherer mode helped my team focus on what was needed to support the gathering of scholarly articles and books. The precise ordering and arrangement of citation data, author biographies, metrics, and publication metadata was all organized around this central thought: &lt;/p&gt;

&lt;p&gt;&lt;i&gt;The user is trying to gather research.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;This focused our feature set and allowed for deprioritizing functionality related to other, non-essential modes (e.g., reading online—our research gatherers were only interested in saving PDFs to read later). &lt;/p&gt;

&lt;p&gt;In fact, the best personas I’ve seen have always included the interaction mode (or dominant behavior) in the title, which encourages a focus on software that supports that way of interacting. Thinking about roles or demographic attributes just isn’t as helpful. Presuming that lots of research gatherers are going to show up, you want them to converse with software that is appropriately trained and has a research gathering mode that can easily be found and switched on. The leap to be made is one from understanding a human behavior to designing its matching counterpart: an appropriate computer behavior. I’ve come to think of interaction modes as aspects of the persona you want your digital product or service to have. They can codify a specific set of behaviors, morals, and manners.&lt;/p&gt;

&lt;h2&gt;Moving between modes&lt;/h2&gt;

&lt;p&gt;In most cases, designers have to account for multiple possible interaction modes and, crucially, the shifts between them. &lt;/p&gt;

&lt;p&gt;Some shifts can be explicitly triggered by the user. Take Audible’s driving mode, which helps users stay safe by minimizing potential distractions: it filters out all but three controls and makes the entire upper part of the screen a giant play/pause button.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/designing-for-interaction-modes/fig1.png" alt="Mobile phone showing Audible's driving mode." style="max-width: 60%;"&gt;
&lt;figcaption&gt;Fig. 1: Audible’s driving mode.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Driving mode is activated by tapping on a tiny icon, but modes could equally be switched on via a link. If a link took you to “lost or stolen card” on your bank’s website, you might welcome a mode that deals with stressful situations. This might involve an appropriately short quantity of text and guidance—hopefully a quick-fix option (e.g., “freeze my card”) and directions to the nearest human support.&lt;/p&gt;

&lt;p&gt;Modes can also shift in response to implied needs. The National Trust—an organization that maintains historic and natural sites across England, Wales, and Northern Ireland—has an app whose visit mode focuses on local events and information relevant to users’ geolocation. This mode is offered to the user when they approach a National Trust property. It’s a safe bet that they’re going to prefer this mode, but they’re offered the choice to activate it anyway. It’s good manners.&lt;/p&gt;

&lt;p&gt;There are also times when there is no need to ask. Let’s consider another familiar human-computer interaction: evaluating, a mode in which the human tries to assess the quality or fitness of something, as one might do when comparison shopping for a new laptop. The computer (if trained appropriately) helps by surfacing the right metadata, summary info, reviews, and so on. A bit like research gathering, it’s a mode that might lead to reading mode, in a move from “Shall I read this?” to “I’m reading this!” A well-presented article will start with different content and functional elements than it continues with. The top of this page is all about supporting evaluation mode; then those elements fall away when the user indicates that they’ve shifted into reading mode. They show this intent by, say, scrolling slowly down the page or clicking a “read more” button.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/designing-for-interaction-modes/fig2.png" alt="One box containing a series of smaller boxes to represent content, broken up to show the layout. Another box containing smaller boxes representing unbroken narrative text."&gt;
&lt;figcaption&gt;Fig. 2: Evaluating mode might include the author bio, date, number of comments, classification tags, lead image, and the first paragraph with a “read more” button. Reading mode might include just beautiful text and the occasional supporting image.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The object, in this case an article, looks different, sometimes very different, when supporting different modes. And the user might move between these modes without even registering the shift.&lt;/p&gt;

&lt;h2&gt;Interaction modes are computer behaviors&lt;/h2&gt;

&lt;p&gt;A simple but important distinction to make when thinking about modes:&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Interaction modes are something the software does, not something the user does; “reading” is just a shorthand for “reading mode.”&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;This distinction is critical, because it allows us to be so much more precise about the behavior of the components in a design system. We don’t always need to rely on individual interpretation of personae or journey maps, or remember an agreed set of design principles. We can, instead, bake our values into our modes. We can, for example, name components according to the mode they’re intended to support rather than just to create more purposeful and consistent designs (though these are great things to aim for).&lt;/p&gt;

&lt;p&gt;Interaction modes also offer us a design tool that can help tame our technology, giving it manners that work in a variety of contexts. And in our world of agentive AI, chatbottery, and algorithms, getting a grip on this conduct is becoming increasingly important. &lt;/p&gt;

&lt;h2&gt;Two moral questions&lt;/h2&gt;

&lt;p&gt;As time goes on, we have more and more powerful controls available to us in fast digital mediums. There’s an increasing need to recognize that poor usability is not the only factor to watch out for. We need to be working design ethics into our decision making.&lt;/p&gt;

&lt;p&gt;It could start with a simple moral question for design teams: how much are you going to help your users interact in the way that they would prefer? If they’re reading, how many ads (or other distractions) are you going to throw in their faces? Even though users might prefer ads to paying for content, there are better and worse ways to show people ads. Deliberately designing for a reading mode will give you a better shot at reconciling this conflict in a good way, allowing you to create the best reading space possible within the constraints. Compromises would become more deliberate and (hopefully) less damaging. &lt;/p&gt;

&lt;p&gt;A second, less obvious, moral question is this: when should we use design to encourage a more appropriate way of interacting than the user’s default? In my article about &lt;a href="https://alistapart.com/article/meta-moments-thoughtfulness-by-design"&gt;meta-moments&lt;/a&gt;, I looked at some ways to slow the user’s experience (using roadblocks, speed bumps, or diversions in the design) when thoughtfulness is needed. The user could be agreeing to give a third party access to their data. Or they might be remortgaging their house. On these kinds of occasions, it’s right to encourage a slower, more attentive mode.&lt;/p&gt;

&lt;p&gt;One way to approach this question is to capture the interaction modes that your users want or need, on a chart like this:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/designing-for-interaction-modes/fig3.png" alt="A chart. More detail in the following footnote link."&gt;
&lt;figcaption id="ref1"&gt;&lt;a href="#note1"&gt;Fig. 3 detailed description&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;To start off, this could just be an expert-led evaluation or a group &lt;a href="http://gamestorming.com/350/"&gt;forced ranking&lt;/a&gt; exercise along the following lines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a list of interaction modes. Words ending in “-ing” can be useful.&lt;/li&gt;
&lt;li&gt;Score for how much thoughtfulness is currently required.&lt;/li&gt;
&lt;li&gt;Score for how much thoughtfulness is currently encouraged.&lt;/li&gt;
&lt;li&gt;Get charting.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ideally, you want all your modes to fall close to a diagonal line that stretches from top right to bottom left of your chart. The amount of thoughtfulness we encourage (or leave space for) in each mode would then be roughly in proportion to the amount of thought required.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/designing-for-interaction-modes/fig4.png" alt="A chart. More detail in the following footnote link."&gt;
&lt;figcaption id="ref2"&gt;&lt;a href="#note2"&gt;Fig. 4 detailed description&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This ethical line makes it look a little like there is only one way to get things right: precisely x amount of thought required = x amount of thought encouraged. It’s hard (and maybe impossible) to measure such things precisely, but that shouldn’t put us off, considering the relative needs in play. If nothing else, the visualization reminds us that there are many more ways to get design wrong than to get it right. &lt;/p&gt;

&lt;p&gt;If you find the interaction modes you’re currently supporting don’t fall on the ethical line, you’ll want to move them with your team’s next design effort.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/designing-for-interaction-modes/fig5.png" alt="A chart. More detail in the following footnote link."&gt;
&lt;figcaption id="ref3"&gt;&lt;a href="#note3"&gt;Fig. 5 detailed description&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Ultimately, deciding where to move interaction modes requires a degree of honest reflection and the willingness to shift any annoying or abusive experiences toward assisting or awakening ones. &lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/designing-for-interaction-modes/fig6.png" alt="A chart. More detail in the following footnote link."&gt;
&lt;figcaption id="ref4"&gt;&lt;a href="#note4"&gt;Fig. 6 detailed description&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;While most designers want to assist and awaken (and avoid abusing or annoying) our users, even a small team will have disagreements about the right path to take. And powerful drivers outside the team, from business models to technology trends, heavily influence design decisions. These factors need our greatest focus if we are to resist following zombie patterns (“our competitors have introduced sexy new feature X so we’d better do it too”) or the tendency to pander (often in the name of UX) to short-term interests. You might be rightly proud of being able to offer a current account opening experience that only takes &lt;a href="https://www.starlingbank.com/open-bank-account-online"&gt;minutes&lt;/a&gt;, but are you sure that this is right for everyone you’re offering it to? Don’t some folks need some extra guidance around how to configure things? Don’t people need to understand the commitments they’re making?&lt;/p&gt;

&lt;p&gt;Adding this kind of consideration to the design process can pull against the push for speed and help designers resist the deployment of persuasion techniques in inappropriate contexts. &lt;/p&gt;

&lt;h2&gt;Where to draw the line&lt;/h2&gt;

&lt;p&gt;But how can we know which techniques are inappropriate? It can be hard to make a call on this. For example, testimonials and reviews can help reassure the user and build trust. They &lt;em&gt;could&lt;/em&gt; also discourage independent research, but they’re hardly an abusive play.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/designing-for-interaction-modes/fig7.png" alt="A chart. More detail in the following footnote link."&gt;
&lt;figcaption id="ref5"&gt;&lt;a href="#note5"&gt;Fig. 7 detailed description&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Someone might want to place a pop-up ad directly in the middle of your user’s reading experience, arguing that it is encouraging thoughtfulness about a product that would be in the user’s long-term interests to know about in that context. And they might be right.&lt;/p&gt;

&lt;p&gt;For me, this is where good research comes in. We need to know the contexts for which more thoughtful engagement is appropriate to help our users achieve their long-term goals. We have to test our designs for whether they deliver comprehension and fair outcomes over a long timeframe. Only then can we know which of our nudges fall on the ethical line.&lt;/p&gt;

&lt;h2&gt;Getting over your squeamishness&lt;/h2&gt;

&lt;p&gt;You might feel squeamish about defining your users’ best interests for them. How do we dare to presume? Shouldn’t we just lay the facts and choices out there, and let people make all the decisions themselves? &lt;/p&gt;

&lt;p&gt;I think there are two solid reasons for getting over this squeamishness. First, design decisions have moral consequences whether you intend them or not. As Tristan Harris puts it, “&lt;a href="http://www.tristanharris.com/2016/05/how-technology-hijacks-peoples-minds%e2%80%8a-%e2%80%8afrom-a-magician-and-googles-design-ethicist/"&gt;If you control the menu, you control the choices.&lt;/a&gt;” It is better, therefore, to make your decisions with some deliberateness and transparency.&lt;/p&gt;

&lt;p&gt;Second, people are not as individual as we like to think we are. There are common misconceptions that lead to poor choices. To support choosing the right mortgage, for example, designers might reasonably seek out the things that typically trip people up (and are important to know). We need to convey the mechanics of the product: how the interest gets calculated, where fees and charges might come into play, and so on. We do this so we can be sure that the user knows their commitments and that they have the best possible chance of selecting something that meets their long-term needs.&lt;/p&gt;

&lt;h2&gt;Bringing dark patterns into the light&lt;/h2&gt;

&lt;p&gt;To help prioritize these considerations, you might add an understanding or clarifying mode to your chart. Just adding it to the chart will help get &lt;i&gt;designing for comprehension&lt;/i&gt; on the agenda. Making space for this conversation will help force dark patterns into the light. Where things are less clear-cut, we might at least acknowledge the need for further research to help add in richer consideration of users and their needs.&lt;/p&gt;&lt;h3&gt;Footnotes&lt;/h3&gt;&lt;ul class="the-footnotes"&gt;&lt;li id="note1"&gt;1. [fig. 3] A two-dimensional chart with axes that meet in the middle. One axis goes from “encouraged to think (independently)” (left) to “encouraged not to think” (right). The other axis goes from “situation requires thought” (bottom) to "no need for thought” (top). Interaction modes are plotted on the chart. “Finding” falls into “no need for thought” and “encouraged not to think.” “Considering” is within "no need for thought” and "encouraged to think (independently).” “Clarifying” falls roughly in the middle of the “encouraged to think” axis and within “situation requires thought.” “Deciding” falls into “encouraged not to think” and “situation requires thought.”&lt;/li&gt;&lt;li id="note2"&gt;2. [fig. 4] On this version of the chart, the ethical line is drawn diagonally between the top-right to the bottom-left corners. “Finding” and “considering” are plotted along the line in the top-right quadrant, which represents the overlap of “no need for thought” and “encouraged not to think.” “Clarifying” and “deciding” are plotted along the line in the bottom-left quadrant, which represents the overlap of “encouraged to think (independently)” and “situation requires thought.”&lt;/li&gt;&lt;li id="note3"&gt;3. [fig. 5] This chart shows the placements of “deciding” on the previous two charts, with an arrow pointing from its initial position in the lower-right quadrant to its position along the ethical line in the lower-left quadrant.&lt;/li&gt;&lt;li id="note4"&gt;4. [fig. 6] A label appears on each of the four quadrants. “Assist with good usability” appears on the top-right quadrant, where “encouraged not to think” overlaps with “no need for thought”; “awaken with meta-moments” appears on the bottom-left quadrant, where “encouraged to think (independently)” overlaps with “situation requires thought”; “annoy with poor usability” appears on the top-left quadrant, where “encouraged to think (independently)” overlaps with “no need for thought”; and “abuse with dark patterns” appears on the bottom-right quadrant, where “encouraged not to think” overlaps with “situation requires thought.”&lt;/li&gt;&lt;li id="note5"&gt;5. [fig. 7] This chart shows how “persuasion design” might fall into more than one quadrant, depending on the situation. It falls mostly into the “abuse” quadrant. But it also overlaps with the “awaken” and “assist” quadrants.&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/yU_aKmJHuYM" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[User Experience, Usability
]]></dc:subject>
      <dc:date>2018-12-13T14:18:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/designing-for-interaction-modes</feedburner:origLink></item><item>
      <title><![CDATA[Progressive Web Apps: The Case for PWAs]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/jason-grigsby">Jason Grigsby</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/VXuTXdfF7KA/progressive-web-apps-excerpt</link>
      <guid isPermaLink="false">http://alistapart.com/article/progressive-web-apps-excerpt</guid>
      <description>&lt;p&gt;&lt;b&gt;A note from the editors:&lt;/b&gt; We’re pleased to share an excerpt from Chapter 2 of Jason Grigsby’s &lt;a href="https://abookapart.com/products/progressive-web-apps"&gt;&lt;cite&gt;Progressive Web Apps&lt;/cite&gt;&lt;/a&gt;, from &lt;a href="https://abookapart.com/"&gt;&lt;cite&gt;A Book Apart&lt;/cite&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Now that you know what a progressive web app is, you’re probably wondering if your organization would benefit from one. To determine if it makes sense for your organization, ask yourself two questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Does your organization have a website?&lt;/strong&gt; If so, you would probably benefit from a progressive web app. This may sound flippant, but it’s true: nearly every website should be a progressive web app, because they represent best practices for the web.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Does your organization make money on your website via ecommerce, advertising, or some other method?&lt;/strong&gt; If so, you &lt;em&gt;definitely&lt;/em&gt; need a progressive web app, because progressive web apps can have a significant impact on revenue.
&lt;/ol&gt;

&lt;p&gt;This doesn’t mean that your site needs to have every possible feature of progressive web apps. You may have no need to provide offline functionality, push notifications, or even the ability for people to install your website to their homescreen. You may only want the bare minimum: a secure site, a service worker to speed up the site, and a manifest file—things that benefit every website.&lt;/p&gt;

&lt;p&gt;Of course, you may decide that your personal website or side project doesn’t warrant the extra effort to make it into a progressive web app. That’s understandable—and in the long run, even personal websites will gain progressive web app features when the underlying content management systems add support for them. For example, both &lt;a href="https://magento.com/news-room/press-releases/magento-commerce-announces-progressive-web-applications-studio"&gt;Magento&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=Di7RvMlk9io"&gt;WordPress&lt;/a&gt; have already announced their plans to bring progressive web apps to their respective platforms. Expect other platforms to follow suit.&lt;/p&gt;

&lt;p&gt;But if you’re running any kind of website that makes money for your organization, then it would behoove you to start planning for how to convert your website to a progressive web app. Companies that have deployed progressive web apps have seen increases in conversion, user engagement, sales, and advertising revenue. For example, &lt;a href="https://medium.com/dev-channel/a-pinterest-progressive-web-app-performance-case-study-3bd6ed2e6154"&gt;Pinterest saw core engagement increase by 60 percent&lt;/a&gt; and user-generated ad revenue increase by 44 percent (Fig 2.1). &lt;a href="https://www.youtube.com/watch?v=PsgW-0M67TQ&amp;amp;feature=youtu.be&amp;amp;t=34m4s"&gt;West Elm saw a 15 percent increase in average time spent on their site&lt;/a&gt; and a 9 percent lift in revenue per visit.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/progressive-web-apps/fig2-1.jpg" alt="Comparing old mobile web to the progressive web version of Pinterest, the time spent that was greater than 5 minutes increased by 40%, the user-generated ad revenue increased by 44%, ad clickthroughs increased by 50%, and core engagement metrics improved by 60%. Even comparing to the native app, most of these same metrics increased between 2-5%."&gt;
&lt;figcaption&gt;&lt;strong&gt;Fig 2.1:&lt;/strong&gt; Addy Osmani, an engineering manager for Google, wrote &lt;a href="https://medium.com/dev-channel/a-pinterest-progressive-web-app-performance-case-study-3bd6ed2e6154"&gt;a case study about Pinterest’s progressive web app&lt;/a&gt;, comparing it to both their old mobile website and their native app.&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;p&gt;The success stories for progressive web apps are so abundant that my company, Cloud Four, started a website called &lt;a href="https://www.pwastats.com/"&gt;PWA Stats&lt;/a&gt; to keep track of them (Fig 2.2). There’s a good chance that we’ve collected a case study from an organization similar to yours that you can use to convince your coworkers that building a progressive web app makes sense.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/progressive-web-apps/fig2-2.jpg" alt="A screenshot of the PWA Stats homepage, showing case studies for Uber, Trivago, Petlove, and the Grand Velas Riviera Maya resort."&gt;
&lt;figcaption&gt;&lt;strong&gt;Fig 2.2:&lt;/strong&gt; &lt;a href="https://www.pwastats.com/"&gt;PWAstats.com&lt;/a&gt; collects statistics and stories documenting the impact of progressive web apps.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;And convincing them may be necessary. Despite the clear benefits of progressive web apps, many businesses still haven’t converted—often because they simply don’t know about PWAs yet. (So if you start building one now, you may get a jump on your competition!)&lt;/p&gt;

&lt;p&gt;But there is also a lot of confusion about what progressive web apps are capable of, where they can be used, and how they relate to native apps. This confusion creates fear, uncertainty, and doubt (FUD) that slow the adoption of progressive web apps.&lt;/p&gt;

&lt;p&gt;If you advocate for progressive web apps in your organization, you’ll likely find some confusion and possibly even encounter some resistance. So let’s equip you with arguments to cut through the FUD and convince your colleagues.&lt;/p&gt;

&lt;h2&gt;Native apps and PWAs can coexist&lt;/h2&gt;

&lt;p&gt;If your organization already has a native app, stakeholders may balk at the idea of &lt;em&gt;also&lt;/em&gt; having a progressive web app—especially since the main selling point of PWAs is to enable native app features and functionality.&lt;/p&gt;

&lt;p&gt;It’s tempting to view progressive web apps as competition to native apps—much of the press coverage has adopted this storyline. But the reality is that progressive web apps make sense irrespective of whether a company has a native app.&lt;/p&gt;

&lt;p&gt;Set aside the “native versus web” debate, and focus on the experience you provide customers who interact with your organization via the web. Progressive web apps simply make sense on their own merits: they can help you reach more customers, secure your site, generate revenue, provide more reliable experiences, and notify users of updates—all as a complement to your native app.&lt;/p&gt;

&lt;h3&gt;Reach more customers&lt;/h3&gt;

&lt;p&gt;Not all of your current customers—and none of your potential customers—have your native app installed. Even your average customer is unlikely to have your app installed, and those customers who &lt;em&gt;do&lt;/em&gt; have your app may still visit your site on a desktop computer.&lt;/p&gt;

&lt;p&gt;Providing a better experience on the website itself will increase the chances that current and future customers will read your content or buy your products (or even download your native app!). A progressive web app can provide that better experience.&lt;/p&gt;

&lt;p&gt;Despite what the tech press might have you believe, the mobile web is growing faster than native apps. comScore compared the top one thousand apps to the top one thousand mobile web properties and found that “&lt;a href="https://www.comscore.com/Insights/Presentations-and-Whitepapers/2016/The-2016-US-Mobile-App-Report"&gt;mobile web audiences are almost 3x the size and growing 2x as fast as app audiences&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;And while it’s true that people spend more time in their favorite apps than they do on the web, you may have trouble convincing people to install your app in the first place. &lt;a href="https://www.comscore.com/Insights/Presentations-and-Whitepapers/2017/The-2017-US-Mobile-App-Report"&gt;Over half of smartphone users in the United States don’t download any apps&lt;/a&gt; in a typical month.&lt;/p&gt;

&lt;p&gt;Having a native app in an app store doesn’t guarantee that people will install it. It costs a lot to advertise an app and convince people to try it. According to app marketing company Liftoff, &lt;a href="https://www.emarketer.com/Article/Cost-of-Acquiring-Mobile-App-User/1016688"&gt;the average cost to get someone to install an app is $4.12&lt;/a&gt;, and that shoots up to $8.21 per install if you want someone to create an account in your app.&lt;/p&gt;

&lt;p&gt;If you’re lucky enough to get someone to install your app, the next hurdle is convincing them to continue to use it. When analyst Andrew Chen analyzed user retention data from 125 million mobile phones, he found that “&lt;a href="https://andrewchen.co/new-data-shows-why-losing-80-of-your-mobile-users-is-normal-and-that-the-best-apps-do-much-better/"&gt;the average app loses 77% of its DAUs [daily active users] within the first 3 days&lt;/a&gt; after the install. Within 30 days, it’s lost 90% of DAUs. Within 90 days, it’s over 95%” (Fig 2.3).&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/progressive-web-apps/fig2-3.jpg" alt="Chart: The average retention curve for Android apps drops precipitously within the first three days and continues to drop more slowly to near 0 over the next 90 days."&gt;
&lt;figcaption&gt;&lt;strong&gt;Fig 2.3:&lt;/strong&gt; App loyalty remains a big issue for native apps. The average app loses over 95 percent of its daily active users within 90 days.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Progressive web apps don’t have those same challenges. They’re as easy for people to discover as your website is, because they &lt;em&gt;are&lt;/em&gt; your website. And the features of a progressive web app are available immediately. There’s no need to jump through the hoops of visiting an app store and downloading the app. Installation is fast: it happens in the background during the first site visit, and can literally be as simple as adding an icon to the home screen.&lt;/p&gt;

&lt;p&gt;As Alex Russell wrote in &lt;a href="https://medium.com/dev-channel/why-are-app-install-banners-still-a-thing-18f3952d349a"&gt;a 2017 Medium post&lt;/a&gt;:&lt;/p&gt;

&lt;figure class="quote"&gt;
	&lt;blockquote&gt;The friction of PWA installation is &lt;em&gt;much&lt;/em&gt; lower. Our internal metrics at Google show that for similar volume of prompting for PWA banners and native app banners — the closest thing to an apples-to-apples comparison we can find — &lt;em&gt;PWA banners convert 5–6x more often&lt;/em&gt;. More than half of users who chose to install a native app from these banners fail to complete installing the app whereas PWA installation is near-instant.&lt;/blockquote&gt;
&lt;/figure&gt;

&lt;p&gt;In short, a large and growing percentage of your customers interact with you on the web. Progressive web apps can lead to more revenue and engagement from more customers.&lt;/p&gt;

&lt;h3&gt;Secure your website&lt;/h3&gt;

&lt;p&gt;If you’re collecting credit cards or private information, providing a secure website for your web visitors is a must. But even if your website doesn’t handle sensitive data, it still makes sense to use HTTPS and provide a secure experience. Even seemingly innocuous web traffic can provide signals that can identify individuals and potentially compromise them. That’s not to mention the concerns raised by revelations of government snooping.&lt;/p&gt;

&lt;p&gt;It used to be that running a secure server was costly, confusing, and (seemingly) slower. Things have changed. SSL/TLS certificates used to cost hundreds of dollars, but now certificate provider &lt;a href="https://letsencrypt.org/"&gt;Let’s Encrypt&lt;/a&gt; gives them out for free. Many hosting providers have integrated with certificate providers so you can set up HTTPS with a single click. And it turns out that &lt;a href="https://istlsfastyet.com/"&gt;HTTPS wasn’t as slow as we thought it was&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Websites on HTTPS can also move to a new version of HTTP called HTTP/2. The biggest benefit is that HTTP/2 is significantly faster that HTTP/1. For many hosting providers and content delivery networks (CDNs), the moment you move to HTTPS, you get HTTP/2 with no additional work.&lt;/p&gt;

&lt;p&gt;If that wasn’t enough incentive to move to HTTPS, browser makers are using a carrot-and-stick approach for pushing websites to make the change. For the stick, Chrome has started warning users when they enter data on a site that isn’t running HTTPS. By the time you read this, &lt;a href="https://blog.chromium.org/2017/04/next-steps-toward-more-connection.html"&gt;Google plans to label all HTTP pages with a “Not secure” warning&lt;/a&gt; (Fig 2.4). Other browsers will likely follow suit and start to flag sites that aren’t encrypted to make sure users are aware that their data could be intercepted.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/progressive-web-apps/fig2-4.jpg" alt="The eventual treatment of all HTTP pages in Chrome will be to show a red yield icon with the words 'Not secure'."&gt;
&lt;figcaption&gt;Fig 2.4: Google has announced its intention to &lt;a href="https://www.chromium.org/Home/chromium-security/marking-http-as-non-secure"&gt;label any website that isn’t running HTTPS as not secure&lt;/a&gt;. Different warning styles will be rolled out over time, until the label reaches the final state shown here.
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;For the HTTPS carrot, browsers are starting to require HTTPS to use new features. If you want to utilize the latest and greatest web tech, &lt;a href="https://blog.mozilla.org/security/2018/01/15/secure-contexts-everywhere/"&gt;you’ll need to be running HTTPS&lt;/a&gt;. In fact, some features that used to work on nonsecure HTTP that are considered to contain sensitive data—for example, geolocation—are being restricted to HTTPS now. On second thought, perhaps this is a bit of a stick as well. A carrot stick?&lt;/p&gt;

&lt;p&gt;With all that in mind, it makes sense to set up a secure website for your visitors. You’ll avoid scary nonsecure warnings. You’ll get access to new browser features. You’ll gain speed benefits from HTTP/2. And: you’ll be setting yourself up for a progressive web app.&lt;/p&gt;

&lt;p&gt;In order to use service workers, the core technology for progressive web apps, your website &lt;em&gt;must&lt;/em&gt; be on HTTPS. So if you want to reap the rewards of all the PWA goodness, you need to do the work to make sure your foundation is secure.&lt;/p&gt;

&lt;h3&gt;Generate more revenue&lt;/h3&gt;

&lt;p&gt;There are numerous studies that show a connection between the speed of a website and the amount of time and money people are willing to spend on it. DoubleClick found that “&lt;a href="https://marketingplatform.google.com/about/resources/"&gt;53% of mobile site visits are abandoned if pages take longer than 3 seconds to load&lt;/a&gt;.” Walmart found that &lt;a href="https://www.slideshare.net/devonauerswald/walmart-pagespeedslide"&gt;for every 100 milliseconds of improvement to page load time, there was up to a one percent increase in incremental revenue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Providing a fast web experience makes a big difference to the bottom line. Unfortunately, the average load time for mobile websites is &lt;a href="https://marketingplatform.google.com/about/resources/"&gt;nineteen seconds on 3G connections&lt;/a&gt;. That’s where a progressive web app can help.&lt;/p&gt;

&lt;p&gt;Progressive web apps use service workers to provide an exceptionally fast experience. Service workers allow developers to explicitly define what files the browser should store in its local cache and under what circumstances the browser should check for updates to the cached files. Files that are stored in the local cache can be accessed much more quickly than files that are retrieved from the network.&lt;/p&gt;

&lt;p&gt;When someone requests a new page from a progressive web app, most of the files needed to render that page are already stored on the local device. This means that the page can load nearly instantaneously because all the browser needs to download is the incremental information needed for that page.&lt;/p&gt;

&lt;p&gt;In many ways, this is the same thing that makes native apps so fast. When someone installs a native app, they download the files necessary to run the app ahead of time. After that occurs, the native app only has to retrieve any new data. Service workers allow the web to do something similar.&lt;/p&gt;

&lt;p&gt;The impact of progressive web apps on performance can be astounding. For example, &lt;a href="https://medium.com/@addyosmani/a-tinder-progressive-web-app-performance-case-study-78919d98ece0"&gt;Tinder cut load times from 11.91 seconds to 4.69 seconds&lt;/a&gt; with their progressive web app—and it’s 90 percent smaller than their native Android app. Hotel chain Treebo launched a progressive web app and &lt;a href="https://tech.treebo.com/we-didnt-see-a-speed-limit-so-we-made-it-faster-treebo-and-pwas-the-journey-so-far-f7378410abc7"&gt;saw a fourfold increase in conversion rates year-over-year&lt;/a&gt;; conversion rates for repeat users saw a threefold increase, and their median interactive time on mobile dropped to 1.5 seconds.&lt;/p&gt;

&lt;h3&gt;Ensure network reliability&lt;/h3&gt;

&lt;p&gt;Mobile networks are flaky. One moment you’re on a fast LTE connection, and the next you’re slogging along at 2G speeds—or simply offline. We’ve all experienced situations like this. But our websites are still primarily built with an assumption that networks are reliable.&lt;/p&gt;

&lt;p&gt;With progressive web apps, you can create an app that continues to work when someone is offline. In fact, the technology used to create an offline experience is the same technology used to make web pages fast: service workers.&lt;/p&gt;

&lt;p&gt;Remember, service workers allow us to explicitly tell the browser what to cache locally. We can expand what is stored locally—not only the assets needed to render the app, but also the content of pages—so that people can continue to view pages offline (Fig 2.5).&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/progressive-web-apps/fig2-5.jpg" alt="Three screens from the housing.com site show how the design adapts to show when it is offline and that it can continue to show saved results even when offline."&gt;
&lt;figcaption&gt;&lt;strong&gt;Fig 2.5:&lt;/strong&gt; The header in &lt;a href="https://housing.com"&gt;housing.com’s progressive web app&lt;/a&gt; changes from purple (left) to gray when offline (middle). Content the user has previously viewed or favorited is available offline (right), which is important for housing.com’s home market in India, where network connectivity can be slow and unreliable.
&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Using a service worker, we can even precache the shell of our application behind the scenes. This means that when someone visits a progressive web app for the first time, the whole application could be downloaded, stored in the cache, and ready for offline use without requiring the person to take any action to initiate it. For more on when precaching makes sense, see Chapter 5.&lt;/p&gt;

&lt;h3&gt;Keep users engaged&lt;/h3&gt;

&lt;p&gt;Push notifications are perhaps the best way to keep people engaged with an application. They prompt someone to return to an app with tantalizing nuggets of new information, from breaking news alerts to chat messages.&lt;/p&gt;

&lt;p&gt;So why limit push notifications to those who install a native application? For instance, if you have a chat or social media application, wouldn’t it be nice to notify people of new messages (Fig 2.6)?&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/progressive-web-apps/fig2-6.jpg" alt="Two screens: On the left, a list of system notifications including one from the Twitter website. On the right, the notification opened on the Twitter site to a funny tweet about WiFi passwords in a bar."&gt;
&lt;figcaption&gt;&lt;strong&gt;Fig 2.6:&lt;/strong&gt; Twitter’s progressive web app, Twitter Lite, sends the same notifications that its native app sends. They appear alongside other app notifications (left). Selecting one takes you directly to the referenced tweet in Twitter Lite (right).&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;p&gt;Progressive web apps—specifically our friend the service worker—make push notifications possible for any website to use. Notifications aren’t required for something to be a progressive web app, but they are often effective at increasing re-engagement and revenue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;United eXtra Electronics saw &lt;a href="https://developers.google.com/web/showcase/2016/extra"&gt;a fourfold increase in re-engagement and a 100 percent increase in sales&lt;/a&gt; from users arriving via push notifications.&lt;/li&gt;
&lt;li&gt;Notifications contributed to &lt;a href="https://developers.google.com/web/showcase/2017/lancome"&gt;a 12 percent increase in recovered carts&lt;/a&gt; for Lancôme.&lt;/li&gt;
&lt;li&gt;Classified ads company OLX saw &lt;a href="https://developers.google.com/web/showcase/2017/olx"&gt;a 250 percent increase in re-engagement&lt;/a&gt; using push notifications and a 146 percent higher click-through rate on ads.&lt;/li&gt;
&lt;li&gt;Carnival Cruise Line garnered &lt;a href="https://developers.google.com/web/showcase/2016/carnival"&gt;a 42 percent open rate from its push notifications&lt;/a&gt;. In addition to the 24 percent of mobile users who opted in to the notifications, 16 percent of desktop users opted in as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll talk more about push notifications in Chapter 6. For now, it can be helpful to know that progressive web apps can send push notifications, just like a native app—which may help you make the case to your company.&lt;/p&gt;

&lt;p&gt;Whether you have a native app or not, a progressive web app is probably right for you. Every step toward a progressive web app is a step toward a better website. Websites &lt;em&gt;should&lt;/em&gt; be secure. They &lt;em&gt;should&lt;/em&gt; be fast. They would be better if they were available offline and able to send notifications when necessary.&lt;/p&gt;

&lt;p&gt;For your customers who don’t have or use your native app, providing them with a better website experience is an excellent move for your business. It’s really that simple.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/VXuTXdfF7KA" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[State of the Web
]]></dc:subject>
      <dc:date>2018-12-06T15:00:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/progressive-web-apps-excerpt</feedburner:origLink></item><item>
      <title><![CDATA[var to JIT]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/kevinsmith">Kevin Smith</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/VWnw2u3qiMU/var-to-jit</link>
      <guid isPermaLink="false">http://alistapart.com/article/var-to-jit</guid>
      <description>&lt;p&gt;In our previous article we described how the browser uses CSS to render beautiful pixels to the user’s screen. Although modern CSS can (and should!) be used to create highly interactive user experiences, for the last mile of interactivity, we need to dynamically update the HTML document. For that, we’re going to need JavaScript.&lt;/p&gt;

&lt;h2&gt;Bundle to bytecode&lt;/h2&gt;

&lt;p&gt;For a modern web application, the JavaScript that the browser first sees will typically not be the JavaScript written by a developer. Instead, it will most likely be a bundle produced by a tool such as webpack. And it will probably be a rather large bundle containing a UI framework such as React, various &lt;i&gt;polyfills&lt;/i&gt; (libraries that emulate new platform features in older browsers), and an assortment of other packages found on npm. The first challenge for the browser’s JavaScript engine is to convert that big bundle of text into instructions that can be executed on a virtual machine. It needs to parse the code, and because the user is waiting on JavaScript for all that interactivity, it needs to do it fast.&lt;/p&gt;

&lt;p&gt;At a high level, the JavaScript engine parses code just like any other programming language compiler. First, the stream of input text is broken up into chunks called &lt;i&gt;tokens&lt;/i&gt;. Each token represents a meaningful unit within the syntactic structure of the language, similar to words and punctuation in natural written language. Those tokens are then fed into a &lt;a href="https://en.wikipedia.org/wiki/Top-down_parsing"&gt;&lt;i&gt;top-down parser&lt;/i&gt;&lt;/a&gt; that produces a tree structure representing the program. Language designers and compiler engineers like to call this tree structure an &lt;i&gt;AST (abstract syntax tree)&lt;/i&gt;. The resulting AST can then be analyzed to produce a list of virtual machine instructions called bytecode.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/var-to-jit/fig1.png" alt="JavaScript is run through the abstract syntax tree, which produces byte code"&gt;
&lt;/figure&gt;

&lt;p&gt;The process of generating an AST is one of the more straightforward aspects of a JavaScript engine. Unfortunately, it can also be slow. Remember that big bundle of code we started out with? The JavaScript engine has to parse and build syntax trees for the entire bundle before the user can start interacting with the site. Much of that code may be unnecessary for the initial page load, and some may not even be executed at all!&lt;/p&gt;

&lt;p&gt;Fortunately, our compiler engineers have invented a variety of tricks to speed things up. First, some engines parse code on a background thread, freeing up the main UI thread for other computations.&amp;nbsp; Second, modern engines will delay the creation of in-memory syntax trees for as long as possible by using a technique called &lt;i&gt;deferred parsing&lt;/i&gt; or &lt;i&gt;lazy compilation&lt;/i&gt;. It works like this: if the engine sees a function definition that might not be executed for a while, it will perform a fast, “throwaway” parse of the function body. This throwaway parse will find any syntax errors that might be lurking within the code, but it will not generate an AST. Later, when the function is called for the first time, the code will be parsed again. This time, the engine will generate the full AST and bytecode required for execution. In the world of JavaScript, doing things twice can sometimes be faster than doing things once!&lt;/p&gt;

&lt;p&gt;The best optimizations, though, are the ones that allow us to bypass doing any work at all. In the case of JavaScript compilation, this means skipping the parsing step completely. Some JavaScript engines will attempt to cache the generated bytecode for later reuse in case the user visits the site again. This isn’t quite as simple as it sounds. JavaScript bundles can change frequently as websites are updated, and the browser must carefully weigh the cost of serializing bytecode against the performance improvements that come from caching.&lt;/p&gt;

&lt;h2&gt;Bytecode to runtime&lt;/h2&gt;

&lt;p&gt;Now that we have our bytecode, we’re ready to start execution. In today’s JavaScript engines, the bytecode that we generated during parsing is first fed into a virtual machine called an &lt;i&gt;interpreter&lt;/i&gt;. An interpreter is a bit like a CPU implemented in software. It looks at each bytecode instruction, one at a time, and decides what actual machine instructions to execute and what to do next.&lt;/p&gt;

&lt;p&gt;The structure and behavior of the JavaScript programming language is defined in a document formally known as &lt;a href="https://tc39.github.io/ecma262"&gt;&lt;i&gt;ECMA-262&lt;/i&gt;&lt;/a&gt;. Language designers like to call the structure part “syntax” and the behavior part “semantics.” The semantics of almost every aspect of the language is defined by algorithms that are written using prose-like pseudo-code. For instance, let’s pretend we are compiler engineers implementing the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3E%3E_(Sign-propagating_right_shift)"&gt;&lt;i&gt;signed right shift operator&lt;/i&gt; (&amp;gt;&amp;gt;)&lt;/a&gt;. Here’s what the &lt;a href="https://tc39.github.io/ecma262/#sec-signed-right-shift-operator-runtime-semantics-evaluation"&gt;specification tells us&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;i&gt;ShiftExpression&lt;/i&gt; : &lt;i&gt;ShiftExpression&lt;/i&gt; &amp;gt;&amp;gt; &lt;i&gt;AdditiveExpression&lt;/i&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Let &lt;var&gt;lref&lt;/var&gt; be the result of evaluating &lt;i&gt;ShiftExpression&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Let &lt;var&gt;lval&lt;/var&gt; be ? &lt;a href="https://tc39.github.io/ecma262/#sec-getvalue"&gt;GetValue&lt;/a&gt;(&lt;var&gt;lref&lt;/var&gt;).&lt;/li&gt;
&lt;li&gt;Let &lt;var&gt;rref&lt;/var&gt; be the result of evaluating &lt;i&gt;AdditiveExpression&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Let &lt;var&gt;rval&lt;/var&gt; be ? GetValue(&lt;var&gt;rref&lt;/var&gt;).&lt;/li&gt;
&lt;li&gt;Let &lt;var&gt;lnum&lt;/var&gt; be ? &lt;a href="https://tc39.github.io/ecma262/#sec-toint32"&gt;ToInt32&lt;/a&gt;(&lt;var&gt;lval&lt;/var&gt;).&lt;/li&gt;
&lt;li&gt;Let &lt;var&gt;rnum&lt;/var&gt; be ? &lt;a href="https://tc39.github.io/ecma262/#sec-touint32"&gt;ToUint32&lt;/a&gt;(&lt;var&gt;rval&lt;/var&gt;).&lt;/li&gt;
&lt;li&gt;Let &lt;var&gt;shiftCount&lt;/var&gt; be the result of masking out all but the least significant 5 bits of &lt;var&gt;rnum&lt;/var&gt;, that is, compute &lt;var&gt;rnum&lt;/var&gt; &amp;amp; 0x1F.&lt;/li&gt;
&lt;li&gt;Return the result of performing a sign-extending right shift of &lt;var&gt;lnum&lt;/var&gt; by &lt;var&gt;shiftCount&lt;/var&gt; bits. The most significant bit is propagated. The result is a signed 32-bit integer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the first six steps we convert the operands (the values on either side of the &gt;&gt;) into 32-bit integers, and then we perform the actual shift operation. If you squint, it looks a bit like a recipe. If you &lt;em&gt;really&lt;/em&gt; squint, you might see the beginnings of a syntax-directed interpreter.&lt;/p&gt;

&lt;p&gt;Unfortunately, if we implemented the algorithms exactly as they are described in the specification, we’d end up with a very slow interpreter. Consider the simple operation of getting a property value from a JavaScript object.&lt;/p&gt;

&lt;p&gt;Objects in JavaScript are conceptually like dictionaries. Each property is keyed by a string name. Objects can also have a &lt;i&gt;prototype object&lt;/i&gt;.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/var-to-jit/fig2.png" alt="A JavaScript object with a prototype, an arrow pointing to an object.prototype, an arrow pointing to obj, an arrow pointing to obj2"&gt;
&lt;/figure&gt;

&lt;p&gt;If an object doesn’t have an entry for a given string key, then we need to look for that key in the prototype. We repeat this operation until we either find the key that we’re looking for or get to the end of the prototype chain.&lt;/p&gt;

&lt;p&gt;That’s potentially a lot of work to perform every time we want to get a property value out of an object! &lt;/p&gt;

&lt;p&gt;The strategy used in JavaScript engines for speeding up dynamic property lookup is called &lt;i&gt;inline caching&lt;/i&gt;. Inline caching was first developed for the language &lt;a href="https://en.wikipedia.org/wiki/Smalltalk"&gt;Smalltalk&lt;/a&gt; in the 1980s. The basic idea is that the results from previous property lookup operations can be stored directly in the generated bytecode instructions.&lt;/p&gt;

&lt;p&gt;To see how this works, let’s imagine that the JavaScript engine is a towering gothic cathedral. As we step inside, we notice that the engine is chock full of objects swarming around. Each object has an identifiable shape that determines where its properties are stored.&lt;/p&gt;

&lt;p&gt;Now, imagine that we are following a series of bytecode instructions written on a scroll. The next instruction tells us to get the value of the property named “x” from some object. You grab that object, turn it over in your hands a few times to figure out where “x” is stored, and find out that it is stored in the object’s second data slot.&lt;/p&gt;

&lt;p&gt;It occurs to you that any object with this same shape  will have an “x” property in its second data slot.&amp;nbsp; You pull out your quill and make a note on your bytecode scroll indicating the shape of the object and the location of the “x” property. The next time you see this instruction you’ll simply check the shape of the object. If the shape matches what you’ve recorded in your bytecode notes, you’ll know exactly where the data is located without having to inspect the object. You’ve just implemented what’s known as a &lt;i&gt;monomorphic inline cache&lt;/i&gt;!&lt;/p&gt;

&lt;p&gt;But what happens if the shape of the object doesn’t match our bytecode notes? We can get around this problem by drawing a small table with a row for each shape we’ve seen. When we see a new shape, we use our quill to add a new row to the table. We now have a &lt;i&gt;polymorphic inline cache&lt;/i&gt;. It’s not quite as fast as the monomorphic cache, and it takes up a little more space on the scroll, but if there aren’t too many rows, it works quite well.&lt;/p&gt;

&lt;p&gt;If we end up with a table that’s too big, we’ll want to erase the table, and make a note to remind ourselves to not worry about inline caching for this instruction. In compiler terms, we have a &lt;i&gt;megamorphic callsite&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;In general, monomorphic code is very fast, polymorphic code is almost as fast, and megamorphic code tends to be rather slow. Or, in haiku form:&lt;/p&gt;

&lt;figure class="text"&gt;One shape, flowing wind&lt;br&gt;
Several shapes, jumping fox&lt;br&gt;
Many shapes, turtle&lt;/figure&gt;

&lt;h2&gt;Interpreter to just-in-time (JIT)&lt;/h2&gt;

&lt;p&gt;The great thing about an interpreter is that it can start executing code quickly, and for code that is run only once or twice, this “software CPU” performs acceptably fast. But for “hot code” (functions that are run hundreds, thousands, or millions of times) what we really want is to execute machine instructions directly on the actual hardware. We want &lt;a href="https://en.wikipedia.org/wiki/Just-in-time_compilation"&gt;just-in-time (JIT) compilation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As JavaScript functions are executed by the interpreter, various statistics are gathered about how often the function has been called and what kinds of arguments it is called with. If the function is run frequently with the same kinds of arguments, the engine may decide to convert the function’s bytecode into machine code.&lt;/p&gt;

&lt;p&gt;Let’s step once again into our hypothetical JavaScript engine, the gothic cathedral. As the program executes, you dutifully pull bytecode scrolls from carefully labeled shelves. For each function, there is roughly one scroll. As you follow the instructions on each scroll, you record how many times you’ve executed the scroll. You also note the shapes of the objects encountered while carrying out the instructions. You are, in effect, a &lt;i&gt;&lt;a href="https://en.wikipedia.org/wiki/Profiling_(computer_programming)"&gt;profiling&lt;/a&gt; interpreter&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;When you open the next scroll of bytecode, you notice that this one is “hot.” You’ve executed it dozens of times, and you think it would run much faster in machine code. Fortunately, there are two rooms full of scribes that are ready to perform the translation for you. The scribes in the first room, a brightly lit open office, can translate bytecode into machine code quite fast. The code that they produce is of good quality and is concise, but it’s not as efficient as it could be. The scribes in the second room, dark and misty with incense, work more carefully and take a bit longer to finish. The code that they produce, however, is highly optimized and about as fast as possible.&lt;/p&gt;

&lt;p&gt;In compiler-speak, we refer to these different rooms as &lt;i&gt;JIT compilation tiers&lt;/i&gt;. Different engines have different numbers of tiers depending on the tradeoffs they’ve chosen to make.&lt;/p&gt;

&lt;p&gt;You decide to send the bytecode to the first room of scribes. After working on it for a bit, using your carefully recorded notes, they produce a new scroll containing machine instructions and place it on the correct shelf alongside the original bytecode version. The next time you need to execute the function, you can use this faster set of instructions.&lt;/p&gt;

&lt;p&gt;The only problem is that the scribes made quite a few assumptions when they translated our scroll. Perhaps they assumed that a variable would always hold an integer. What happens if one of those assumptions is invalidated?&lt;/p&gt;

&lt;p&gt;In that case we must perform what’s known as a &lt;i&gt;bailout&lt;/i&gt;. We pull the original bytecode scroll from the shelf, and figure out which instruction we should start executing from. The machine code scroll disappears in a puff of smoke and the process starts again.&lt;/p&gt;

&lt;h2&gt;To infinity and beyond&lt;/h2&gt;

&lt;p&gt;Today’s high-performance JavaScript engines have evolved far beyond the relatively simple interpreters that shipped with Netscape Navigator and Internet Explorer in the 1990s. And that evolution continues. New features are incrementally added to the language. Common coding patterns are optimized. &lt;a href="https://webassembly.org/"&gt;WebAssembly&lt;/a&gt; is maturing. A richer standard module library is being developed. As developers, we can expect modern JavaScript engines to deliver fast and efficient execution as long as we keep our bundle sizes in check and try to make sure our performance-critical code is not overly dynamic.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/VWnw2u3qiMU" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Browsers, JavaScript
]]></dc:subject>
      <dc:date>2018-11-29T13:36:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/var-to-jit</feedburner:origLink></item><item>
      <title><![CDATA[Braces to Pixels]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/gregwhitworth">Greg Whitworth</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/ziCmKg402QY/braces-to-pixels</link>
      <guid isPermaLink="false">http://alistapart.com/article/braces-to-pixels</guid>
      <description>&lt;p&gt;Doesn’t CSS seem like magic? Well, in this third installment of “&lt;a href="/article/from-url-to-interactive"&gt;URL to Interactive&lt;/a&gt;” we’ll look at the journey that your browser goes through to take your CSS from braces to pixels. As a bonus, we’ll also quickly touch on how end-user interaction affects this process. We have a lot of ground to cover, so grab a cup of &amp;lt;insert your favorite drink’s name here&amp;gt;, and let’s get going.&lt;/p&gt;

&lt;h2&gt;Parsing&lt;/h2&gt;

&lt;p&gt;Similar to what we learned about HTML in “&lt;a href="/article/tags-to-dom"&gt;Tags to DOM&lt;/a&gt;,” once CSS is downloaded by the browser, the CSS parser is spun up to handle any CSS that it encounters. This can be CSS within individual documents, inside of &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tags, or inline within the &lt;code&gt;style&lt;/code&gt; attribute of a DOM element. All the CSS is parsed out and tokenized in accordance with the &lt;a href="https://drafts.csswg.org/css-syntax-3/"&gt;syntax specification&lt;/a&gt;. At the end of this process, we have a data structure with all the selectors, properties, and properties’ respective values.&lt;/p&gt;

&lt;p&gt;For example, consider the following CSS:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-css"&gt;.fancy-button {
	background: green;
	border: 3px solid red;
	font-size: 1em;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That will result in the following data structure for easy utilization later in the process:&lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Selector&lt;/th&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;background-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(0,255,0)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3px&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-style&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;solid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,0,0)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1em&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;One thing that is worth noting is that the browser exploded the shorthands of &lt;code&gt;background&lt;/code&gt; and &lt;code&gt;border&lt;/code&gt; into their longhand variants, as shorthands are primarily for developer ergonomics; the browser only deals with the longhands from here on.&lt;/p&gt;

&lt;p&gt;After this is done, the engine continues constructing the DOM tree, which Travis Leithead also covers in “&lt;a href="/article/tags-to-dom"&gt;Tags to DOM&lt;/a&gt;”; so go read that now if you haven’t already, I’ll wait.&lt;/p&gt;

&lt;h3&gt;Computation&lt;/h3&gt;

&lt;p&gt;Now that we have parsed out all styles within the readily available content, it’s time to do style computation on them. All values have a standardized computed value that we try to reduce them to. When leaving the computation stage, any dimensional values are reduced to one of three possible outputs: &lt;code&gt;auto&lt;/code&gt;, a percentage, or a pixel value. For clarity, let’s take a look at a few examples of what the web developer wrote and what the result will be following computation:&lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Web Developer&lt;/th&gt;
&lt;th&gt;Computed Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;font-size: 1em&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;font-size: 16px&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;width: 50%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;width: 50%&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;height: auto&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;height: auto&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;width: 506.4567894321568px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;width: 506.46px&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;line-height: calc(10px + 2em)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;line-height: 42px&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;border-color: currentColor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-color: rgb(0,0,0)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;height: 50vh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;height: 540px&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;display: grid&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;display: grid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;Now that we’ve computed all the values in our data store, it’s time to handle the cascade.&lt;/p&gt;

&lt;h2&gt;Cascade&lt;/h2&gt;

&lt;p&gt;Since the CSS can come from a variety of sources, the browser needs a way to determine which styles should apply to a given element. To do this, the browser uses a formula called specificity, which counts the number of tags, classes, ids, and attribute selectors utilized in the selector, as well as the number of &lt;code&gt;!important&lt;/code&gt; declarations present. Styles on an element via the inline &lt;code&gt;style&lt;/code&gt; attribute are given a rank that wins over any style from within a &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; block or external style sheet. And if a web developer utilizes &lt;code&gt;!important&lt;/code&gt; on a value, the value will win over any CSS no matter its location, unless there is a &lt;code&gt;!important&lt;/code&gt; inline as well.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_2_696w.png" alt="Graphic showing a hierarchy for determining CSS priority"&gt;
&lt;/figure&gt;

&lt;p&gt;To make this clear, let’s show a few selectors and their resulting specificity scores:&lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Selector&lt;/th&gt;
&lt;th&gt;Specificity Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;li&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 0 1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;li.foo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;#comment li.foo.bar&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 1 2 1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;li style="color: red"&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 1 0 0 0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;color: red !important&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1 0 0 0 0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;So what does the engine do when the specificity is tied? Given two or more selectors of equal specificity, the winner will be whichever one appears last in the document. In the following example, the &lt;code&gt;div&lt;/code&gt; would have a blue background.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-css"&gt;div {
	background: red;
}

div {
	background: blue;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let’s expand on our &lt;code&gt;.fancy-button&lt;/code&gt; example a little bit:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-css"&gt;.fancy-button {
	background: green;
	border: 3px solid red;
	font-size: 1em;
}

div .fancy-button {
	background: yellow;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the CSS will produce the following data structure. We’ll continue building upon this throughout the article. &lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Selector&lt;/th&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Specificity Score&lt;/th&gt;
&lt;th&gt;Document Order&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;background-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(0,255,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-style&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;solid&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,0,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;16px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;div .fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;background-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,255,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;h3&gt;Understanding origins&lt;/h3&gt;

&lt;p&gt;In “&lt;a href="/article/server-to-client"&gt;Server to Client&lt;/a&gt;,” Ali Alabbas discusses origins as they relate to browser navigation. In CSS, there are also origins, but they serve different purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user: any styles set globally within the user agent by the user;&lt;/li&gt;
&lt;li&gt;author: the web developer’s styles;&lt;/li&gt;
&lt;li&gt;and user agent: anything that can utilize and render CSS (to most web developers and users, this is a browser).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cascade power of each of these origins ensures that the greatest power lies with the user, then the author, and finally the user agent. Let’s expand our dataset a bit further and see what happens when the user sets their browser’s font size to a minimum of 2em: &lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Origin&lt;/th&gt;
&lt;th&gt;Selector&lt;/th&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Specificity Score&lt;/th&gt;
&lt;th&gt;Document Order&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;background-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(0,255,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-style&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;solid&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,0,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;16px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;div .fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;background-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,255,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;User&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;32px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 0 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;h3&gt;Doing the cascade&lt;/h3&gt;

&lt;p&gt;When the browser has a complete data structure of all declarations from all origins, it will sort them in accordance with specification. First it will sort by origin, then by specificity, and finally, by document order. &lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Origin ⬆&lt;/th&gt;
&lt;th&gt;Selector&lt;/th&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Specificity Score ⬆&lt;/th&gt;
&lt;th&gt;DocumentOrder ⬇&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;User&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;32px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 0 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;div .fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;background-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,255,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;background-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(0,255,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-style&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;solid&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;border-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,0,0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.fancy-button&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;16px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0 0 0 1 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;This results in the “winning” properties and values for the &lt;code&gt;.fancy-button&lt;/code&gt; (the higher up in the table, the better). For example, from the previous table, you’ll note that the user’s browser preference settings take precedence over the web developer’s styles. Now the browser finds all DOM elements that match the denoted selectors, and hangs the resulting computed styles off the matching elements, in this case a &lt;code&gt;div&lt;/code&gt; for the &lt;code&gt;.fancy-button&lt;/code&gt;:&lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;32px&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;background-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,255,0)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;border-width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3px&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;border-color&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rgb(255,0,0)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;border-style&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;solid&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;If you wish to learn more about how the cascade works, take a look at the &lt;a href="https://www.w3.org/TR/css-cascade-4/#cascading"&gt;official specification&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;CSS Object Model&lt;/h3&gt;

&lt;p&gt;While we’ve done a lot up to this stage, we’re not done yet. Now we need to update the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model"&gt;CSS Object Model (CSSOM)&lt;/a&gt;. The CSSOM resides within &lt;code&gt;document.stylesheets&lt;/code&gt;, we need to update it so that it represents everything that has been parsed and computed up to this point.&lt;/p&gt;

&lt;p&gt;Web developers may utilize this information without even realizing it. For example, when calling into &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle"&gt;&lt;code&gt;getComputedStyle()&lt;/code&gt;&lt;/a&gt;, the same process denoted above is run, if necessary.&lt;/p&gt;

&lt;h2&gt;Layout&lt;/h2&gt;

&lt;p&gt;Now that we have a DOM tree with styles applied, it’s time to begin the process of building up a tree for visual purposes. This tree is present in all modern engines and is referred to as the box tree. In order to construct this tree, we traverse down the DOM tree and create zero or more CSS boxes, each having a margin, border, padding and content box.&lt;/p&gt;

&lt;p&gt;In this section, we’ll be discussing the following CSS layout concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Formatting context (FC)&lt;/i&gt;: there are many types of formatting contexts, most of which web developers invoke by changing the &lt;code&gt;display&lt;/code&gt; value for an element. Some of the most common formatting contexts are block (block formatting context, or BFC), flex, grid, table-cells, and inline. Some other CSS can force a new formatting context, too, such as &lt;code&gt;position: absolute&lt;/code&gt;, using &lt;code&gt;float&lt;/code&gt;, or utilizing multi-column.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Containing block&lt;/i&gt;: this is the ancestor block that you resolve styles against.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Inline direction&lt;/i&gt;: this is the direction in which text is laid out, as dictated by the element’s writing mode. In Latin-based languages this is the horizontal axis, and in CJK languages this is the vertical axis.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Block direction&lt;/i&gt;: this behaves exactly the same as the inline direction but is perpendicular to that axis. So, for Latin-based languages this is the vertical axis, and in CJK languages this is the horizontal axis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Resolving &lt;code&gt;auto&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Remember from the computation phase that dimension values can be one of three values: &lt;code&gt;auto&lt;/code&gt;, percentage, or pixel. The purpose of layout is to size and position all the boxes in the box tree to get them ready for painting. As a very visual person myself, I find examples can make it easier to understand how the box tree is constructed. To make it easier to follow, I will not be showing the individual CSS boxes, just the principal box. Let’s look at a basic “Hello world” layout using the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-markup"&gt;&amp;lt;body&amp;gt;
&amp;lt;p&amp;gt;Hello world&amp;lt;/p&amp;gt;
&amp;lt;style&amp;gt;
	body {
		width: 50px;
	}
&amp;lt;/style&amp;gt;
&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_3_1_696w.png" alt="Diagram showing an HTML body, a CSS box, and a property of width with a value of 50 pixels"&gt;
&lt;figcaption&gt;The browser starts at the &lt;code&gt;body&lt;/code&gt; element. We produce its principal box, which has a width of 50px, and a default height of &lt;code&gt;auto&lt;/code&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_3_2_696w.png" alt="Diagram showing a tree with a CSS box for the body and a CSS box for a paragraph"&gt;
&lt;figcaption&gt;Now the browser moves on to the paragraph and produces its principal box, and since paragraphs have a margin by default, this will impact the height of the body, as reflected in the visual.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_3_3_696w.png" alt="Diagram showing a tree with a CSS box for the body and a CSS box for a paragraph, and now a line box appended to the end"&gt;
&lt;figcaption&gt;Now the browser moves onto the text of “Hello world,” which is a text node in the DOM. As such, we produce a &lt;i&gt;line box&lt;/i&gt; inside of the layout. Notice that the text has overflowed the body. We’ll handle this in the next step.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_3_4_696w.png" alt="Diagram showing a tree with a CSS box for the body and a CSS box for a paragraph, and now a line box appended to the end, which has an arrow pointing back to the paragraph CSS box"&gt;
&lt;figcaption&gt;Because “world” does not fit and we haven’t changed the &lt;code&gt;overflow&lt;/code&gt; property from its default, the engine reports back to its parent where it left off in laying out the text.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_3_5_696w.png" alt="Diagram showing a tree with a CSS box for the body and a CSS box for a paragraph, and now two line boxes appended to the end"&gt;
&lt;figcaption&gt;Since the parent has received a token that its child wasn’t able to complete the layout of all the content, it clones the line box, which includes all the styles, and passes the information for that box to complete the layout.

Once the layout is complete, the browser walks back up the box tree, resolving any &lt;code&gt;auto&lt;/code&gt; or percentage-based values that haven’t been resolved. In the image, you can see that the body and the paragraph is now encompassing all of “Hello world” because its &lt;code&gt;height&lt;/code&gt; was set to &lt;code&gt;auto&lt;/code&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3&gt;Dealing with floats&lt;/h3&gt;

&lt;p&gt;Now let’s get a little bit more complex. We’ll take a normal layout where we have a button that says “Share It,” and float it to the left of a paragraph of Latin text. The float itself is what is considered to be a “shrink-to-fit” context. The reason it is referred to as “shrink-to-fit” is because the box will shrink down around its content if the dimensions are &lt;code&gt;auto&lt;/code&gt;. Float boxes are one type of box that matches this layout type, but there are many other boxes, such as absolute positioned boxes (including &lt;code&gt;position: fixed&lt;/code&gt; elements) and table cells with &lt;code&gt;auto&lt;/code&gt;-based sizing, for example.&lt;/p&gt;

&lt;p&gt;Here is the code for our button scenario:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-markup"&gt;&amp;lt;article&amp;gt;
	&amp;lt;button&amp;gt;SHARE IT&amp;lt;/button&amp;gt;
	&amp;lt;p&amp;gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pellentesq&amp;lt;/p&amp;gt;
&amp;lt;/article&amp;gt;
&amp;lt;style&amp;gt;
	article {
		min-width: 400px;
		max-width: 800px;
		background: rgb(191, 191, 191);
		padding: 5px;
	}

	button {
		float: left;
		background: rgb(210, 32, 79);
		padding: 3px 10px;
		border: 2px solid black;
		margin: 5px;
	}

	p {
		margin: 0;
	}
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_4_1_696w.png" alt="Diagram of a box tree with a CSS box for an article, a CSS box for a button floated left, and a line box"&gt;
&lt;figcaption&gt;The process starts off by following the same pattern as our “Hello world” example, so I’m going to skip to where we begin handling the floated button.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_4_2_696w.png" alt="Diagram of a box tree with a CSS box and a line box that calculates the maximum and minimum width for the button"&gt;
&lt;figcaption&gt;Since a float creates a new &lt;i&gt;block formatting context (BFC)&lt;/i&gt; and is a shrink-to-fit context, the browser does a specific type of layout called &lt;i&gt;content measure&lt;/i&gt;. In this mode, it looks identical to the other layout but with an important difference, which is that it is done in infinite space. What the browser does during this phase is lay out the tree of the BFC in both its largest and smallest widths. In this case, it is laying out a button with text, so its narrowest size, including all other CSS boxes, will be the size of the longest word. At its widest, it will be all of the text on one line, with the addition of the CSS boxes.

&lt;i&gt;Note: The color of the buttons here is not literal. It is for illustrative purposes only.&lt;/i&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_4_3_696w.png" alt="Diagram of a box tree with a CSS box for an article, a CSS box for a button floated left, and a line box, with the CSS box for the button now communicating the min and max width back up to the CSS box for the article"&gt;
&lt;figcaption&gt;Now that we know that the minimum width is 86px, and the maximum width is 115px, we pass this information back to the parent box for it to decide the width and to place the button appropriately. In this scenario, there is space to fit the float at max size so that is how the button is laid out.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_4_4_696w.png" alt="Diagram of a box tree with a CSS box for an article with two branches: a CSS box for a button floated left and a CSS box for a paragraph. The CSS box for the article is communicating the min and max width for the button to the paragraph."&gt;
&lt;figcaption&gt;In order to ensure that the browser adheres to the standard and the content wraps around the float, the browser changes the geometry of the &lt;code&gt;article&lt;/code&gt; BFC. This geometry is passed to the paragraph to use during its layout.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_4_5_696w.png" alt="Diagram of a box tree with a CSS box for an article with two branches: a CSS box for a button floated left and a CSS box for a paragraph. The paragraph has not been parsed yet and is on one line overflowing the parent container."&gt;
&lt;figcaption&gt;From here the browser follows the same layout process as it did in our first example—but it ensures that any inline content’s inline and block starting positions are outside of the constraint space taken up by the float.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_4_6_696w.png" alt="Diagram of a box tree with a CSS box for an article with two branches: a CSS box for a button floated left and a CSS box for a paragraph. The paragraph has now been parsed and broken into four lines, and there are four line boxes in the diagram to show this."&gt;
&lt;figcaption&gt;As the browser continues walking down the tree and cloning nodes, it moves past the block position of the constraint space. This allows the final line of text (as well as the one before it) to begin at the start of the content box in the inline direction. And then the browser walks back up the tree, resolving &lt;code&gt;auto&lt;/code&gt; and percentage values as necessary.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h3&gt;Understanding fragmentation&lt;/h3&gt;

&lt;p&gt;One final aspect to touch on for how layout works is fragmentation. If you’ve ever printed a web page or used CSS Multi-column, then you’ve taken advantage of fragmentation. Fragmentation is the logic of breaking content apart to fit it into a different geometry. Let’s take a look at the same example utilizing CSS Multi-column:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-markup"&gt;&amp;lt;body&amp;gt;
	&amp;lt;div&amp;gt;
		&amp;lt;p&amp;gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras nibh orci, tincidunt eget enim et, pellentesque condimentum risus. Aenean sollicitudin risus velit, quis tempor leo malesuada vel. Donec consequat aliquet mauris. Vestibulum ante ipsum primis in faucibus
		&amp;lt;/p&amp;gt;
	&amp;lt;/div&amp;gt;
&amp;lt;style&amp;gt;
	body {
		columns: 2;
		column-fill: auto;
		height: 300px;
	}
&amp;lt;/style&amp;gt;
&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_5_1_696w.png" alt="Diagram of a box tree showing a CSS box for a body and a multicol box for a div"&gt;
&lt;figcaption&gt;Once the browser reaches the multicol formatting context box, it sees that it has a set number of columns.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_5_2_696w.png" alt="Diagram of a box tree showing a CSS box for a body and a multicol box for a div, now with a fragmentainer CSS box created under the div"&gt;
&lt;figcaption&gt;It follows the similar cloning model from before, and creates a &lt;i&gt;fragmentainer&lt;/i&gt; with the correct dimensions to adhere to the authors desire for their columns.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_5_3_696w.png" alt="Diagram of a box tree showing a CSS box for a body and a multicol box for a div, now with a CSS box for each column and a line box for each line within each column"&gt;
&lt;figcaption&gt;The browser then lays out as many lines as possible by following the same pattern as before. Then the browser creates another fragmentainer and continues the layout to completion.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2&gt;Painting&lt;/h2&gt;

&lt;p&gt;OK, so let’s recap where we’re at to this point. We’ve taken out all the CSS content, parsed it, cascaded it onto the DOM tree, and completed layout. But we haven’t applied color, borders, shadows, and similar design treatments to the layout–adding these is known as painting. &lt;/p&gt;

&lt;p&gt;Painting is roughly standardized by CSS, and to put it concisely (you can read the full breakdown in &lt;a href="https://www.w3.org/TR/CSS22/zindex.html#painting-order"&gt;CSS 2.2 Appendix E&lt;/a&gt;), you paint in the following order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;background;&lt;/li&gt;
&lt;li&gt;border;&lt;/li&gt;
&lt;li&gt;and content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if we take our “SHARE IT” button from earlier and follow this process, it will look something like this:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_6_696w.png" alt="Graphic showing progressive passes of a box: first the background, then the border, the the content"&gt;
&lt;/figure&gt;

&lt;p&gt;Once this is completed, it is converted to a bitmap. That’s right—ultimately every layout element (even text) becomes an image under the hood.&lt;/p&gt;

&lt;h3&gt;Concerning the &lt;code&gt;z-index&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;Now, most of our websites don’t consist of a single element. Moreover, we often want to have certain elements appear on top of other elements. To accomplish this, we can harness the power of the &lt;code&gt;z-index&lt;/code&gt; to superimpose one element over another. This may feel like how we work with layers in our design software, but the only layers that exist are within the browser’s compositor. It might seem as though we’re creating new layers using &lt;code&gt;z-index&lt;/code&gt;, but we’re not—so what are we doing? &lt;/p&gt;

&lt;p&gt;What we’re doing is creating a new stacking context. Creating a new &lt;i&gt;stacking context&lt;/i&gt; effectively changes the order in which you paint elements. Let’s look at an example:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-markup"&gt;&amp;lt;body&amp;gt;
&amp;lt;div id="one"&amp;gt;
	Item 1
&amp;lt;/div&amp;gt;
&amp;lt;div id="two"&amp;gt;
	Item 2
&amp;lt;/div&amp;gt;
&amp;lt;style&amp;gt;
body {
	background: lightgray;
}
div {
	width: 300px;
	height: 300px;
	position: absolute;
	background: white;
	z-index: 2;
}
#two {
	background: green;
	z-index: 1;
}
&amp;lt;/style&amp;gt;
&amp;lt;/body&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Without &lt;code&gt;z-index&lt;/code&gt; utilization, the document above would be painted in document order, which would place “Item 2” on top of “Item 1.” But because of the &lt;code&gt;z-index&lt;/code&gt;, the painting order is changed. Let’s step through each phase, similar to how we stepped through our earlier layouts.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_7_1_696w.png" alt="Diagram of a box tree with a basic layout representing a root stacking context. One box has a z-index of one, another box has a z-index of 2."&gt;
&lt;figcaption&gt;The browser starts with the root box; we paint in the background.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_7_2_696w.png" alt="The same layout, but the box with the z-index of 1 is now rendering."&gt;
&lt;figcaption&gt;The browser then traverses, out of document order to the lower level stacking context (which in this case is “Item 2”) and begins to paint that element following the same rules from above.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_7_3_696w.png" alt="The same layout, but the box with the z-index of 2 is now rendering on top of the previous box"&gt;
&lt;figcaption&gt;Then it traverses to the next highest stacking context (which in this case is “Item 1”) and paints it according to the order defined in CSS 2.2.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The &lt;code&gt;z-index&lt;/code&gt; has no bearing on color, just which element is visible to users, and hence, which text and color is visible. &lt;/p&gt;

&lt;h3&gt;Composition&lt;/h3&gt;

&lt;p&gt;At this stage, we have a minimum of a single bitmap that is passed from painting to the compositor. The compositor’s job is to create a layer, or layers, and render the bitmap(s) to the screen for the end user to see.&lt;/p&gt;

&lt;p&gt;A reasonable question to ask at this point is, “Why would any site need more than one bitmap or compositor layer?” Well, with the examples that we’ve looked at thus far, we really wouldn’t. But let’s look at an example that’s a little bit more complex. Let’s say that in a hypothetical world, the Office team wants to bring Clippy back online, and they want to draw attention to Clippy by having him pulsate via a CSS transform.&lt;/p&gt;

&lt;p&gt;The code for animating Clippy could look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-markup"&gt;&amp;lt;div class="clippy"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;style&amp;gt;
.clippy {
	width: 100px;
	height: 100px;
	animation: pulse 1s infinite;
	background: url(clippy.svg);
}

@keyframes pulse {
	from {
		transform: scale(1, 1);
	}
	to {
		transform: scale(2, 2);
	}
}
&amp;lt;/style&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When the browser reads that the web developer wants to animate Clippy on infinite loop, it has two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It can go back to the repaint stage for every frame of the animation, and produce a new bitmap to send back to the compositor.&lt;/li&gt;
&lt;li&gt;Or it can produce two different bitmaps, and allow the compositor to do the animation itself on only the layer that has this animation applied.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most circumstances, the browser will choose option two and produce the following (I have purposefully simplified the amount of layers Word Online would produce for this example):&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_8_1_696w.png" alt="Diagram showing a root composite layer with Clippy on his own layer"&gt;
&lt;/figure&gt;

&lt;p&gt;Then it will re-compose the Clippy bitmap in the correct position and handle the pulsating animation. This is a great win for performance as in many engines the compositor is on its own thread, and this allows the main thread to be unblocked. If the browser were to choose option one above, it would have to block on every frame to accomplish the same result, which would negatively impact performance and responsiveness for the end user.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_8_2_696w.png" alt="A diagram showing a layout with Clippy, with a chart of the process of rendering. The Compose step is looping."&gt;
&lt;/figure&gt;

&lt;h2&gt;Creating the illusion of interactivity&lt;/h2&gt;

&lt;p&gt;As we’ve just learned, we took all the styles and the DOM, and produced an image that we rendered to the end user. So how does the browser create the illusion of interactivity? Welp, as I’m sure you’ve now learned, so let’s take a look at an example using our handy “SHARE IT” button as an analogy:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-css"&gt;button {
    float: left;
    background: rgb(210, 32, 79);
    padding: 3px 10px;
    border: 2px solid black;
}

button:hover {
    background: teal;
    color: black;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All we’ve added here is a pseudo-class that tells the browser to change the button’s background and text color when the user hovers over the button. This begs the question, how does the browser handle this?&lt;/p&gt;

&lt;p&gt;The browser constantly tracks a variety of inputs, and while those inputs are moving it goes through a process called &lt;i&gt;hit testing&lt;/i&gt;. For this example, the process looks like this:&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/braces-to-pixels/03_Braces_to_Pixels_9_696w.png" alt="A diagram showing the process for hit testing. The process is detailed below."&gt;
&lt;/figure&gt;

&lt;ol&gt;
&lt;li&gt;The user moves the mouse over the button.&lt;/li&gt;
&lt;li&gt;The browser fires an event that the mouse has been moved and goes into the hit testing algorithm, which essentially asks the question, “What box(es) is the mouse touching?”&lt;/li&gt;
&lt;li&gt;The algorithm returns the box that is linked to our “SHARE IT” button.&lt;/li&gt;
&lt;li&gt;The browser asks the question, “Is there anything I should do since a mouse is hovering over you?”&lt;/li&gt;
&lt;li&gt;It quickly runs style/cascade for this box and its children and determines that, yes, there is a &lt;code&gt;:hover&lt;/code&gt; pseudo-class with paint-only style adjustments inside of the declaration block.&lt;/li&gt;
&lt;li&gt;It hangs those styles off of the DOM element (as we learned in the cascade phase), which is the &lt;code&gt;button&lt;/code&gt; in this case.&lt;/li&gt;
&lt;li&gt;It skips past layout and goes directly to painting a new bitmap.&lt;/li&gt;
&lt;li&gt;The new bitmap is passed off to the compositor and then to the user.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To the user, this effectively creates the perception of interactivity, even though the browser is just swapping an orange image to a green one.&lt;/p&gt;

&lt;h2&gt;Et voilà!&lt;/h2&gt;

&lt;p&gt;Hopefully this has removed some of the mystery from how CSS goes from the braces you’ve written to rendered pixels in your browser.&lt;/p&gt;

&lt;p&gt;In this leg of our journey, we discussed how CSS is parsed, how values are computed, and how the cascade actually works. Then we dove into a discussion of layout, painting, and composition. &lt;/p&gt;

&lt;p&gt;Now stay tuned for the final installment of this series, where one of the designers of the JavaScript language itself will discuss how browsers compile and execute our JavaScript.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/ziCmKg402QY" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Browsers, CSS
]]></dc:subject>
      <dc:date>2018-11-15T15:05:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/braces-to-pixels</feedburner:origLink></item><item>
      <title><![CDATA[Tags to DOM]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/travisleithead">Travis Leithead</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/hTxw9s5Q7mo/tags-to-dom</link>
      <guid isPermaLink="false">http://alistapart.com/article/tags-to-dom</guid>
      <description>&lt;p&gt;In our previous segment, “&lt;a href="/article/server-to-client"&gt;Server to Client&lt;/a&gt;,” we saw how a URL is requested from a server and learned all about the many conditions and caches that help optimize delivery of the associated resource. Once the browser engine finally gets the resource, it needs to start turning it into a rendered web page. In this segment, we focus primarily on HTML resources, and how the tags of HTML are transformed into the building blocks for what will eventually be presented on screen.&lt;/p&gt;

&lt;p&gt;To use a construction metaphor, we’ve drafted the blueprints, acquired all the permits, and collected all the raw materials at the construction site; it’s time to start building!&lt;/p&gt;

&lt;h2&gt;Parsing&lt;/h2&gt;

&lt;p&gt;Once content gets from the server to the client through the networking system, its first stop is the HTML parser, which is composed of a few systems working together: encoding, pre-parsing, tokenization, and tree construction. The parser is the part of the construction project metaphor where we walk through all the raw materials: unpacking boxes; unbinding pallets, pipes, wiring, etc.; and pouring the foundation before handing off everything to the experts working on the framing, plumbing, electrical, etc. &lt;/p&gt;

&lt;h2&gt;Encoding&lt;/h2&gt;

&lt;p&gt;The payload of an HTTP response body can be anything from HTML text to image data. The first job of the parser is to figure out how to interpret the bits just received from the server. Assuming we’re processing an HTML document, the decoder must figure out how the text document was translated into bits in order to reverse the process. &lt;/p&gt;

&lt;figure&gt;
&lt;table&gt;
&lt;caption&gt;Binary-to-text representation&lt;/caption&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="row"&gt;Characters&lt;/th&gt;
&lt;th scope="col"&gt;D&lt;/th&gt;
&lt;th scope="col"&gt;O&lt;/th&gt;
&lt;th scope="col"&gt;M&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th scope="row"&gt;ASCII Values&lt;/th&gt;
&lt;td data-title="D"&gt;68&lt;/td&gt;
&lt;td data-title="O"&gt;79&lt;/td&gt;
&lt;td data-title="M"&gt;77&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope="row"&gt;Binary Values&lt;/th&gt;
&lt;td data-title="D"&gt;01000100&lt;/td&gt;
&lt;td data-title="O"&gt;01001111&lt;/td&gt;
&lt;td data-title="M"&gt;01001101&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;th scope="row"&gt;Bits&lt;/th&gt;
&lt;td data-title="D"&gt;8&lt;/td&gt;
&lt;td data-title="O"&gt;8&lt;/td&gt;
&lt;td data-title="M"&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/figure&gt;

&lt;p&gt;(Remember that ultimately even text must be translated to binary in the computer. Encoding—in this case ASCII encoding—defines that a binary value such as “01000100” means the letter “D,” as shown in the figure above.) Many possible encodings exist for text—it’s the browser’s job to figure out how to properly decode the text. The server should provide hints via &lt;code&gt;Content-Type&lt;/code&gt; headers, and the leading bits themselves can be analyzed (for a &lt;a href="https://en.wikipedia.org/wiki/Byte_order_mark"&gt;byte order mark&lt;/a&gt;, or BOM). If the encoding still cannot be determined, the browser can apply its best guess based on heuristics. Sometimes the only definitive answer comes from the (encoded) content itself in the form of a &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; html tag. Worst case scenario, the browser makes an educated guess and then later finds a contradicting &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag after parsing has started in earnest. In these rare cases, the parser must restart, throwing away the previously decoded content. Browsers sometimes have to deal with old web content (using legacy encodings), and a lot of these systems are in place to support that.&lt;/p&gt;

&lt;p&gt;When saving your HTML documents for the web today, the choice is clear: use UTF-8 encoding. Why? It nicely supports the full Unicode range of characters, has good compatibility with ASCII for single-byte characters common to languages like CSS, HTML, and JavaScript, and is likely to be the browser’s fallback default. You can tell when encoding goes wrong, because text won’t render properly (you will tend to get garbage characters or boxes where legible text is usually visible).&lt;/p&gt;

&lt;h2&gt;Pre-parsing/scanning&lt;/h2&gt;

&lt;p&gt;Once the encoding is known, the parser starts an initial pre-parsing step to scan the content with the goal of minimizing round-trip latency for additional resources. The pre-parser is not a full parser; for example, it doesn’t understand nesting levels or parent/child relationships in HTML. However, the pre-parser does recognize specific HTML tag names and attributes, as well as URLs. For example, if you have an &lt;code&gt;&amp;lt;img src="https://somewhere.example.com/&amp;#8203;images/&amp;#8203;dog.png" alt=""&amp;gt;&lt;/code&gt; somewhere in your HTML content, the pre-parser will notice the &lt;code&gt;src&lt;/code&gt; attribute, and queue a resource request for the dog picture via the networking system. The dog image is requested as quickly as possible, minimizing the time you need to wait for it to arrive from the network. The pre-parser may also notice certain explicit requests in the HTML such as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content"&gt;preload&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ"&gt;prefetch directives&lt;/a&gt;, and queue these up for processing as well.&lt;/p&gt;

&lt;h3&gt;Tokenization&lt;/h3&gt;

&lt;p&gt;Tokenization is the first half of parsing HTML. It involves turning the markup into individual tokens such as “begin tag,” “end tag,” “text run,” “comment,” and so forth, which are fed into the next state of the parser. The tokenizer is a state machine that transitions between the different states of the HTML language, such as “in tag open state” (&lt;code&gt;&amp;lt;|video controls&amp;gt;&lt;/code&gt;), “in attribute name state” (&lt;code&gt;&amp;lt;video con|trols&amp;gt;&lt;/code&gt;), and “after attribute name state” (&lt;code&gt;&amp;lt;video controls|&amp;gt;&lt;/code&gt;), doing so iteratively as each character in the HTML markup text document is read. &lt;/p&gt;

&lt;p&gt;(In each of those example tags, the vertical pipe illustrates the tokenizer’s position.)&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/tags-to-dom2/fig2.png" alt="Diagram showing HTML tags being run through a tokenizer to create tokens"&gt;
&lt;/figure&gt;

&lt;p&gt;The &lt;a href="https://html.spec.whatwg.org/multipage/parsing.html"&gt;HTML spec&lt;/a&gt; (see “12.2.5 Tokenization”) currently defines &lt;em&gt;eighty separate states&lt;/em&gt; for the tokenizer. The tokenizer and parser are very adaptable: both can handle and convert any text content into an HTML document—even if code in the text is not valid HTML. Resiliency like this is one of the features that has made the web so approachable by developers of all skill levels. However, the drawback of the tokenizer and parser’s resilience is that you may not always get the results you expect, which can lead to some subtle programming bugs. (&lt;a href="https://validator.w3.org/"&gt;Checking your code in the HTML validator&lt;/a&gt; can help you avoid bugs like this.)&lt;/p&gt;

&lt;p&gt;For those who prefer a more black-and-white approach to markup language correctness, browsers have an alternate parsing mechanism built in that treats any failure as a catastrophic failure (meaning any failure will cause the content to not render). This parsing mode uses the &lt;a href="https://en.wikipedia.org/wiki/XHTML"&gt;rules of XML to process HTML&lt;/a&gt;, and can be enabled by sending the document to the browser with the “application/xhtml+xml” &lt;a href="https://en.wikipedia.org/wiki/MIME"&gt;MIME type&lt;/a&gt; (or &lt;em&gt;any&lt;/em&gt; XML-based MIME type that uses elements in the &lt;a href="https://html.spec.whatwg.org/multipage/infrastructure.html"&gt;HTML namespace&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Browsers may combine the pre-parser and tokenization steps together as an optimization.&lt;/p&gt;

&lt;h2&gt;Parsing/tree construction&lt;/h2&gt;

&lt;p&gt;The browser needs an internal (in-memory) representation of a web page, and, in the &lt;a href="https://dom.spec.whatwg.org/"&gt;DOM standard&lt;/a&gt;, web standards define exactly what shape that representation should be. The parser’s responsibility is to take the tokens created by the tokenizer in the previous step, and create and insert the objects into the Document Object Model (DOM) in the appropriate way (specifically using the &lt;a href="https://html.spec.whatwg.org/multipage/parsing.html"&gt;twenty-three separate states&lt;/a&gt; of its state machine; see “12.2.6.4 The rules for parsing tokens in HTML content”). The DOM is organized into a &lt;a href="https://en.wikipedia.org/wiki/Tree_(data_structure)"&gt;tree data structure&lt;/a&gt;, so this process is sometimes referred to as tree construction. (As an aside, Internet Explorer &lt;a href="https://blogs.windows.com/msedgedev/2017/04/19/modernizing-dom-tree-microsoft-edge/"&gt;did not use a tree structure for much of its history&lt;/a&gt;.)&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/tags-to-dom2/fig3.png" alt="Diagram showing tokens being turned into the DOM"&gt;
&lt;/figure&gt;

&lt;p&gt;HTML parsing is complicated by the variety of error-handling cases that ensure that legacy HTML content on the web continues to have compatible structure in today’s modern browsers. For example, many HTML tags have implied end tags, meaning that if you don’t provide them, the browser auto-closes the matching tag for you. Consider, for instance, this HTML:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;p&amp;gt;sincerely&amp;lt;p&amp;gt;The authors&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The parser has a rule that will create an implied end tag for the paragraph, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-html"&gt;&amp;lt;p&amp;gt;sincerely&amp;lt;/p&amp;gt;&amp;lt;p&amp;gt;The authors&amp;lt;/p&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This ensures the two paragraph objects in the resulting tree are siblings, as opposed to one paragraph object by ignoring the second open tag. HTML tables are perhaps the most complicated where the parser’s rules attempt to ensure that tables have the proper structure.&lt;/p&gt;

&lt;p&gt;Despite all the complicated parsing rules, once the DOM tree is created, all of the parsing rules that try to create a “correct” HTML structure are no longer enforced. Using JavaScript, a web page can rearrange the DOM tree in almost any way it likes, even if it doesn’t make sense! (For example, adding a table cell as the child of a &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tag). The rendering system becomes responsible for figuring out how to deal with any weird inconsistencies like that.&lt;/p&gt;

&lt;p&gt;Another complicating factor in HTML parsing is that JavaScript can add more content to be parsed while the parser is in the middle of doing its job. &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags contain text that the parser must collect and then send to a scripting engine for evaluation. While the script engine parses and evaluates the script text, the parser waits. If the script evaluation includes invoking the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/write"&gt;&lt;code&gt;document.write&lt;/code&gt; API&lt;/a&gt;, a second instance of the HTML parser must start running (&lt;a href="https://en.wikipedia.org/wiki/Reentrancy_(computing)"&gt;reentrantly&lt;/a&gt;). To quickly revisit our construction metaphor, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; and &lt;code&gt;document.write&lt;/code&gt; require stopping all in-progress work to go back to the store to get some additional materials that we hadn’t realized we needed. While we’re away at the store, all progress on the construction is stalled. &lt;/p&gt;

&lt;p&gt;All of these complications make writing a compliant HTML parser a non-trivial undertaking.&lt;/p&gt;

&lt;h2&gt;Events&lt;/h2&gt;

&lt;p&gt;When the parser finishes, it announces its completion via an event called &lt;code&gt;DOMContentLoaded&lt;/code&gt;. Events are the broadcast system built into the browser that JavaScript can listen and respond to. In our construction metaphor, events are the reports that various workers bring to the foreman when they encounter a problem or finish a task. Like &lt;code&gt;DOMContentLoaded&lt;/code&gt;, there are a variety of events that signal significant state changes in the web page such as &lt;code&gt;load&lt;/code&gt; (meaning parsing is done, and all the resources requested by the parser, like images, CSS, video, etc., have been downloaded) and &lt;code&gt;unload&lt;/code&gt; (meaning the web page is about to be closed). Many events are specific to user input, such as the user touching the screen (&lt;code&gt;pointerdown&lt;/code&gt;, &lt;code&gt;pointerup&lt;/code&gt;, and others), using a mouse (&lt;code&gt;mouseover&lt;/code&gt;, &lt;code&gt;mousemove&lt;/code&gt;, and others), or typing on the keyboard (&lt;code&gt;keydown&lt;/code&gt;, &lt;code&gt;keyup&lt;/code&gt;, and &lt;code&gt;keypress&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The browser creates an event object in the DOM, packs it full of useful state information (such as the location of the touch on the screen, the key on the keyboard that was pressed, and so on), and “fires” that event. Any JavaScript code that happens to be listening for that event is then run and provided with the event object. &lt;/p&gt;

&lt;p&gt;The tree structure of the DOM makes it convenient to “filter” how frequently code responds to an event by allowing events to be listened for at any level in the tree (i.e.., at the root of the tree, in the leaves of the tree, or anywhere in between). The browser first determines where to fire the event in the tree (meaning which DOM object, such as a specific &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; control), and then calculates a route for the event starting from the root of the tree, then down each branch until it reaches the target (the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; for example), and then back along the same path to the root. Each object along the route then has its event listeners triggered, so that listeners at the root of the tree will “see” more events than specific listeners at the leaves of the tree. &lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/tags-to-dom2/fig4.png" alt="Diagram showing a route being calculated for an event, and then event listeners being called"&gt;
&lt;/figure&gt;

&lt;p&gt;Some events can also be canceled, which provides, for example, the ability to stop a form submission if the form isn’t filled out properly. (A &lt;code&gt;submit&lt;/code&gt; event is fired from a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element, and a JavaScript listener can check the form and optionally cancel the event if fields are empty or invalid.)&lt;/p&gt;

&lt;h2&gt;DOM&lt;/h2&gt;

&lt;p&gt;The HTML language provides a rich feature set that extends far beyond the markup that the parser processes. The parser builds the structure of which elements contain other elements and what state those elements have initially (their attributes). The combination of the structure and state is enough to provide both a basic rendering and some interactivity (such as through built-in controls like &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, etc.). But without the addition of CSS and JavaScript, the web would be very boring (and static). The DOM provides an additional layer of functionality both to the elements of HTML and to other objects that are not related to HTML at all.&lt;/p&gt;

&lt;p&gt;In the construction metaphor, the parser has assembled the final building—all the walls, doors, floors, and ceilings are installed, and the plumbing, electrical, gas, and such, are ready. You can open the doors and windows, and turn the lights on and off, but the structure is otherwise quite plain. CSS provides the interior details—color on the walls and baseboards, for example. (We’ll get to CSS in the next installment.) JavaScript enables access to the DOM—all the furniture and appliances inside, as well as the services outside the building, such as the mailbox, storage shed and tools, solar panels, water well, etc. We describe the “furniture” and outside “services” next.&lt;/p&gt;

&lt;h3&gt;Element interfaces&lt;/h3&gt;

&lt;p&gt;As the parser is constructing objects to put into the tree, it looks up the element’s name (and namespace) and finds a matching HTML interface to wrap around the object. &lt;/p&gt;

&lt;p&gt;Interfaces add features to basic HTML elements that are specific to their &lt;i&gt;kind&lt;/i&gt; or &lt;i&gt;type&lt;/i&gt; of element. Some generic features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;access to HTML collections representing all or a subset of the element’s children;&lt;/li&gt;
&lt;li&gt;the ability to search the element’s attributes, children, and parent elements;&lt;/li&gt;
&lt;li&gt;and importantly, ways to create new elements (without using the parser), and attach them to (or detach them from) the tree.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For specific elements like &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;, the interface contains additional table-specific features for locating all the rows, columns, and cells within the table, as well as shortcuts for removing and adding rows and cells from and to the table. Likewise, &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; interfaces have features for drawing lines, shapes, text, and images. JavaScript is required to use these APIs—they are not available using HTML markup alone. &lt;/p&gt;

&lt;p&gt;Any DOM changes made to the tree via the APIs described above (such as the hierarchical position of an element in the tree, the element’s state by toggling an attribute name or value, or any of the API actions from an element’s interface) after parsing ends will trigger a chain-reaction of browser systems whose job is to analyze the change and update what you see on the screen as soon as possible. The tree maintains many optimizations for making these repeated updates fast and efficient, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;representing common element names and attributes via a number (using hash tables for fast identification);&lt;/li&gt;
&lt;li&gt;collection caches that remember an element’s frequently-visited children (for fast child-element iteration);&lt;/li&gt;
&lt;li&gt;and sub-tree change-tracking to minimize what parts of the whole tree get “dirty” (and will need to be re-validated).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Other APIs&lt;/h3&gt;

&lt;p&gt;The HTML elements and their interfaces in the DOM are the browser’s only mechanism for showing content on the screen. CSS can affect layout, but only for content that exists in HTML elements. Ultimately, if you want to see content on screen, it must be done through HTML interfaces that are part of the tree.&amp;#8221; (For those wondering about Scalable Vector Graphics (SVG) and MathML languages—those elements must also be added to the tree to be seen—I’ve skipped them for brevity.)&lt;/p&gt;

&lt;p&gt;We learned how the parser is one way of getting HTML from the server into the DOM tree, and how element interfaces in the DOM can be used to add, remove, and modify that tree after the fact. Yet, the browser’s programmable DOM is quite vast and not scoped to just HTML element interfaces. &lt;/p&gt;

&lt;p&gt;The scope of the browser’s DOM is comparable to the set of features that apps can use in any operating system. Things like (but not limited to):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;access to storage systems (databases, key/value storage, network cache storage);&lt;/li&gt;
&lt;li&gt;devices (geolocation, proximity and orientation sensors of various types, USB, MIDI, Bluetooth, Gamepads);&lt;/li&gt;
&lt;li&gt;the network (HTTP exchanges, bidirectional server sockets, real-time media streaming);&lt;/li&gt;
&lt;li&gt;graphics (2D and 3D graphics primitives, shaders, virtual and augmented reality);&lt;/li&gt;
&lt;li&gt;and multithreading (shared and dedicated execution environments with rich message passing capabilities).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The capabilities exposed by the DOM continue to grow as new web standards are developed and implemented by major browser engines. Most of these “extra” APIs of the DOM are out of scope for this article, however.&lt;/p&gt;

&lt;h2&gt;Moving on from markup&lt;/h2&gt;
&lt;p&gt;In this segment, you’ve learned how parsing and tree construction create the foundation for the DOM: the stateful, in-memory representation of the HTML tags received from the network.&lt;/p&gt;

&lt;p&gt;With the DOM model in place, services such as the event model and element APIs enable web developers to change the DOM structure at any time. Each change begins a sequence of “re-building” work of which updating the DOM is only the first step.&lt;/p&gt;

&lt;p&gt;Going back to the construction analogy, the on-site raw materials have been formed into the structural framing of the building and built to the right dimensions with internal plumbing, electrical, and other services installed, but with no real sense yet of the building’s final look—its exterior and interior design.&lt;/p&gt;

&lt;p&gt;In the next installment, we’ll cover how the browser takes the DOM tree as input to a layout engine that incorporates CSS and transforms the tree into something you can finally see on the screen.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/hTxw9s5Q7mo" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Browsers, HTML
]]></dc:subject>
      <dc:date>2018-11-01T12:45:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/tags-to-dom</feedburner:origLink></item><item>
      <title><![CDATA[From URL to Interactive]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/agustafson">Aaron Gustafson</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/NFGEXZdcnGQ/from-url-to-interactive</link>
      <guid isPermaLink="false">http://alistapart.com/article/from-url-to-interactive</guid>
      <description>&lt;p&gt;Imagine, if you will, that you’re behind the wheel of a gorgeous 1957 Chevy Bel Air convertible, making your way across the desert on a wide open highway. The sun is setting, so you’ve got the top down, naturally. The breeze caresses your cheek like a warm hand as your nose catches a faint whiff of … &lt;em&gt;What was that?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The car lurches and chokes before losing all power. You coast, ever more slowly, to a stop. There’s steam rising from the hood. &lt;em&gt;Oh jeez. What the heck just happened?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You reach down to pop the hood, and open the door. Getting out, you make your way around to the front of the car. As you release the latch and lift the bonnet, you get blasted in the face with even more steam. You hope it’s just water.&lt;/p&gt;

&lt;p&gt;Looking around, it’s clear the engine has overheated, but you have no idea what you’re looking at. Back home you’ve got a guy who’s amazing with these old engines, but you fell in love with the luxurious curves, the fins, the plush interior, the allure of the open road.&lt;/p&gt;

&lt;p&gt;A tumbleweed rolls by. In the distance a buzzard screeches.&lt;/p&gt;

&lt;h2&gt;What’s happening under the hood?&lt;/h2&gt;

&lt;p&gt;Years ago, my colleague Molly Holzschlag used a variant of this story to explain the importance of understanding our tools. When it comes to complex machines like cars, knowing how they work can really get you out of a jam when things go wrong. Fail to understand how they work and you could end up, well, buzzard food.&lt;/p&gt;

&lt;p&gt;At the time, Molly and I were trying to convince folks that learning HTML, CSS, and JavaScript was more important than learning Dreamweaver. Like many similar tools, Dreamweaver allowed you to focus on the look and feel of a website without needing to burden yourself with knowing how the HTML, CSS, and JavaScript it produced actually worked. This analogy still applies today, though perhaps more so to frameworks than WYSIWYG design tools.&lt;/p&gt;

&lt;p&gt;If you think about it, our whole industry depends on our faith in a handful of “black boxes” few of us fully understand: browsers. We hand over our HTML, CSS, JavaScript, images, etc., and then cross our fingers and hope they render the experience we have in our heads. But how do browsers do what they do? How do they take our users from a URL to a fully-rendered and interactive page?&lt;/p&gt;

&lt;p&gt;To get from URL to interactive, we’ve assembled a handful of incredibly knowledgeable authors to act as our guides. This journey will take place in four distinct legs, delivered over the course of a few weeks. Each will provide you with details that will help you do your job better.&lt;/p&gt;

&lt;h2&gt;Leg 1: Server to Client&lt;/h2&gt;

&lt;p&gt;Ali Alabbas understands the ins and outs of networking, and he kicks off this journey with a discussion of how our code gets to the browser in the first place. He discusses how server connections are made, caching, and how Service Workers factor into the request and response process. He also discusses the “origin model” and how to improve performance using HTTP2, Client Hints, and more. Understanding this aspect of how browsers work will undoubtedly help you make your pages download more quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://alistapart.com/article/server-to-client"&gt;Read the article&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Leg 2: tags to DOM&lt;/h2&gt;

&lt;p&gt;In the second installment, Travis Leithead—a former editor of the W3C’s HTML spec—takes us through the process of parsing HTML. He covers how browsers create trees (like the DOM tree) and how those trees become element collections you can access via JavaScript. And speaking of JavaScript, he’ll even get into how the DOM responds to manipulation and to events, including touch and click. Armed with this information, you’ll be able to make smarter decisions about how and when you touch the DOM, how to reduce Time To Interactive (TTI), and how to eliminate unintended reflows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://alistapart.com/article/tags-to-dom"&gt;Read the article&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Leg 3: braces to pixels&lt;/h2&gt;

&lt;p&gt;Greg Whitworth has spent much of his career in the weeds of browsers’ CSS mechanics, and he’s here to tell us how they do what they do. He explains how CSS is parsed, how values are computed, and how the cascade actually works. Then he dives into a discussion of layout, painting, and composition. He wraps things up with details concerning how hit testing and input are managed. Understanding how CSS works under the hood is critical to building resilient, performant, and beautiful websites.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://alistapart.com/article/braces-to-pixels"&gt;Read the article&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Leg 4: &lt;code&gt;var&lt;/code&gt; to JIT&lt;/h2&gt;

&lt;p&gt;One of JavaScript’s language designers, Kevin Smith, joins us for the final installment in this series to discuss how browsers compile and execute our JavaScript. For instance, what do browsers do when tearing down a page when users navigate away? How do they optimize the JavaScript we write to make it run even faster? He also tackles topics like writing code that works in multiple threads using workers. Understanding the inner processes browsers use to optimize and run your JavaScript can help you write code that is more efficient in terms of both performance and memory consumption.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://alistapart.com/article/var-to-jit"&gt;Read the article&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Leg 5: Semantics to Screen Readers&lt;/h2&gt;

&lt;p&gt;Now that our page is generated, we need to understand how screen readers access it. Front-end developer Melanie Richards take us through a step-by-step journey. She covers a wide array of screen readers, which vary greatly and are highly customizable to users. Understanding the nuances of accessibility APIs, thorough testing approaches, and the wealth of resources available, site creators can create the most widely accessible content for the most users possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://alistapart.com/article/semantics-to-screen-readers"&gt;Read the article&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Let’s get going&lt;/h2&gt;

&lt;p&gt;I sincerely hope you’ll join us on this trip across the web and into the often foggy valley where browsers turn code into experience.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/NFGEXZdcnGQ" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Browsers, CSS, HTML, JavaScript
]]></dc:subject>
      <dc:date>2018-10-25T13:11:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/from-url-to-interactive</feedburner:origLink></item><item>
      <title><![CDATA[Server to Client]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/alialabbas">Ali Alabbas</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/Uv9E02zIJJc/server-to-client</link>
      <guid isPermaLink="false">http://alistapart.com/article/server-to-client</guid>
      <description>&lt;p&gt;Before anything can happen in a browser, it must first know where to go. There are multiple ways to get somewhere: entering a URL in the address bar, clicking (or tapping) on a link on a page or in another app, or clicking on a favorite. No matter the case, these all result in what’s called a navigation. A navigation is the very first step in any web interaction, as it kicks off a chain reaction of events that culminates in a web page being loaded.&lt;/p&gt;

&lt;h2&gt;Initiating the request&lt;/h2&gt;

&lt;p&gt;Once a URL has been provided to the browser to load, a few things happen under the hood.&lt;/p&gt;

&lt;h3&gt;Check for HSTS&lt;/h3&gt;

&lt;p&gt;First, the browser needs to determine if the URL specifies the HTTP (non-secure) scheme. If it’s an HTTP request, the browser needs to check if the domain is in the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security"&gt;HSTS&lt;/a&gt; list (HTTP Strict Transport Security). This list is comprised of both a preloaded list and a list of previously visited sites that opted-in to using HSTS; both are stored in the browser. If the requested HTTP host is in the HSTS list, a request is made to the HTTPS version of the URL instead of HTTP. This is why you’ll notice that even if you try to type http://www.bing.com into a modern browser, it will send you to https://www.bing.com instead.&lt;/p&gt;

&lt;h3&gt;Check for service workers&lt;/h3&gt;

&lt;p&gt;Next, the browser needs to determine if a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"&gt;service worker&lt;/a&gt; is available to handle the request—this is especially important in the case that the user is offline and does not have a network connection. Service workers are a relatively new feature in browsers. They enable offline-capable web sites by allowing interception of network requests (including the top-level request) so the requests can be served from a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Cache"&gt;script-controlled cache&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A service worker can be registered when a page is visited, a process that records the &lt;a href="https://www.w3.org/TR/service-workers-1/#dfn-scope-to-registration-map"&gt;service worker registration and URL mapping&lt;/a&gt; to a local database. Determining whether a service worker is installed is as simple as looking up the navigated URL in that database. If a service worker exists for that given URL, it will be allowed to handle responding to the request. In the case that the new Navigation Preload feature is available in the browser, and the site makes use of it, the browser will simultaneously also consult the network for the initial navigation request. This is beneficial because it allows the browser to not block on a potentially slower service worker start up.&lt;/p&gt;

&lt;p&gt;In a case where there is no service worker to handle the initial request (or if Navigation Preload is being used), the browser moves on to consulting the networking layer.&lt;/p&gt;

&lt;h3&gt;Check the network cache&lt;/h3&gt;

&lt;p&gt;The browser, via the network layer, will check if there’s a fresh response in its cache. This is usually defined by the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control"&gt;&lt;code&gt;Cache-Control&lt;/code&gt;&lt;/a&gt; header in the response, where setting a &lt;code&gt;max-age&lt;/code&gt; can define how long the cached item is considered fresh, and setting &lt;code&gt;no-store&lt;/code&gt; indicates whether it should be cached at all. And of course, if the browser finds nothing in its network cache, then a network request will be required. If there is a fresh response in the cache, it is returned back for the purposes of loading the page. If there’s a resource found but it’s not fresh, the browser may convert the request to a conditional revalidation request, which contains an &lt;code&gt;If-Modified-Since&lt;/code&gt; or &lt;code&gt;If-None-Match&lt;/code&gt; header that tells the server what version of the content the browser already has in its cache. The server can either tell the browser that its copy is still fresh by returning an &lt;code&gt;HTTP 304 (Not Modified)&lt;/code&gt; with no body, or tell the browser that its copy is stale by returning an &lt;code&gt;HTTP 200 (OK)&lt;/code&gt; response with the new version of the resource. &lt;/p&gt;

&lt;h3&gt;Check for connection&lt;/h3&gt;

&lt;p&gt;If there’s a previously established connection for the host and port for the request, the connection will be reused rather than establishing a new one. If not, the browser consults the networking layer to understand if it needs to do a &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/DNS"&gt;DNS&lt;/a&gt; (Domain Name System) lookup. This would involve looking through the local DNS cache (which is stored on your device), and, depending on the freshness of that cache, remote name servers may also be consulted (they can be hosted by Internet Service Providers), which would eventually result in the correct IP address for the browser to connect to.&lt;/p&gt;

&lt;p&gt;In some cases, the browser may be able to predict which domains will be accessed, and connections to those domains can be primed. The page can hint to the browser which to prime connections to by using &lt;a href="https://www.w3.org/TR/resource-hints/"&gt;resource hints&lt;/a&gt; such as &lt;code&gt;rel="preconnect”&lt;/code&gt; on the link tag. One such scenario where using resource hints is helpful is if a user is on a Bing search results page, and there is an expectation that the first few search results are the most likely to be visited. In this case, priming connections to those domains can help with not having to pay the cost of a DNS lookup and connection setup later on when those links are clicked.&lt;/p&gt;

&lt;h3&gt;Establish connection&lt;/h3&gt;

&lt;p&gt;The browser can now establish a connection with the server so the server knows it will be both sending to and receiving from the client. If we’re using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security/Transport_Layer_Security"&gt;TLS&lt;/a&gt;, we need to perform a TLS handshake to validate the certificate provided by the server.&lt;/p&gt;

&lt;h3&gt;Send the request to the server&lt;/h3&gt;

&lt;p&gt;The first request that will go over this connection is the top-level page request. Typically, this will be an HTML file that gets served from the server back to the client.&lt;/p&gt;

&lt;h3&gt;Handle the response&lt;/h3&gt;

&lt;p&gt;As the data is being streamed over to the client, the response data is analyzed. First, the browser checks the &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Response_header"&gt;headers of the response&lt;/a&gt;. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers"&gt;HTTP headers&lt;/a&gt; are name-value pairs that are sent as part of the HTTP response. If the headers of the response indicate a redirect (e.g., via the Location header), the browser starts the navigation process all over again and returns to the very first step of checking if an HSTS upgrade is required.&lt;/p&gt;

&lt;p&gt;If the server response is compressed or chunked, the browser will attempt to decompress and dechunk it.&lt;/p&gt;

&lt;p&gt;As the response is being read, the browser will also kick off writing it to the network cache in parallel.&lt;/p&gt;

&lt;p&gt;Next, the browser will attempt to understand the MIME type of the file being sent to the browser, so it can appropriately interpret how to load the file. For instance, an image file will just be loaded as an image, while HTML will be parsed and rendered. If the HTML parser is engaged, the contents of the response are scanned for URLs of likely resources to be downloaded so that the browser can start those downloads ahead of time before the page even begins to render. This will be covered in more detail by the next post in this series.&lt;/p&gt;

&lt;p&gt;By this point, the requested navigation URL has been entered into the browser history, which makes it available for navigation in the back and forward functionality of the browser.&lt;/p&gt;

&lt;p&gt;Here’s a flowchart that gives you an overview of what’s been discussed so far, with a bit more detail:&lt;/p&gt;

&lt;figure&gt;
&lt;a href="/d/server-to-client/Flowchart_A_List_Apart_1392w.png"&gt;&lt;img src="/d/server-to-client/Flowchart_A_List_Apart_696w.png" alt="Flowchart showing the path from server to client"&gt;&lt;/a&gt;
&lt;figcaption&gt;Click for full-size image&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;As you know, the page will continue to make requests, because there are many sub-resources on the page that are important for the overall experience, including images, JavaScript, and style sheets. Additionally, resources that are referenced within those sub-resources, such as background images (referenced in CSS) or other resources initiated by &lt;code&gt;fetch()&lt;/code&gt;, &lt;code&gt;import()&lt;/code&gt;, or &lt;code&gt;AJAX&lt;/code&gt; calls. Without these, we would just have a plain page without much interactivity. As you’ve seen in both the explanation earlier and the flowchart, each resource that is requested is in part impacted by the browser’s caching policies.&lt;/p&gt;

&lt;h2&gt;Caching&lt;/h2&gt;

&lt;p&gt;As mentioned previously, the browser manages a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching"&gt;network cache&lt;/a&gt;, which allows previously downloaded resources to be reused in many cases. This is particularly useful for largely unchanging resources, such as logos and JavaScript from frameworks. It’s important to take advantage of this cache as much as possible, because it can help reduce the number of outgoing network requests by instead reusing the locally available cached resource. In turn, this helps minimize the otherwise laborious and latent-prone operations that are required, improving the page load time. &lt;/p&gt;

&lt;p&gt;Of course, the network cache has a quota that impacts both how many items will be stored and how long they’ll be stored for. This doesn’t mean that the website doesn’t get a say in the matter. Cache-Control headers in responses control the browser’s caching logic. In some cases, it’s prudent to tell the browser to not cache an item at all (such as with &lt;code&gt;Cache-Control: no-store&lt;/code&gt;), because it is expected to always be different. In other cases, it makes sense to have the browser cache the item indefinitely via &lt;code&gt;Cache-Control: immutable&lt;/code&gt;, because the response for a given URL will never change. In such a case, it makes sense to use different URLs to point to different versions of the same resource rather than making a change to a resource of the same URL since the cached version would always be used.&lt;/p&gt;

&lt;p&gt;Of course, the network cache is not the only type of cache in the browser. There are programmatic caches that can be leveraged via JavaScript. Specifically, in the example of the service worker given above, an initial resource request for the top-level page can be intercepted by the service worker and can then use a cached item that was defined by the site by one of its programmatic caches. This is useful, because it gives the web site more control over what cached items to use when. These caches are origin-bound, which means that each domain has its own sandboxed set of caches it can control that are isolated from the caches of another domain.&lt;/p&gt;

&lt;h2&gt;Origin model&lt;/h2&gt;

&lt;p&gt;An origin is simply a tuple consisting of the scheme/protocol, the hostname, and the port. For instance, https://www.bing.com:443 has the HTTPS protocol, www.bing.com hostname, and 443 as the port. If any of those are different when compared to another origin, they are considered to be different origins. For instance, https://images.bing.com:443 and http://www.bing.com:80 are different origins.&lt;/p&gt;

&lt;p&gt;The origin is an important concept for the browser, because it defines how data is sandboxed and secured. In most cases, for security purposes, the browser enforces a &lt;A href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy"&gt;same-origin policy&lt;/a&gt;, which means that one origin cannot access the data of another origin—both would need to be the same origin. Specifically, in the caching case presented earlier, neither https://images.bing.com:443 nor http://www.bing.com:80 can see the programmatic cache of the other.&lt;/p&gt;

&lt;p&gt;If bing.com wanted to load a JavaScript file that is from microsoft.com, it would be making a cross-origin resource request on which the browser would enforce the same-origin policy. To allow this behavior, microsoft.com would need to cooperate with bing.com by specifying CORS (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"&gt;Cross-Origin Resource Sharing&lt;/a&gt;) headers that enable bing.com to be able to load the JavaScript file from microsoft.com. It’s good practice to set the correct CORS headers so browsers can appropriately deal with the cross-origin resource requests.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Now that you know how we go from the server to the client—and all the details in between—stay tuned to learn about the next step in loading a web page: how we go from HTML tags to the DOM.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/Uv9E02zIJJc" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Browsers, The Server Side
]]></dc:subject>
      <dc:date>2018-10-25T13:10:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/server-to-client</feedburner:origLink></item><item>
      <title><![CDATA[Writing for Designers]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/scottkubie">Scott Kubie</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/B7yKqNq1wBk/writing-for-designers-excerpt</link>
      <guid isPermaLink="false">http://alistapart.com/article/writing-for-designers-excerpt</guid>
      <description>&lt;p&gt;&lt;b&gt;A note from the editors:&lt;/b&gt; We’re pleased to share an excerpt from the Introduction of Scott Kubie’s &lt;a href="https://abookapart.com/products/writing-for-designers"&gt;&lt;cite&gt;Writing for Designers&lt;/cite&gt;&lt;/a&gt;, from &lt;a href="https://abookapart.com/"&gt;&lt;cite&gt;A Book Apart&lt;/cite&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Shit. The writing. We forgot about the writing. The thing, the design thing…it needs words! Oh man, so many words. I thought somebody…wasn’t the client going to&amp;#8230;shit. We’ve got to get the writing done. We’ve got to get the writing done! How are we going to get the writing done?!&lt;/p&gt;

&lt;p&gt;Don’t worry, friend. I’m here. We’ll get the writing done. The first step is to accept a hard truth: &lt;em&gt;someone&lt;/em&gt; has to do the writing.&lt;/p&gt;

&lt;p&gt;Some teams seem to build their whole process around &lt;em&gt;not&lt;/em&gt; writing. They fill wireframes with &lt;em&gt;lorem ipsum&lt;/em&gt; (that fake Latin text that confuses stakeholders) and write &lt;em&gt;CTA goes here&lt;/em&gt; on their buttons. I’ve been handed my share of comps where anything remotely word-based was represented by a bunch of squiggly lines.&lt;/p&gt;

&lt;p&gt;You know that comic about how to draw an owl? Step one: draw some circles. Step two: draw the rest of the fucking owl. That’s you with your squiggly lines. Rude.&lt;/p&gt;

&lt;p&gt;Everything left unwritten is a mystery box of incomplete design. These mysteries beget other mysteries, and pretty soon you’ve got dozens of screens of things that kinda-sorta-&lt;em&gt;maybe&lt;/em&gt; make sense but none of them can really be final because &lt;em&gt;you never wrote the words&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Choosing words and &lt;em&gt;writing&lt;/em&gt; what appears in an interface forces us to name components, articulate choices, and explain things to the user. It’s part of design.&lt;/p&gt;

&lt;p&gt;We know this, don’t we? We knew it at the beginning of the design project, and yet here we are. Why did we wait?&lt;/p&gt;

&lt;h2&gt;Writing is part of design&lt;/h2&gt;

&lt;p&gt;Words are one of the most &lt;em&gt;powerful&lt;/em&gt; design materials available. They convey deeply complex meanings in a compact space. They load fast. They’re easy to manipulate and easy to transmit. And the best part is, you don’t have to invent any of them! You just have to use them.&lt;/p&gt;

&lt;p&gt;Sometimes words get written off (see what I did there) as mere “details” in our designs. True details can wait until the end of your design process. Words, however, are deeply integrated throughout the user’s experience of your design. Look at your favorite app, site, or interface. Take all the words away and what do you have? Not much!&lt;/p&gt;

&lt;p&gt;Even if the particular thing you’re designing seems light on words, take a broader view and you’ll find words hiding everywhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;error messages and recovery flows&lt;/li&gt;
&lt;li&gt;confirmation screens&lt;/li&gt;
&lt;li&gt;user-visible metadata like page titles and search engine descriptions&lt;/li&gt;
&lt;li&gt;transactional emails&lt;/li&gt;
&lt;li&gt;in-app user assistance&lt;/li&gt;
&lt;li&gt;support documentation&lt;/li&gt;
&lt;li&gt;changelogs&lt;/li&gt;
&lt;li&gt;feature descriptions and marketing copy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are as much a part of the design as the layout, graphics, and animations. Designs &lt;em&gt;depend&lt;/em&gt; on words.&lt;/p&gt;

&lt;p&gt;Even if your design were simple, beautiful, and intuitive, writing can take it one step further. Writing can reinforce how you want users to think about your design. Writing can explain the approach or philosophy that underpins your design. Writing can guide users through complex processes. Writing can even help cover for the quirks and compromises in our designs—hopefully not our first resort, but valuable nonetheless.&lt;/p&gt;

&lt;p&gt;Sometimes the writing isn&amp;#8217;t done because we’re trying to solve everything with “pure design.” Supposed UX thought leaders throw around baloney like “Good design doesn’t need explanation” and “If you have to use words, you’ve failed.” Come on. I hope my pilot knows what all those switches in the cockpit do, but I also hope they’re labeled, just in case.&lt;/p&gt;

&lt;p&gt;To keep things simple in this book, we’ll be talking about three general categories of writing you might have to do to support your design work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Interface copy:&lt;/strong&gt; Often referred to as UI copy or microcopy, this is the text that’s deeply integrated within the interface, like labels for form fields, text on buttons, navigation labels on a website, error messages, and similar. It’s often made of single words or short phrases. If the interface would “break” or be extremely hard to use if you removed this text, we’ll call it interface copy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Product copy:&lt;/strong&gt; Writing that’s integral to the function of the site/product/app/experience, but not necessarily a direct part of the interface—the body of an onboarding email, for instance, or a description of updates to an application in a changelog. This is content focused on helping/supporting the reader.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Marketing copy:&lt;/strong&gt; Longer-form writing that is primarily filling a sales or promotional sort of role. This is content focused on persuading the reader.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depending on your product and organization, you might have many more buckets of content, or you may find the lines especially blurry even between these three. That’s okay! These buckets will just make things easier while we talk about writing in this book. Cool? Cool.&lt;/p&gt;

&lt;p&gt;(Oh, and “copy” is just a way to distinguish words written by a designer from the more generic idea of “text,” which could be just about anything in your system, including user-generated input.)&lt;/p&gt;

&lt;h2&gt;Writing is always hard&lt;/h2&gt;

&lt;p&gt;If you know someone who makes writing look easy, you’re right. They make it look easy. You can’t plan well for a difficult journey if you assume it’s going to be an easy journey. Accepting that writing is hard is an important step toward making it easier and getting it done.&lt;/p&gt;

&lt;p&gt;Writing is hard because it’s personal. Even if you’re writing about something you don’t feel strongly about, or even something you disagree with, it’s still your writing. The words you write carry a little echo of you. To get the writing done, you’re going to have to be a little vulnerable. Maybe a lot.&lt;/p&gt;

&lt;p&gt;Writing is even hard for writers—and since most people don’t realize that, they make it even harder on writers. They don’t give writers enough time to write. They don’t provide enough information to work with. They say things that minimize the difficulty of the task and the skill required to complete it. “You’re so creative! This should be easy, right? Shoot me something back before lunch.” Ugh.&lt;/p&gt;

&lt;p&gt;Unfortunately, there’s no special potion you can take to help you get the writing done, and even the most beautifully retro hipster typewriter still needs you to operate the keys.&lt;/p&gt;

&lt;h2&gt;Workflow gets the writing done&lt;/h2&gt;

&lt;p&gt;So if magic won’t help you get the writing done, what will? In design contexts, a useful way to think about writing is &lt;em&gt;workflow&lt;/em&gt;. Workflow is a big-picture idea that accommodates all kinds of different processes, techniques, and tools.&lt;/p&gt;

&lt;p&gt;If following a recipe is a process, making dinner is a workflow. A dinner-making workflow has obvious phases—plan the meal, prep the ingredients, mix and cook things, finish and serve the meal. The specific steps and outcomes vary depending on the meal, but the basic workflow remains the same.&lt;/p&gt;

&lt;p&gt;This is also a useful way to think about design writing. No matter what you’re cooking up—no matter how custom the request and how many dietary restrictions your stakeholders might have—you’ll follow the same basic workflow each time you do the writing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Prepare (to write)&lt;/li&gt;
&lt;li&gt;Compose (the words)&lt;/li&gt;
&lt;li&gt;Edit (what you wrote)&lt;/li&gt;
&lt;li&gt;Finish (the damn writing)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Planning your workflow means choosing the tools, techniques, people, and processes that will be part of each of these four phases. Until this framework becomes old hat, I recommend explicitly planning your writing workflow. Planning is how you avoid getting stuck. You might not immediately know every single tool, step, and person you’ll need to get the writing done. But knowing even a few things, and giving yourself a basic map to follow to get the writing done, will help you learn what’s missing.&lt;/p&gt;

&lt;p&gt;Planning your workflow doesn’t need to be a long process—or even something you share with other people. You can create a formal, structured worksheet to plan it out (Fig 0.1), you could sketch it out on a whiteboard or in a notebook (Fig 0.2), or simply make some notes at the top of a new document. The important thing is to think about &lt;em&gt;how&lt;/em&gt; you’re going to get the writing done before you start writing.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/wfd/WFD001_-_workflow_planner_worksheet.jpg" alt="An example of a structured worksheet with the assignment and writer details at the top, and space to add details for preparation, composition, editing, and finishing including tools, steps, processes, and more."&gt;
&lt;figcaption&gt;&lt;strong&gt;Fig 0.1:&lt;/strong&gt; A &lt;a href="http://bkaprt.com/resources/writing-for-designers/fig-0.1-workflow-planner-worksheet.pdf"&gt;structured worksheet&lt;/a&gt; can help you plan your writing workflow before you start, and serve as an anchor in the storm throughout the project. If you go this route, I recommend customizing it to suit the particulars of your organization.&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/wfd/WFD002_-_sketched_workflow@2x.jpg"&gt;
&lt;img src="/d/wfd/WFD002_-_sketched_workflow.jpg" alt="A simpler example of a simpler workflow with four quadrants for preparation, composition, editing, and finishing handwritten on a piece of paper."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;&lt;strong&gt;Fig 0.2:&lt;/strong&gt; Planning your workflow on paper doesn’t have to take long, and it’s a nice break from staring at screens. Plus, you can cross things off as you go! (Always satisfying.)&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;h2&gt;You can write&lt;/h2&gt;

&lt;p&gt;Mr. Hays, my high school choir teacher, was a great recruiter. When he’d ask people to try out for choir, they’d protest with some version of “Oh, no, I can’t sing.” Nonsense, he’d say: “If you can talk, you can sing. It’s all the same muscles!” And, more often than not, he’d pull that student right over to a piano and demonstrate to them that they could, in fact, sing.&lt;/p&gt;

&lt;p&gt;In case you’re skeptical, worried, or unsure about whether or not you can handle this, here’s my pitch for writing: writing is just thinking plus typing. You can think. You can type (or otherwise get text into a computer). So yes, you can write.&lt;/p&gt;

&lt;p&gt;We’re going to get into all kinds of methods about how to compose and refine text throughout this book. But at the end of the day, writing is just thinking plus typing. Have some thoughts in your head, then write them down. Do this over and over until the writing is done. Every other tip, trick, method, and process is just an improvement or distillation of this basic approach.&lt;/p&gt;

&lt;p&gt;And more good news: writing is more like design than you might think. Common design activities like framing the problem, identifying constraints, and exploring solutions are part of writing, too. Many of the methodologies one might use in UX work can be part of a writing workflow: stakeholder interviews, user research, content auditing, ideation workshops, critiques, and more.&lt;/p&gt;

&lt;p&gt;Writing is always hard, yes. But it gets easier.&lt;/p&gt;

&lt;p&gt;Good? Good. We&amp;#8217;re making progress already. It’s time to Prepare.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/B7yKqNq1wBk" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Writing, Workflow &amp; Tools
]]></dc:subject>
      <dc:date>2018-10-18T13:58:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/writing-for-designers-excerpt</feedburner:origLink></item><item>
      <title><![CDATA[Designing for Cognitive Differences]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/brandongregory">Brandon Gregory</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/glRyt4-1OLc/designing-for-cognitive-differences</link>
      <guid isPermaLink="false">http://alistapart.com/article/designing-for-cognitive-differences</guid>
      <description>&lt;p&gt;&lt;a href="https://idrc.ocadu.ca/index.php/resources/idrc-online/library-of-papers/443-whatisinclusivedesign"&gt;Inclusive design&lt;/a&gt; is designing to be inclusive of as many users as possible, considering all aspects of diversity in users. With increased understanding, compassionate discussions around how to design for disabilities are becoming increasingly common in the web industry. But even with this growth, there are misconceptions: accessibility is still frequently thought of as “design for blind people” when it’s so much more than that. Users with limited motor functions and those who are hearing-impaired require separate considerations, for instance. But accessibility and inclusiveness also mean considering more than just physical symptoms. What about users with cognitive differences like inattention, anxiety, and depression? &lt;/p&gt;

&lt;p&gt;Many affective and anxiety disorders qualify as disabilities, with inattention causing challenges on the web as well. Whatever the cause, inattention, anxiety, and depression can have a major impact on internet usage for users dealing with them. The unique issues presented by cognitive differences and the design considerations they require can be tricky to understand for people who have never dealt with them. Through this article, I’ll share some methods to accommodate these users’ unique needs. &lt;/p&gt;

&lt;h2&gt;Inattention&lt;/h2&gt;

&lt;p&gt;Inattention is often regarded as a joke in our industry (and just about everywhere else), but it can be a serious impediment for people who struggle with it. While Attention Deficit Hyperactivity Disorder (ADHD) is a common culprit, &lt;a href="https://www.nimh.nih.gov/health/statistics/attention-deficit-hyperactivity-disorder-adhd.shtml"&gt;affecting 4.4% of adults&lt;/a&gt;, it’s not the only source of inattention. Bipolar disorder (&lt;a href="https://www.nimh.nih.gov/health/statistics/bipolar-disorder.shtml"&gt;estimated at 2.8% of adults&lt;/a&gt;), major depression (&lt;a href="https://www.nimh.nih.gov/health/statistics/major-depression.shtml"&gt;6.7% of adults&lt;/a&gt;), and anxiety disorders (&lt;a href="https://www.nimh.nih.gov/health/statistics/any-anxiety-disorder.shtml"&gt;19.1% of adults&lt;/a&gt;) can cause occasional inattention. More common conditions such as stress or sleep deprivation can cause inattention in people who don’t experience it as regularly.&lt;/p&gt;

&lt;p&gt;I’m quite familiar with inattention because I have &lt;a href="https://www.nimh.nih.gov/health/topics/bipolar-disorder/index.shtml"&gt;bipolar disorder&lt;/a&gt;, which frequently causes inattention in manic phases. The term &lt;i&gt;inattention&lt;/i&gt; is a bit of a misnomer, because it implies that those suffering from it have trouble paying attention to anything. It’s more accurate to say that we have to pay attention to everything—we have trouble tuning things out, and the more things that are competing for our attention, the harder it is for us to focus on anything.&lt;/p&gt;

&lt;p&gt;Designers who are able to focus normally rarely see the things that cause problems for users with inattention, but these things are everywhere, and they can make the web much harder for us to use. Some design considerations we can make to be more inclusive of users with inattention include adding an option to mute notifications at certain times, which is a more obvious solution while others are less so, such as giving users the ability to turn off design features that are distracting them. &lt;/p&gt;

&lt;h3&gt;Drowning in the ocean of motion&lt;/h3&gt;

&lt;p&gt;I was recently reading an article on search engine optimization, and the author saw fit to incorporate animated GIFs throughout the article. The GIFs, looped infinitely and placed prominently, didn’t add anything of substance. Worse, as I was already struggling through a manic episode, the GIFs actually prevented me from reading the article—I had to open Chrome DevTools and hide all of the GIFs to get through the content. &lt;/p&gt;

&lt;p&gt;Motion is everywhere. This simple fact of the modern internet makes designers smile, while users with inattention issues cringe. &lt;a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3837230/"&gt;Motion distracts people with inattention even when neurotypical people, or those not characterized by neurological patterns, are fine.&lt;/a&gt; Most users struggling with inattention won’t use Chrome DevTools to make your site usable for them, they’ll simply leave and probably end up on a competitor’s site. I cringe anytime I see an article with pointless animation, and often just click the back button. Even though I’m sure the designer or author saw the motion as beneficial, it can distract users who struggle with inattention from what they came to your site to do.&lt;/p&gt;

&lt;p&gt;Motion isn’t always bad. Sometimes you need to use subtle motion to draw attention to something, such as when a user has to click a button before changes are applied. User-initiated motions, such as hover and click effects, usually don’t distract. Your website or app doesn’t need to be a static, motionless wasteland. But if you’re going to distract your users with motion that they don’t initiate, it had better accomplish something.&lt;/p&gt;

&lt;p&gt;Unnecessary motion, like the animated GIFs I mentioned above, are nothing but a barrier for these users. If the motion is actually accomplishing something, you have to ask if what you’re drawing attention to is worth sacrificing other content on the page in return. Designers and content developers tend to use motion—autoplayed videos, animated GIFs, and CSS animations—simply to be cute or expressive. Inclusive design would use motion only to improve clarity so as not to exclude users struggling with inattention. If motion would significantly improve the experience for neurotypical users, but hurt it for users with inattention, you can give users the option to turn off motion, allowing them to choose which would be best for them.&lt;/p&gt;

&lt;h3&gt;Designing forms for inattention&lt;/h3&gt;

&lt;p&gt;Forms add layers of interactivity and are often at the center of what we want users to do on our websites or apps; and yet, forms are often hard to use for users who struggle with inattention. Poor design reduces clarity and increases errors; some interactions take so long that they become extremely difficult for those of us with inattention. Rather than slapping on a quick fix or letting ease of implementation define the user experience, we need to fix design issues to be more inclusive of these users.&lt;/p&gt;

&lt;p&gt;In my twelve years in the industry, there’s a phrase I hear way too often: “Why can’t the users just follow the directions?” This doesn’t show a problem with the user, but with the site or app. The problem isn’t with the directions—it’s with the design.&lt;/p&gt;

&lt;p&gt;If users are making mistakes on a form, our first instinct is to add instructions before it. There are two problems here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most people will not read the instructions. Stats show that of the $13.8 billion of technical gadgets that were returned to the store by consumers in 20o7, &lt;a href="https://www.engadget.com/2008/06/03/95-percent-of-all-returned-gadgets-still-work-americans-dont-r/"&gt;only 5% were due to faulty products&lt;/a&gt;. The rest were because users did not understand how to use the products. Users hate reading instructions.&lt;/li&gt;
&lt;li&gt;Your form is so complicated that it requires instructions. A better solution would be to fix the design of the form itself so you’re not attempting to solve a design problem with content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If most users are making mistakes on a form, users with inattention will struggle even more. When this happens, figure out exactly where the errors are occurring, and fix the design of the form to target that error. For instance, if you’re receiving the wrong data for a field, it’s a sign that form labels are unclear; if you have inline-only labels, adding regular labels outside of the fields will do more than adding an explanatory note. Taking steps like this will make the process less confusing, reducing the need to have long instructions. If an explanation is needed, add it adjacent to the form field where users are having trouble, not at the top of the form where users will likely ignore it. The best option is to simplify the form so that explanations are not needed.&lt;/p&gt;

&lt;p&gt;Inattention also makes sustained concentration considerably more difficult, and the longer your form or process is, the harder it will be for users with inattention to complete in one sitting. If it is more than two steps or pages, add the functionality to save progress and come back later to finish it. Please, please, please don’t have your multi-page form time out quickly—if they come back from a break and find that your form has lost their progress, they probably won’t be starting over.&lt;/p&gt;

&lt;h2&gt;Anxiety&lt;/h2&gt;

&lt;p&gt;Anxiety is a fairly common problem for adults. Among adults, 19.1% have an &lt;a href="https://www.nimh.nih.gov/health/topics/anxiety-disorders/index.shtml"&gt;anxiety disorder&lt;/a&gt;, but anxiety can also result from other things, like taking certain medications, withdrawal from drugs or alcohol, prolonged stress, or chronic pain. As common as anxiety is, you’d think we’d be better at designing for it than we are.&lt;/p&gt;

&lt;p&gt;Anxiety has been described as knowing that you turned off the stove, but having to turn your car around to check anyway. Users with anxiety fear that they will do something wrong when interacting with your site or app. To counteract this, provide reassurance that what they’re doing is the right thing, and make the experience forgiving if they do the wrong thing. Reassuring them reduces stress and helps to retain anxious users who are more likely to leave in the middle of a difficult process.&lt;/p&gt;

&lt;h3&gt;Let users think like users&lt;/h3&gt;

&lt;p&gt;Nobody goes to your site not knowing why they’re there. If users go to your site to solve a problem, they need to know where to find the solution. The problem may be common to all users, but users with anxiety will struggle more when they can’t find the answers they need or when the way forward is unclear.&lt;/p&gt;

&lt;p&gt;One of the biggest culprits of unclear user flow is basing the user experience on your company’s understanding of the problem. Companies have their own &lt;em&gt;internal&lt;/em&gt; terminology and organizational structures to address these problems &lt;em&gt;internally&lt;/em&gt;. Users likely won’t understand any of this and shouldn’t require a glossary of industry terms or internal structures in order to use your website or app.&lt;/p&gt;

&lt;p&gt;Define clear paths for users to solve common problems, and design them to address the user’s concerns; don’t give a list of the types of data you accept or organize things according to how your company receives them. If you have multiple types of users using your site (for instance, parents applying for school as well as school administrators), define clear user paths for each.&lt;/p&gt;

&lt;p&gt;Remember that many of your users will not always start on the homepage of your site. If the user paths are only clear on the homepage, then they’re not clear.&lt;/p&gt;

&lt;p&gt;Provide clear wayfinding. Even once anxious users are on the path to their solution, they need to know they’re heading in the right direction. On each step of a process, state not only what step they’re on, but what the end of that path is. Remember, anxious users may have a need to keep checking to make sure they’re in the right spot—don’t make them click the back button to do that.&lt;/p&gt;

&lt;h3&gt;There’s no anxiety like form anxiety&lt;/h3&gt;

&lt;p&gt;With a good chunk of anxiety being caused by the fear that you’re doing something wrong, forms are a huge stressor for anxious users. A lack of clarity on forms really harms usability and accessibility for users with anxiety, sometimes causing them to stop the process altogether. Improving clarity and providing reassurance can go a long way in reducing anxiety in these users.&lt;/p&gt;

&lt;p&gt;Every form and action should be clearly labeled with a headline that plainly states what the form does. I occasionally struggle with anxiety, and there are times when I have to glance up at the headline to double-check that I’m filling out the right form.&lt;/p&gt;

&lt;p&gt;Similarly, submit buttons should clearly state what happens when users click them. Submit buttons should have copy like “send message,” “complete purchase,” “continue to the next step,” or “sign up for our newsletter.” One of the worst things you can do with a submit button is have it just say “submit.”&lt;/p&gt;

&lt;p&gt;There’s a trend for designers to get overly clever with form labels: inline-only labels, labels that only appear when their field has focus, or even labels that start inside their field and then animate elsewhere. I’ve never encountered a situation where I was glad these overly clever solutions were in place. A label exists not only to tell users what information to put in the field, but also to confirm to users who have already filled out the form that their information is in the right place. Inline-only form labels make this impossible and cause undue stress to anxious users. Labels that cover up auto-filled text (common with labels that start inside form fields and then move somewhere else) cause similar problems. Form labels are not a medium for creative expression; they’re a tool for users to know how to use a form. This basic functionality should not be hindered.&lt;/p&gt;

&lt;p&gt;If you’re asking the user for any personal information, privacy is a huge concern, especially for users suffering from social anxiety who dread getting unexpected phone calls. Include a prominent link to your privacy policy on the form itself so it’s easy to find. Also, if it’s not immediately obvious why a piece of information is needed in your form, like a phone number, add a bit of help text to explain it. (For example, clicking a “Why do we need this?” link displays a “We need your phone number to call you in case of a mix-up with your order” tooltip.) If you don’t have a good reason for asking for a piece of personal information or can’t clearly explain why you need it, get rid of the field.&lt;/p&gt;

&lt;p&gt;And your job is not done once the user has submitted the form. Confirmation messages can be either a huge relief or a huge source of stress for anxious users. I can’t tell you how many times I’ve submitted a form online and the confirmation message just says, “Your data was submitted.” For users with anxiety, this can start the stress cycle all over again. &lt;i&gt;What data? Submitted where? What if I messed something up?&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Confirmation messages should state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what action was taken (“Thank you for signing up for our newsletter!”);&lt;/li&gt;
&lt;li&gt;what data was posted (“Your email address, brandon.gregory@myemail.com, has been added to our distribution list.”);&lt;/li&gt;
&lt;li&gt;and what the user should do if they made a mistake (“If you want to stop receiving our newsletter at any time, you can unsubscribe on your user profile.”).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adding this little bit of reassurance can really help users struggling with anxiety to avoid undue stress.&lt;/p&gt;

&lt;h2&gt;Depression&lt;/h2&gt;

&lt;p&gt;Depression is not something we think about often in design, but it impacts how a lot of people use the web. About 6.7% of adults have &lt;a href="https://www.nimh.nih.gov/health/topics/depression/index.shtml"&gt;major depression&lt;/a&gt;, and 2.8% of adults have bipolar disorder, which involves severe depression at times. Additionally, temporary or even long-term depression can be caused by traumatic events, drug use, or certain medications.&lt;/p&gt;

&lt;p&gt;The book &lt;a href="https://abookapart.com/products/design-for-real-life"&gt;&lt;cite&gt;Design for Real Life&lt;/cite&gt;&lt;/a&gt;, by Sara Wachter-Boettcher and Eric Meyer (&lt;a href="https://alistapart.com/article/design-for-real-life-excerpt"&gt;excerpt here&lt;/a&gt;), reminds us that we can’t just design for happy users. Some of our users will be in crisis: having their order mishandled, desperately needing information that’s not readily available, or just having an exceptionally bad day. For users with depression, any ordinary day has the potential to be an exceptionally bad day or crisis, and minor annoyances in user experience can become overwhelming.&lt;/p&gt;

&lt;h3&gt;Keep it easy&lt;/h3&gt;

&lt;p&gt;Depression is thought of as a psychological condition, but it also has physical side effects. For instance, &lt;a href="https://www.health.harvard.edu/newsletter_article/the-quirky-brain-how-depression-may-alter-visual-perception"&gt;depression actually impairs contrast perception&lt;/a&gt;—the world really does look gray for users dealing with depression. Fatigue and physical pain are common and can be hard to deal with. Everything is harder with depression. If your site or app is hard to use, many depressed users will simply not use it. A lot of the shortcuts we take in the web industry add up to insurmountable challenges for these users.&lt;/p&gt;

&lt;p&gt;A great example of this is unnecessary user registrations. Registering for a user account is a lengthy (and, for depressed users, exhausting) process. If it’s not absolutely required for a user task, you’re punishing depressed users (and probably everyone else too). If your site has a checkout process, make sure users can check out as a guest. Forcing a user to register for an account just to look at the content (I’m looking at you, Pinterest) is a great way to make sure depressed users will never look at your content.&lt;/p&gt;

&lt;p&gt;Long sign-up processes, unforgiving forms, and loss of data can quickly make depressed users give up altogether. Minor annoyances such as these can slide through the design-and-build process for our sites and apps, and impact depressed users much more than neurotypical ones.&lt;/p&gt;

&lt;p&gt;If content requires significant effort to locate, it will also be ignored by depressed users. Large blocks of endless content, like wall-to-wall tiles, force users to sift through it to find what they’re looking for. Long videos without accompanying text (that is searchable) can similarly be a deterrent. Assuming that users are so in love with your content that they will read or view every bit of it is naïve and creates a significant barrier for depressed users (and can also hinder users with inattention).&lt;/p&gt;

&lt;h3&gt;Chat can be a lifesaver&lt;/h3&gt;

&lt;p&gt;I get severely depressed three to six months out of the year, and talking to people is one of the hardest things I have to do. The effort required to carry on an actual conversation is immense, and it prevents me from doing a lot of things that I would ordinarily be doing. Add to that stress the stress of a botched order or customer service fiasco, and I sometimes get so stressed out, I can’t make phone calls that I need to. In these situations, any place that lets me contact them via chat instead of a phone call gains my eternal gratitude. &lt;/p&gt;

&lt;p&gt;A great example of this is the National Suicide Prevention Hotline (because if anyone knows how to design for depressed users, it’s this group), who opened their online chat in 2013. By 2015, the chat lines were open 24 hours a day. Chat lines are unfortunately frequently clogged, partly due to the influx of users and partly due to a lack of funding, but the number of chat operators is growing each year. Chat lines attract a different demographic: while the phone line is roughly a 50-50 split between male and female, &lt;a href="https://www.theatlantic.com/health/archive/2015/07/online-crisis-hotlines-chat-prevention/398312/"&gt;the chat line is 78–80% female&lt;/a&gt; (70% of the total were women under 25).&lt;/p&gt;

&lt;p&gt;The article linked to in the paragraph above revealed some other interesting stats. The National Suicide Prevention Hotline is not the only crisis center that has caught onto this. The National Domestic Violence Hotline launched chat in 2013 and now receives 1,000–1,500 chats a month. The Rape, Abuse &amp;amp; Incest National Network (RAINN) has implemented a chat on their site, and they’ve found that chat users typically go into more depth about their traumatic issues than callers. And, like the National Suicide Prevention Hotline, both of these organizations are looking to scale up their chat services due to how popular they are.&lt;/p&gt;

&lt;p&gt;Businesses that regularly work with users in crisis have realized that chat is a vital tool for their users and are rapidly expanding their chat services to accommodate. Your business may not exclusively deal with crisis users, but with depression affecting a significant portion of the population, any day can be a crisis day for these users. If you have a phone line but not a chat, consider adding one. If you have a chat line and it’s constantly clogged, consider expanding the service.&lt;/p&gt;

&lt;h2&gt;Disability takes many forms, as should inclusive solutions&lt;/h2&gt;

&lt;p&gt;Far from being just about impaired vision and wheelchairs, disability takes many forms, and accessibility and inclusive design need to take just as many. In our industry, compassionate discussion around physical disabilities has been a huge benefit, and cognitive differences need to be part of the conversation too. Removing unnecessary distractions, reassuring users that they’re doing the right thing, and keeping things easy for users who are struggling are things we can do to accommodate these users and make them feel like you actually want them to use our sites and apps. As one of these users myself, I can say we would really appreciate your efforts. This can be just as important as including alt text for your images.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/glRyt4-1OLc" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[User Experience, Accessibility
]]></dc:subject>
      <dc:date>2018-10-16T12:26:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/designing-for-cognitive-differences</feedburner:origLink></item><item>
      <title><![CDATA[The FAQ as Advice Column]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/carolineroberts">Caroline Roberts</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/_MuICA3Ji38/the-faq-as-advice-column</link>
      <guid isPermaLink="false">http://alistapart.com/article/the-faq-as-advice-column</guid>
      <description>&lt;p&gt;&lt;strong&gt;Dear &lt;cite&gt;A List Apart&lt;/cite&gt;,&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I have a problem that may be harming my content strategy career. In my current position, no one likes FAQs … except for me. The question-and-answer format is satisfying and efficient. Whenever I mention adding an FAQ section to a website, though, I receive numerous suggestions that I should wean myself off FAQs one question at a time or go cold turkey.&lt;/p&gt;

&lt;p&gt;Perhaps that is overdoing it, but sometimes I feel like defending FAQs by pen, sword, or Dothraki horde. Should I keep my addiction to myself, or should I embrace this oddity and champion a format I believe in?&lt;/p&gt;

&lt;p&gt;Signed,&lt;br /&gt;
FAQ Fanatic&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dear FAQ Fanatic,&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You’re not wrong: FAQs are as out of vogue as a fat footer. You’re also not alone. As an aspiring advice columnist, I’ve been wondering why the format is so unpopular even though it remains on many websites. In fact, in a recent &lt;cite&gt;A List Apart&lt;/cite&gt; piece, &lt;a href="https://alistapart.com/article/order-out-of-chaos-patterns-of-organization-for-writing-on-the-job"&gt;Richard Rabil, Jr. listed the FAQ&lt;/a&gt; as one of many legitimate patterns of organization that you can use when writing.&lt;/p&gt;

&lt;p&gt;To address your query properly, I propose some soul-searching through a series of FAQs about FAQs. Let’s tackle the toughest question first.&lt;/p&gt;

&lt;h2&gt;Can I trust FAQs?&lt;/h2&gt;

&lt;p&gt;If you are a content strategist or information architect, chances are good you’ve been burned. &lt;a href="https://alistapart.com/article/no-more-faqs-create-purposeful-information-for-a-more-effective-user-experi"&gt;Lisa Wright nails every single reason why&lt;/a&gt; the FAQ can be bad news. It is a poor excuse for a proper content strategy that would generate “purposeful information” across a website. For example, if you see an FAQ, you know right away that the website is duplicating content, which often leads to discrepancies.&lt;/p&gt;

&lt;p&gt;FAQs may also lead to a bigger design issue: accordion abuse. The typical FAQ design involves expand-and-collapse features. In theory, this makes it easier for users to scan to find what they need. But in a content migration or consolidation, I’ve seen desperate freelancers or webmasters shove entire web pages under a question just to make an old page fit a new design. If a user is coming to an FAQ for a quick-hit answer, as is often the case, imagine how horrifying it can be to expand a question and see an answer the length of David Foster Wallace’s &lt;cite&gt;Infinite Jest&lt;/cite&gt; tucked underneath.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/faq-advice/Too-Much-Text.png" alt="Example of long text displaying in an expanded accordion within an FAQ."&gt;
&lt;figcaption&gt;How many times have you opened an FAQ accordion and been overwhelmed by the novella beneath?&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;h2&gt;Can the FAQ and I still be friends?&lt;/h2&gt;

&lt;p&gt;Ah, you must be a content author. If you’re a content author on a budget, under a deadline, or both, the FAQ will become your bestie—whether you planned on it or not. In my experience, teams bust out the FAQs not because they are lazy but because they find them to be a reliable way to structure content. &lt;/p&gt;

&lt;p&gt;When I worked at an agency, a few of my projects were microsites that weren’t so “micro.” Some clients wanted a small site on a minimal CMS within an even more minimal timeline, but the content kept ballooning, leaving no time for true &lt;a href="https://alistapart.com/article/object-oriented-ux"&gt;content modeling&lt;/a&gt;. The only way to build the content on time was to use the FAQ as a content model or spine.&lt;/p&gt;

&lt;p&gt;Like you, I now work with people who avoid FAQs. Since my current agency specializes in site redesigns for higher-ed clients, it’s expected that the information has more structure to begin with—and it usually does. Plus, my particular agency gives information architects and content strategists more time than the norm. From the get-go, our sitemaps, wireframes, and patterns serve as a stable foundation for the content.&lt;/p&gt;

&lt;p&gt;Sometimes, though, even the most stable foundations won’t prevent the appearance of an FAQ. If a content team doesn’t get enough time to &lt;a href="https://alistapart.com/article/the-hidden-work-of-content"&gt;inventory their content&lt;/a&gt;, they’ll probably encounter numerous FAQs. They’ll need to figure out a way to get that content over to the new site somehow … which means those FAQs aren’t going anywhere.&lt;/p&gt;

&lt;h2&gt;So, do I have to quit FAQs cold turkey?&lt;/h2&gt;

&lt;p&gt;No. The FAQ structure has held up for so long because it is a brilliant pattern. Think the Socratic method. Or the catechism. Or Usenet. Or “&lt;a href="https://www.newyorker.com/humor/daily-shouts/f-a-q-s-about-f-a-q-s"&gt;F.A.Q.s about F.A.Q.s&lt;/a&gt;.” Or—you guessed it—“Dear Prudence,” “Dear Sugar,” or any other popular advice column. Users will always have questions, and they will always want answers.&lt;/p&gt;

&lt;p&gt;What makes FAQs troublesome is incorrect or lazy use. Lisa Wright has already shared what not to do, but perhaps the best way to start an FAQ is to choose each question with great care. For example, advice columnists spend plenty of time selecting what questions they will answer each week. In general, listeners want to hear the advice columnist flexing their mental muscles to resolve the most complicated situations.&lt;/p&gt;

&lt;p&gt;If you’re using FAQs correctly, start with the best content possible, and align that content with what both &lt;strong&gt;content authors&lt;/strong&gt; and &lt;strong&gt;content consumers&lt;/strong&gt; want. Content authors can rely on the Q&amp;amp;A structure to deliver quality content on a regular basis while reassuring content consumers that they are receiving the best answers.&lt;/p&gt;

&lt;h3&gt;FAQ-appropriate content&lt;/h3&gt;

&lt;p&gt;What is the best content for an FAQ? Thus far, I’ve discussed choosing your questions wisely and keeping your answers short (and, yes, shorter than the answers of a typical advice columnist). Since I’ve worked in higher ed, I’ve had the chance to speak with people who support admissions and enrollment, and they spend most of their time answering frequently asked questions from students and parents.&lt;/p&gt;

&lt;p&gt;In one stakeholder interview session with the staff of a community college, it became clear that the questions the staff handled fell into two camps: the questions people ask over and over and the head-scratching edge cases. For example, questions about transcripts or financial aid awards are timeless. As for the edge cases, a full-time student might ask if he or she can get a discount if they want to take a yoga class through a community education program. &lt;/p&gt;

&lt;p&gt;For the common content, FAQs shouldn’t repeat what’s already on the website, but they are called “frequently asked questions” for a reason. As long as you provide the content only twice—once in the FAQ and once on a relevant content page—you’re fine. Your authors shouldn’t have to manage anything past that.&lt;/p&gt;

&lt;p&gt;With an edge case, the question might be so specific that the answer wouldn’t have a clear home on any page—in my example, the yoga class question would straddle full-time registration and community education. Therefore, even though the off-the-wall question isn’t “frequently asked,” it can still live in the FAQ, and if the edge cases pile up (as they can in the world of higher ed), then you could shift these questions to a blog, which could provide a source of fresh content.&lt;/p&gt;

&lt;p&gt;I wouldn’t have known about the full-time student who wants to take a community ed class if it hadn’t emerged during the stakeholder interview. For that reason, you want to talk to customers or students and ask them what questions they’ve had in the past. If you don’t have time for that, read over user research to find out what users typically ask.&lt;/p&gt;

&lt;p&gt;Or use Google Search Console to look at the search queries that lead to your site, and figure out how well your site answers those questions. You may find that many of the queries leading to your site are written as questions. In fact, according to &lt;a href="https://moz.com/blog/state-of-searcher-behavior-revealed"&gt;a study by Moz and Jumpshot&lt;/a&gt;, questions make up approximately 8% of search queries, so this research may help you populate your FAQ. And if you’re looking for inspiration, you could try a tool like &lt;a href="https://answerthepublic.com/"&gt;Answer the Public&lt;/a&gt; (free to access UK data; a monthly payment required for other regions). Type in a keyword like “college applications,” and the tool will serve up a range of questions people have asked in their search queries.&lt;/p&gt;

&lt;p&gt;The final way to articulate what works for an FAQ is to describe what doesn’t work. If your answer begins to spin into a narrative instead of a straightforward answer, you might need to add a separate page of content to your sitemap. And if your answer starts to sound too much like marketing copy, then it belongs elsewhere on the site. FAQs exist for those who are further along in the sales process or those who are already sold. Continuing to sell to that audience in an FAQ will only annoy them.&lt;/p&gt;

&lt;p&gt;When you know which questions you’re going to cover, you can start to refine the language for your main audiences: authors and consumers.&lt;/p&gt;

&lt;h3&gt;FAQs for content authors: your in-house reference desk&lt;/h3&gt;

&lt;p&gt;A clever content author can use an FAQ as a core research document. Armed with a CMS that has a decent back-end search, a content author will have a much easier time keeping content aligned and fact-checked if the FAQ itself is treated as a trustworthy source of information.&lt;/p&gt;

&lt;p&gt;For that reason, what Wright calls “documentation-by-FAQ” might not be the worst situation in the world, depending on how much content you’re working with. If you actually have someone tending the FAQ like a garden, your content will always change, but you can be sure of its accuracy.&lt;/p&gt;

&lt;p&gt;To convince your more skeptical peers of the value of maintaining your FAQ page or database, tell them that the FAQ is a content opportunity that may save them time. Think of how delightful it is when you get your “&lt;a href="https://slate.com/human-interest/dear-prudence"&gt;Dear Prudence&lt;/a&gt;” newsletter or a podcast notification for the latest &lt;a href="https://hanandmattknowitall.com/"&gt;&lt;cite&gt;Han and Matt Know It All&lt;/cite&gt;&lt;/a&gt;. Whenever you add a new question or update a new fact, spread the word among your users. These updates can help feed the social-media-marketing content beast while proving that you want to keep users informed and engaged.&lt;/p&gt;

&lt;h3&gt;FAQs for content consumers: give them power&lt;/h3&gt;

&lt;p&gt;Speaking of keeping users informed and engaged, a good FAQ can help the audience even more than it helps content authors. The best way to ensure that the FAQ works for the audience is to give them more control over the questions and answers they see.&lt;/p&gt;

&lt;p&gt;Most FAQs, including those on higher-ed sites, chunk up the FAQs by content category, tuck answers into accordions, and stop right there. More effective FAQs, though, provide other forms of interaction. Some allow users to refine information through filters, searches, and tags so the user isn’t stuck opening and closing accordion windows.&lt;/p&gt;

&lt;p&gt;For example, the website for &lt;a href="https://undergrad.admissions.columbia.edu/ask/faq/topic/405"&gt;Columbia Undergraduate Admissions&lt;/a&gt; has a fairly standard format, but the FAQ answers are tagged, so users have another option for navigating through the information. Other higher-ed services, like the syndicated &lt;a href="https://framingham.financialaidtv.com/play/1561-eligibility/348-do-i-have-be-enrolled-full-time-receive-financial-aid"&gt;financial aid web channel FATV&lt;/a&gt;, answer common FAQs with videos. Changing up the format and providing text, video, and audio options help prospective students feel like they are receiving more personal attention.&lt;/p&gt;

&lt;p&gt;Beyond higher-ed FAQs, Amazon encourages users to vote FAQs up and down, Reddit-style, which can lead to fun interactions and enables the users to rate the quality—or humor—of the information they receive.&lt;/p&gt;

&lt;figure&gt;
&lt;img src="/d/faq-advice/amazon-echo-q-and-a-screenshot.jpg" alt="Amazon’s customer questions and answers feature, which includes the ability to search and vote on answers."&gt;
&lt;figcaption&gt;Amazon’s more interactive FAQ model, in which users can vote on answers and search for questions.&lt;/figcaption&gt;		
&lt;/figure&gt;

&lt;p&gt;You can also remind skeptics that FAQs aren’t always what they expect. The FAQ format has experienced a renaissance in the form of our newly beloved voice gadgets. Some content creators are even using their existing FAQs as the foundation for their Alexa skills. For example, &lt;a href="https://www.amazon.com/GeorgiaGov-Interactive-GTA-Ask/dp/B074XBQGTQ/"&gt;georgia.gov created an Alexa skill&lt;/a&gt; by transforming its “&lt;a href="https://georgia.gov/popular-topics"&gt;Popular Topics&lt;/a&gt;” FAQ database, working with Acquia to structure the Q&amp;amp;A format so Alexa can answer common questions from Georgia residents. When describing the project, &lt;a href="https://digitalservices.georgia.gov/blog/2017-10-24/write-alexa-%E2%80%94-even-if-you-just-have-website"&gt;user experience designer Rachel Hart writes&lt;/a&gt;:&lt;/p&gt;

&lt;figure class="quote"&gt;
&lt;blockquote&gt;&lt;p&gt;If you say “No” to an FAQ question, Alexa skips to the next FAQ, and the next, until you say something sounds helpful or Alexa runs out of questions.&lt;/p&gt;
&lt;p style="margin-bottom: 0;"&gt;When the user chooses what they want to hear, they need to know exactly what they’re committing to. We need to make sure that our [labeling]—for both titles and FAQs—is clear.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/figure&gt;

&lt;p&gt;Read that again, dear FAQ fanatic. The complications for Alexa skills arise in the labeling, not in the FAQ itself. In fact, it’s the FAQ content that makes Alexa skills like the one for georgia.gov possible.&lt;/p&gt;

&lt;h2&gt;So I can make peace with my quirky love of the FAQ?&lt;/h2&gt;

&lt;p&gt;Indeed. Let your FAQ flag fly. FAQs—or dialogues that convey information—will always exist in some way, shape, or form. As for the accordion, though, the jury is out.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/_MuICA3Ji38" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Content Strategy, Writing
]]></dc:subject>
      <dc:date>2018-10-11T14:00:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/the-faq-as-advice-column</feedburner:origLink></item><item>
      <title><![CDATA[The Psychology of Design]]></title>
      <author>by <a itemprop="url" class="author" rel="author" href="/author/jonyablonski">Jon Yablonski</a></author>
      <link>http://feedproxy.google.com/~r/alistapart/main/~3/PapqWWEGLro/psychology-of-design</link>
      <guid isPermaLink="false">http://alistapart.com/article/psychology-of-design</guid>
      <description>&lt;p&gt;There are a number of debates about which additional skills designers should learn. Should designers code, write, or understand business? These skills are incredibly valuable but perhaps not essential. However, I would argue that every designer should learn the fundamentals of psychology. As humans, we have an underlying “blueprint” for how we perceive and process the world around us, and the study of psychology helps us define this blueprint. As designers, we can leverage psychology to build more intuitive, human-centered products and experiences. Instead of forcing users to conform to the design of a product or experience, we can use some key principles from psychology as a guide for designing how people actually are.&lt;/p&gt;

&lt;p&gt;But knowing where to start can be a challenge. Which principles from psychology are useful? What are some examples of these principles at work? In this article, I’ll cover the basics, and discuss the ethical implications of using psychology in design.&lt;/p&gt;

&lt;h2&gt;Key principles&lt;/h2&gt;

&lt;p&gt;The intersection of psychology and design is extensive. There’s an endless list of principles that occupy this space, but there are a few that I’ve found more ubiquitous than others. Let’s take a look at what these are and where they are effectively leveraged by products and experiences we interact with everyday.&lt;/p&gt;

&lt;h3&gt;Hick’s Law&lt;/h3&gt;

&lt;p&gt;One of the primary functions we have as designers is to synthesize information and present it in a way that it doesn’t overwhelm users—after all, &lt;a href="https://alistapart.com/article/cult-of-the-complex"&gt;good communication strives for clarity&lt;/a&gt;. This directly relates to our first key principle: Hick’s Law. Hick’s Law predicts that &lt;em&gt;the time it takes to make a decision increases with the number and complexity of choices available&lt;/em&gt;. It was formulated by psychologists William Edmund Hick and Ray Hyman in 1952 after examining the relationship between the number of stimuli present and an individual’s reaction time to any given stimulus.&lt;/p&gt;

&lt;p&gt;It turns out there is an actual formula to represent this relationship: &lt;i&gt;&lt;var&gt;RT&lt;/var&gt; = &lt;var&gt;a&lt;/var&gt; + &lt;var&gt;b&lt;/var&gt; log2 (&lt;var&gt;n&lt;/var&gt;)&lt;/i&gt;. Fortunately, we don’t need to understand the math behind this formula to grasp what it means. The concept is quite simple: the time it takes for users to respond directly correlates to the number and complexity of options available. It implies that complex interfaces result in longer processing time for users, which is important because it’s related to a fundamental theory in psychology known as cognitive load.&lt;/p&gt;

&lt;h4&gt;Cognitive load&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Cognitive load&lt;/em&gt; refers to the mental processing power being used by our working memory. Our brains are similar to computer processors in that we have limited processing power: when the amount of information coming in exceeds the space available, cognitive load is incurred. Our performance suffers and tasks become more difficult, which results in missed details and even frustration.&lt;/p&gt;

&lt;h4&gt;Examples&lt;/h4&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/remotes@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/remotes.jpg" alt="Three photos of television remotes where the majority of buttons have been covered, leaving only holes for the channel, volume, and number buttons."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Modified TV remotes that simplify the “interface” for grandparents.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;There are examples of Hick’s Law in action everywhere, but we’ll start with a common one: remote controls. As features available in TVs increased over the decades, so did the options available on their corresponding remotes. Eventually we ended up with remotes so complex that using them required either muscle memory from repeated use or a significant amount of mental processing. This led to the phenomenon known as “grandparent-friendly remote.” By taping off everything except for the essential buttons, grandkids were able to improve the usability of remotes for their loved ones, and they also did us all the favor of sharing them online.&lt;/p&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/apple-remote@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/apple-remote.jpg" alt="A photo of the Apple TV remote, which has a gesture-friendly touch pad and only six buttons."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Apple TV remote, which simplifies the controls to only those absolutely necessary.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;In contrast, we have smart TV remotes: the streamlined cousin of the previous example, simplifying the controls to only those absolutely necessary. The result is a remote that doesn’t require a substantial amount of working memory and therefore incurs much less cognitive load. By transferring complexity to the TV interface itself, information can be effectively organized and progressively disclosed within menus.&lt;/p&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/slack@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/slack.jpg" alt="Screenshots of Slack's onboarding experience where users learn the system by chatting with Slackbot before being introduced to the rest of the UI."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Screenshots from Slack’s progressive onboarding experience.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;Let’s take a look at another example of Hick’s Law. Onboarding is a crucial but risky process for new users, and few nail it as well as Slack. Instead of dropping users into a fully featured app after enduring a few onboarding slides, they use a bot (Slackbot) to engage users and prompt them to learn the messaging feature consequence-free. To prevent new users from feeling overwhelmed, Slack hides all features except for the messaging input. Once users have learned how to message via Slackbot, they are progressively introduced to additional features.&lt;/p&gt;

&lt;p&gt;This is a more effective way to onboard users because it mimics the way we actually learn: we build upon each subsequent step, and add to what we already know. By revealing features at just the right time, we enable our users to adapt to complex workflows and feature sets without feeling overwhelmed.&lt;/p&gt;

&lt;h4&gt;Key takeaways&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Too many choices will increase the cognitive load for users.&lt;/li&gt;
&lt;li&gt;Break up long or complex processes into screens with fewer options.&lt;/li&gt;
&lt;li&gt;Use progressive onboarding to minimize cognitive load for new users.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Miller’s Law&lt;/h3&gt;

&lt;p&gt;Another key principle is Miller’s Law, which predicts that &lt;em&gt;the average person can only keep 7 (± 2) items in their working memory&lt;/em&gt;. It originates from a paper published in 1956 by cognitive psychologist George Miller, who discussed the limits of short-term memory and memory span. Unfortunately there has been a lot of misinterpretation regarding this heuristic over the years, and it’s led to the “&lt;a href="https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two"&gt;magical number seven&lt;/a&gt;” being used to justify unnecessary limitations (for example, limiting interface menus to no more than seven items).&lt;/p&gt;

&lt;h4&gt;Chunking&lt;/h4&gt;

&lt;p&gt;Miller’s fascination with short-term memory and memory span centered not on the number seven, but on the concept of “chunking” and our ability to memorize information accordingly. When applied to design, chunking can be an incredibly valuable tool. Chunking describes the act of visually grouping related information into small, distinct units of information. When we chunk content in design, we are effectively making it easier to process and understand. Users can scan the content and quickly identify what they are interested in, which is aligned with how we tend to consume digital content.&lt;/p&gt;

&lt;h4&gt;Examples&lt;/h4&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/chunking-1@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/chunking-1.jpg" alt="Two example numbers side by side, one a single unbroken string of ten digits, the other with parentheses around the first three digits, and a dash after the second three digits (resembling a phone number much like Jenny's from Tommy Tutone's classic song)."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;An example of chunking with strings like phone numbers.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;The simplest example of chunking can be found with how we format phone numbers. Without chunking, a phone number would be a long string of digits, which increases the difficulty to process and remember it. Alternatively, a phone number that has been formatted (chunked) becomes much easier to interpret and memorize. This is similar to how we perceive a “wall of text” in comparison to well-formatted content with appropriate headline treatments, line-length, and content length.&lt;/p&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/chunking-2@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/chunking-2@2x.jpg" alt="A screenshot of Bloomberg's homepage with visually grouped blocks outlined in blue to show how they have been chunked together."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Chunking can organize content to help users process, understand, and memorize easily. At right, I’ve highlighted how Bloomberg grouped information.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;Another example of chunking being used effectively in design is with layout. We can use this technique to help users understand underlying relationships and hierarchy by grouping content into distinctive modules. Especially in information-dense experiences, chunking can be leveraged to provide structure to the content. Not only is the result more visually pleasing, but it’s more scannable.&lt;/p&gt;

&lt;h4&gt;Key takeaways&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Don’t use the “magical number seven” to justify unnecessary design limitations.&lt;/li&gt;
&lt;li&gt;Organize content into smaller chunks to help users process, understand, and memorize easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Jakob’s Law&lt;/h3&gt;

&lt;p&gt;The last principle we’ll look at is Jakob’s Law (short for Jakob’s Law of Internet User Experience), which states that &lt;em&gt;users spend most of their time on other sites, and they prefer your site to work the same way as all the other sites they already know&lt;/em&gt;. In 2000, it was &lt;a href="https://www.nngroup.com/videos/jakobs-law-internet-ux/"&gt;put forth by usability expert Jakob Nielsen&lt;/a&gt;, who described the tendency for users to develop an expectation of design patterns based on their cumulative experience from other websites. This principle encourages designers to follow common design patterns in order to avoid confusing users, which can result in higher cognitive load.&lt;/p&gt;

&lt;h4&gt;Mental models&lt;/h4&gt;

&lt;p&gt;I know what you&amp;#8217;re thinking: if all websites followed the same design patterns, that would make for quite the boring web. The answer is yes, that is probably true. But there is something incredibly valuable to be found in familiarity for users, which leads us to another fundamental concept in psychology that is valuable for designers: mental models.&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;mental model&lt;/em&gt; is what we think we know about a system, especially about how it works. Whether it’s a website or a car, we form models of how a system works, and then we apply that model to new situations where the system is similar. In other words, we use knowledge we already have from past experiences when interacting with something new.&lt;/p&gt;

&lt;p&gt;Mental models are valuable for designers, because we can &lt;a href="https://alistapart.com/article/object-oriented-ux"&gt;match our user’s mental model to improve their experience&lt;/a&gt;. Consequently, users can easily transfer their knowledge from one product or experience to another without taking time to understand how the new system works. Good user experiences are made possible when the designer’s mental model is aligned with the user’s mental model. The task of shrinking the gap between our mental models and those of our users is one of our biggest challenges, and to achieve this we use a variety of methods: user interviews, personas, journey maps, empathy maps, and more. The point of all this is to gain a deeper insight into not only the goals and objectives of our users but also their pre-existing mental models, and how that applies to the product or experience we are designing.&lt;/p&gt;

&lt;h4&gt;Examples&lt;/h4&gt;

&lt;p&gt;Have you ever wondered why form controls look the way they do? It’s because the humans designing them had a mental model for what these elements should look like, which they based on control panels they were already familiar with in the physical world. Things like form toggles, radio inputs, and even buttons originated from the design of their tactile counterparts.&lt;/p&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/forms@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/forms.jpg" alt="Two images side by side: one showing buttons and radio inputs on a physical control panel and the other showing form inputs on the web."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Comparison between control panel elements and typical form elements.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;As designers, we must close the gap that exists between our mental models and that of our users. It’s important we do this because there will be problems when they aren’t aligned, which can affect how users perceive the products and experiences we’ve helped build. This misalignment is called &lt;em&gt;mental model discordance&lt;/em&gt;, and it occurs when a familiar product is suddenly changed. &lt;/p&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/snapchat@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/snapchat.jpg" alt="Screenshots from before and after Snapchat's redesign show a drastically different interface that confused many users."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Snapchat redesign before-and-after comparison.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;Take for example Snapchat, which rolled out a major redesign in early 2018. They launched a reformatted layout, which in turn confused users by making it difficult to access features they used on a daily basis. These unhappy users immediately took to Twitter and expressed their disapproval en masse. Even worse was the subsequent migration of users to Snapchat’s competitor, Instagram. Snapchat had failed to ensure the mental model of their users would be aligned with the redesigned version of their app, and the resulting discordance caused major backlash.&lt;/p&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/youtube@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/youtube.jpg" alt="By contrast to Snapchat, Google allowed users to explore and test YouTube's redesign ahead of time which lead to a more successful launch."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Before and after comparison of YouTube redesign in 2017.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;But major redesigns don’t always have to result in backlash—just ask Google. Google has a history of allowing users to opt in to redesigned versions of their products like Google Calendar, YouTube, and Gmail. When they launched the new version of YouTube in 2017 after years of essentially the same design, they allowed desktop users to ease into the new Material Design UI without having to commit. Users could preview the new design, gain some familiarity, submit feedback, and even revert to the old version if they preferred it. As a result, the inevitable mental model discordance was avoided by simply empowering users to switch when they were ready.&lt;/p&gt;

&lt;h4&gt;Key takeaways&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Users will transfer expectations they have built around one familiar product to another that appears similar.&lt;/li&gt;
&lt;li&gt;By leveraging existing mental models, we can create superior user experiences in which the user can focus on their task rather than learning new models.&lt;/li&gt;
&lt;li&gt;Minimize discordance by empowering users to continue using a familiar version for a limited time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Recap&lt;/h3&gt;

&lt;p&gt;You might be thinking, “These principles are great, but how do I use them in my projects?” While nothing will replace actual user research and data specific to our projects, we can use these psychological principles to serve as a guide for designing more intuitive, human-centered products and experiences. Being mindful of these principles helps us create designs that consider how people actually are, as opposed to forcing them to conform to the technology. To quickly recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hick’s Law can help guide us to reduce cognitive load for users by minimizing choice and breaking long or complex processes into screens with fewer options.&lt;/li&gt;
&lt;li&gt;Miller’s Law teaches us to use chunking to organize content into smaller clusters to help users process, understand, and memorize easily.&lt;/li&gt;
&lt;li&gt;Jakob’s Law reminds us that users will transfer expectations they have built around one familiar product to another that appears similar. Therefore, we can leverage existing mental models to create superior user experiences.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ve covered some key principles that are useful for building more intuitive, human-centered products and experiences. Now let’s touch on their ethical implications and how easy it can be to fall into the trap of exploiting users with psychology.&lt;/p&gt;

&lt;h2&gt;A note on ethics&lt;/h2&gt;

&lt;p&gt;On the one hand, designers can use psychology to create more intuitive products and experiences; on the other, they can use it to exploit how our minds work, for the sake of creating more addictive apps and websites. Let’s first take a look at why this is a problem, and then consider some potential solutions.&lt;/p&gt;

&lt;h3&gt;Problem&lt;/h3&gt;

&lt;p&gt;One doesn’t have to go far to see why the well-being of users being deprioritized in favor of profit is a problem. When was the last time you were on a subway, on a sidewalk, or in a car and didn’t see someone glued to their smartphone? There are some that would argue &lt;a href="https://humanetech.com/problem/"&gt;we’re in the middle of an epidemic&lt;/a&gt;, and that our attention is being held captive by the mini-computers that we carry with us everywhere.&lt;/p&gt;

&lt;p&gt;It wouldn’t be an exaggeration to say that the mobile platforms and social networks that connect us also put a lot of effort into how they can keep us glued, and they’re getting better at it every day. The effects of this addiction are beginning to become well-known: from sleep reduction and anxiety to deterioration of social relationships, it’s becoming apparent that the race for our attention has some unintended consequences. These effects become problematic when they start to change how we form relationships and how we view ourselves.&lt;/p&gt;

&lt;h3&gt;Solution&lt;/h3&gt;

&lt;p&gt;As designers, our responsibility is to create products and experiences that support and align with the goals and well-being of users. In other words, we should build technology for augmenting the human experience, not replacing it with virtual interaction and rewards. The first step in making ethical design decisions is to acknowledge how the human mind can be exploited. &lt;/p&gt;

&lt;p&gt;We must also question what we should and shouldn’t build. We can find ourselves on quite capable teams that have the ability to build almost anything you can imagine, but that doesn’t always mean we should—especially if the goals of what we are building don’t align with the goals of our users. &lt;/p&gt;

&lt;p&gt;Lastly, we must consider metrics beyond usage data. Data tells us lots of things, but what it doesn’t tell us is why users are behaving a certain way or how the product is impacting their lives. To gain insight into why, we must both listen and be receptive to our users. This means getting out from behind a screen, talking with them, and then using this qualitative research to inform how we evolve the design.&lt;/p&gt;

&lt;h3&gt;Examples&lt;/h3&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/google-wellbeing@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/google-wellbeing.jpg" alt="Google's Digital Wellbeing initiative website details how they're helping users spend less time staring at screens."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Google’s Digital Wellbeing initiative website.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;It’s been great to see companies taking the right steps when it comes to considering the digital well-being of users. Take for example Google, which just announced &lt;a href="https://wellbeing.google/"&gt;tools and features&lt;/a&gt; at their latest I/O event that focus on helping people better understand their tech usage, focus on what matters most, disconnect when needed, and create healthy digital habits. Features like an app dashboard that provides a usage overview, additional control over alerts and notifications, and Family Link for setting digital ground rules for the little ones all are geared towards protecting users.&lt;/p&gt;

&lt;figure&gt;
&lt;picture&gt;
&lt;source media="(min-width: 600px)" srcset="/d/psychology-of-design/facebook-news-feed@2x.jpg"&gt;
&lt;img src="/d/psychology-of-design/facebook-news-feed.jpg" alt="Facebook released a video detailing how they're defining new success criteria around meaningful connections."&gt;
&lt;/picture&gt;
&lt;p&gt;&lt;figcaption&gt;Screenshot from Facebook’s “News Feed FYI: Bringing People Closer Together” video.&lt;/figcaption&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;Some companies are even redefining their success metrics. Instead of time on site, companies like Facebook are &lt;a href="https://newsroom.fb.com/news/2018/01/news-feed-fyi-bringing-people-closer-together/"&gt;defining success through meaningful interactions&lt;/a&gt;. This required them to restructure their news feed algorithm to prioritize the content that people actually find valuable over the stuff we mindlessly consume. Content from friends and family now takes precedence, even if the result means users spend a little less time in their app.&lt;/p&gt;

&lt;p&gt;These examples are just a glimpse into the steps that many companies are taking, and I hope to see many more in the coming years. The technology we play a part in building can significantly impact people’s lives, and it’s crucial that we ensure that impact is positive. It’s our responsibility to create products and experiences that support and align with the goals and well-being of users. We can make ethical design decisions by acknowledging how the human mind can be exploited, consider what we should and shouldn’t build, and talk with users to gain qualitative feedback on how the products and experiences we build affect their lives.&lt;/p&gt;

&lt;h2&gt;Resources&lt;/h2&gt;

&lt;p&gt;There are tons of great resources we can reference for making our designs more intuitive for users. Here are a few I have referenced quite frequently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lawsofux.com/"&gt;&lt;cite&gt;Laws of UX&lt;/cite&gt;&lt;/a&gt;: A website I created for designers to learn more about psychological principles that relate to UX/UI design.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cognitiveuxd.com/"&gt;&lt;cite&gt;Cognitive UXD&lt;/cite&gt;&lt;/a&gt;: This hand-selected publication curated by Norbi Gaal is a great resource for anyone interested in the intersection of psychology and UX.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://humanetech.com/"&gt;Center for Humane Technology&lt;/a&gt;: A world-class team of former tech 
insiders and CEOs who are advancing thoughtful solutions to change the culture, business incentives, design techniques, and organizational 
structures driving how technology hijacks our brains.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/The_Design_of_Everyday_Things"&gt;&lt;cite&gt;The Design of Everyday Things: Revised and Expanded Edition&lt;/cite&gt;&lt;/a&gt;: An absolute classic that explores the communication between object and user through design, how to optimize this communication, and ultimately how psychology plays a part in designing for how humans actually are.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://abookapart.com/products/designing-for-emotion"&gt;&lt;cite&gt;Designing for Emotion&lt;/cite&gt;&lt;/a&gt;: A look at the importance of emotion when expressing a brand’s personality, and how designers can go beyond functionality, reliability, and usability to design for humans as opposed to machines.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nirandfar.com/hooked"&gt;&lt;cite&gt;Hooked: How to Build Habit-Forming Products&lt;/cite&gt;&lt;/a&gt;: A guide that provides insight into the behavioral techniques used by companies like Twitter, Instagram, and Pinterest.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/alistapart/main/~4/PapqWWEGLro" height="1" width="1" alt=""/&gt;</description>
      <dc:subject><![CDATA[Design, User Experience
]]></dc:subject>
      <dc:date>2018-10-05T13:59:00+00:00</dc:date>
    <feedburner:origLink>http://alistapart.com/article/psychology-of-design</feedburner:origLink></item>

    </channel>
</rss>
