This feed does not validate.

In addition, interoperability with the widest range of feed readers could be improved by implementing the following recommendations.


  1. <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
  2. <rss version="2.0" xmlns:content="">
  3.  <channel>
  4.    <title>Articles on Smashing Magazine — For Web Designers And Developers</title>
  5.    <link></link>
  6.    <description>Recent content in Articles on Smashing Magazine — For Web Designers And Developers</description>
  7.    <generator>Hugo --</generator>
  8.    <language>en-us</language>
  9.    <lastBuildDate>Fri, 20 Apr 2018 15:32:23 +0000</lastBuildDate>
  11.      <item>
  14.          <author>Suzanna Scacca</author>
  16.        <title>What You Need To Know To Increase Mobile Checkout Conversions</title>
  17.        <link></link>
  18.        <pubDate>Fri, 20 Apr 2018 13:35:58 +0200</pubDate>
  19.        <guid></guid>
  20.        <description>Google’s mobile-first indexing is here. Well, for some websites anyway. For the rest of us, it will be here soon enough, and our websites need to be in tip-top shape if we don’t want search rankings to be adversely affected by the change.
  21. That said, responsive web design is nothing new. We’ve been creating custom mobile user experiences for years now, so most of our websites should be well poised to take this on… right?</description>
  22.        <content:encoded><![CDATA[
  23.          <html>
  24.            <head>
  25.              <meta charset="utf-8">
  26.              <link rel="canonical" href="" />
  27.              <title>What You Need To Know To Increase Mobile Checkout Conversions</title>
  28.            </head>
  29.            <body>
  30.              <article>
  31.                <header>
  32.                  <h1>What You Need To Know To Increase Mobile Checkout Conversions</h1>
  35.                    <address>Suzanna Scacca</address>
  37.                  <time datetime="2018-04-20T13:35:58&#43;02:00" class="op-published">2018-04-20T13:35:58+02:00</time>
  38.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  39.                </header>
  40.                <p><a href="">Google’s mobile-first indexing</a> is here. Well, for some websites anyway. For the rest of us, it will be here soon enough, and our websites need to be in tip-top shape if we don’t want search rankings to be adversely affected by the change.</p>
  42. <p>That said, responsive web design is nothing new. We’ve been creating custom mobile user experiences for years now, so most of our websites should be well poised to take this on… right?</p>
  44. <p>Here’s the problem: Research shows that the dominant device through which users access the web, <em>on average</em>, is the smartphone. Granted, this might not be the case for every website, but the data indicates that this is the direction we’re headed in, and so every web designer should be prepared for it.</p>
  46. <p>However, mobile checkout conversions are, to put it bluntly, not good. There are a number of reasons for this, but that doesn’t mean that m-commerce designers should take this lying down.</p>
  48. <p>As more mobile users rely on their smart devices to access the web, websites need to be more adeptly designed to give them the simplified, convenient and secure checkout experience they want. In the following roundup, I’m going to explore some of the impediments to conversion in the mobile checkout and focus on what web designers can do to improve the experience.</p>
  52.  <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  53.    <div class="container product-panel--book__container">
  54.      <div class="panel__description panel__description--book">
  55.    <p>Getting the process <em>just</em> right ain't an easy task. That's why we've set up <strong>'this-is-how-I-work'-sessions</strong> — with smart cookies sharing what works really well for them. A part of the <a href="">Smashing Membership</a>, of course.</p>
  56.      <a href="" class="btn btn--green btn--large">
  57.        Explore features&nbsp;→
  58.      </a>
  59.      </div>
  60.      <div class="panel__image panel__image--book">
  61.        <a href="" class="books__book__image">
  62.        <div class="books__book__img">
  63.          <img src="" alt="Smashing TV, with live sessions for professional designers and developers." width="310" height="400">
  64.        </div>
  65.      </a>
  66.      </div>
  67.    </div>
  68.  </aside>
  74. <div class="c-garfield-the-cat">
  77. <h3>Why Are Mobile Checkout Conversions Lagging?</h3>
  79. <p>According to the data, prioritizing the mobile experience in our web design strategies is a smart move for everyone involved. With people spending roughly <a href="">51% of their time with digital media</a> through mobile devices (as opposed to only 42% on desktop), search engines and websites really do need to align with user trends.</p>
  81. <p>Now, while that statistic paints a positive picture in support of designing websites with a mobile-first approach, other statistics are floating around that might make you wary of it. Here’s why I say that: <a href="">Monetate’s e-commerce quarterly report</a> issued for Q1 2017 had some really interesting data to show.</p>
  83. <p>In this first table, they break down the percentage of visitors to e-commerce websites using different devices between Q1 2016 and Q1 2017. As you can see, smartphone Internet access has indeed surpassed desktop:</p>
  85. <p><table class="tablesaw break-out" data-tablesaw-mode="swipe" data-tablesaw-minimap>
  86.    <thead>
  87.        <tr>
  88.            <th data-tablesaw-priority="persist">Website Visits by Device</th>
  89.            <th>Q1 2016</th>
  90.            <th>Q2 2016</th>
  91.            <th>Q3 2016</th>
  92.            <th>Q4 2016</th>
  93.            <th>Q1 2017</th>
  94.        </tr>
  95.    </thead>
  96.    <tbody>
  97.        <tr>
  98.            <td>Traditional</td>
  99.            <td>49.30%</td>
  100.            <td>47.50%</td>
  101.            <td>44.28%</td>
  102.            <td>42.83%</td>
  103.            <td>42.83%</td>
  104.        </tr>
  105.        <tr>
  106.            <td>Smartphone</td>
  107.            <td>36.46%</td>
  108.            <td>39.00%</td>
  109.            <td>43.07%</td>
  110.            <td>44.89%</td>
  111.            <td>44.89%</td>
  112.        </tr>
  113.        <tr>
  114.            <td>Other</td>
  115.            <td>0.62%</td>
  116.            <td>0.39%</td>
  117.            <td>0.46%</td>
  118.            <td>0.36%</td>
  119.            <td>0.36%</td>
  120.        </tr>
  121.        <tr>
  122.            <td>Tablet</td>
  123.            <td>13.62%</td>
  124.            <td>13.11%</td>
  125.            <td>12.19%</td>
  126.            <td>11.91%</td>
  127.            <td>11.91%</td>
  128.        </tr>
  129.    </tbody>
  130. </table>
  131. <p><em>Monetate’s findings on which devices are used to access in the Internet. (<a href="">Source</a>)</em></p></p>
  133. <p>In this next data set, we can see that the average conversion rate for e-commerce websites isn’t great. In fact, the number has gone down significantly since the first quarter of 2016.</p>
  135. <p><table class="tablesaw break-out" data-tablesaw-mode="swipe" data-tablesaw-minimap>
  136.    <thead>
  137.        <tr>
  138.            <th data-tablesaw-priority="persist">Conversion Rates</th>
  139.            <th>Q1 2016</th>
  140.            <th>Q2 2016</th>
  141.            <th>Q3 2016</th>
  142.            <th>Q4 2016</th>
  143.            <th>Q1 2017</th>
  144.        </tr>
  145.    </thead>
  146.    <tbody>
  147.        <tr>
  148.            <td>Global</td>
  149.            <td>3.10%</td>
  150.            <td>2.81%</td>
  151.            <td>2.52%</td>
  152.            <td>2.94%</td>
  153.            <td>2.48%</td>
  154.        </tr>
  155.    </tbody>
  156. </table>
  157. <p><em>Monetate’s findings on overall e-commerce global conversion rates (for all devices).  (<a href="">Source</a>)</em></figcaption></p>
  159. <p>Even more shocking is the split between device conversion rates:</p>
  161. <p><table class="tablesaw break-out" data-tablesaw-mode="swipe" data-tablesaw-minimap>
  162.    <thead>
  163.        <tr>
  164.            <th data-tablesaw-priority="persist">Conversion Rates by Device</th>
  165.            <th>Q1 2016</th>
  166.            <th>Q2 2016</th>
  167.            <th>Q3 2016</th>
  168.            <th>Q4 2016</th>
  169.            <th>Q1 2017</th>
  170.        </tr>
  171.    </thead>
  172.    <tbody>
  173.        <tr>
  174.            <td>Traditional</td>
  175.            <td>4.23%</td>
  176.            <td>3.88%</td>
  177.            <td>3.66%</td>
  178.            <td>4.25%</td>
  179.            <td>3.63%</td>
  180.        </tr>
  181.        <tr>
  182.            <td>Tablet</td>
  183.            <td>1.42%</td>
  184.            <td>1.31%</td>
  185.            <td>1.17%</td>
  186.            <td>1.49%</td>
  187.            <td>1.25%</td>
  188.        </tr>
  189.        <tr>
  190.            <td>Other</td>
  191.            <td>0.69%</td>
  192.            <td>0.35%</td>
  193.            <td>0.50%</td>
  194.            <td>0.35%</td>
  195.            <td>0.27%</td>
  196.        </tr>
  197.        <tr>
  198.            <td>Smartphone</td>
  199.            <td>3.59%</td>
  200.            <td>3.44%</td>
  201.            <td>3.21%</td>
  202.            <td>3.79%</td>
  203.            <td>3.14%</td>
  204.        </tr>
  205.    </tbody>
  206. </table>
  207. <p><em>Monetate’s findings on the average conversion rates, broken down by device. (<a href="">Source</a>)</em></p></p>
  209. <p>Smartphones consistently receive fewer conversions than desktop, despite being the predominant device through which users access the web.</p>
  211. <p>What’s the problem here? Why are we able to get people to mobile websites, but we lose them at checkout?</p>
  213. <p>In its report from 2017 named “<a href="">Mobile’s Hierarchy of Needs</a>,” comScore breaks down the top five reasons why mobile checkout conversion rates are so low:</p>
  225. <figure >
  226. <img
  227. srcset=",q_auto/w_400/ 400w,
  228.,q_auto/w_800/ 800w,
  229.,q_auto/w_1200/ 1200w,
  230.,q_auto/w_1600/ 1600w,
  231.,q_auto/w_2000/ 2000w"
  232. src=",q_auto/w_400/"
  233. sizes="100vw"
  234. alt="Reasons why m-commerce doesn’t convert"
  235. />
  237. <figcaption class="op-vertical-bottom">
  238. The most common reasons why m-commerce shoppers don’t convert. (Image: <a href=''>comScore</a>) (<a href=''>View large version</a>)
  239. </figcaption>
  240. </figure>
  243. <p>Here is the breakdown for why mobile users don’t convert:</p>
  245. <ul>
  246. <li>20.2% &mdash; security concerns</li>
  247. <li>19.6% &mdash; unclear product details</li>
  248. <li>19.6% &mdash; inability to open multiple browser tabs to compare</li>
  249. <li>19.3% &mdash; difficulty navigating</li>
  250. <li>18.6% &mdash; difficulty inputting information.</li>
  251. </ul>
  253. <p>Those are plausible reasons to move from the smartphone to the desktop to complete a purchase (if they haven’t been completely turned off by the experience by that point, that is).</p>
  255. <p>In sum, we know that consumers want to access the web through their mobile devices. We also know that barriers to conversion are keeping them from staying put. So, how do we deal with this?</p>
  257. <h3>10 Ways to Increase Mobile Checkout Conversions In 2018</h3>
  259. <p>For most of the websites you’ve designed, you’re not likely to see much of a change in search ranking when Google’s mobile-first indexing becomes official.</p>
  261. <p>Your mobile-friendly designs might be “good enough” to keep your websites at the top of search (to start, anyway), but what happens if visitors don’t stick around to convert? Will Google start penalizing you because your website can’t seal the deal with the majority of visitors? In all honesty, that scenario will only occur in extreme cases, where the mobile checkout is so poorly constructed that bounce rates skyrocket and people stop wanting to visit the website at all.</p>
  263. <p>Let’s say that the drop-off in traffic at checkout doesn’t incur penalties from Google. That’s great… for SEO purposes. But what about for business? Your goal is to get visitors to convert without distraction and without friction. Yet, that seems to be what mobile visitors get.</p>
  265. <p>Going forward, your goal needs to be two-fold:</p>
  267. <ul>
  268. <li>to design websites with Google’s mobile-first mission and guidelines in mind,</li>
  269. <li>to keep mobile users on the website until they complete a purchase.</li>
  270. </ul>
  272. <p>Essentially, this means decreasing the amount of work users have to do and improving the visibility of your security measures. Here is what you can do to more effectively design mobile checkouts for conversions.</p>
  274. <h4>1. Keep the Essentials in the Thumb Zone</h4>
  276. <p>Research on <a href="">how users hold their mobile phones</a> is old hat by now. We know that, whether they use the single- or double-handed approach, certain parts of the mobile screen are just inconvenient for mobile users to reach. And when expediency is expected during checkout, this is something you don’t want to mess around with.</p>
  278. <p>For single-handed users, the middle of the screen is the prime playing field:</p>
  290. <figure >
  291. <img
  292. srcset=",q_auto/w_400/ 400w,
  293.,q_auto/w_800/ 800w,
  294.,q_auto/w_1200/ 1200w,
  295.,q_auto/w_1600/ 1600w,
  296.,q_auto/w_2000/ 2000w"
  297. src=",q_auto/w_400/"
  298. sizes="100vw"
  299. alt="The thumb zone for single-handed mobile"
  300. />
  302. <figcaption class="op-vertical-bottom">
  303. The good, OK and bad areas for single-handed mobile users. (Image: <a href=''>UX Matters</a>) (<a href=''>View large version</a>)
  304. </figcaption>
  305. </figure>
  308. <p>Although users who cradle their phones for greater stability have a couple options for which fingers to use to interact with the screen, only 28% use their index finger. So, let’s focus on the capabilities of thumb users, which, again, means giving the central part of the screen the most prominence:</p>
  320. <figure >
  321. <img
  322. srcset=",q_auto/w_400/ 400w,
  323.,q_auto/w_800/ 800w,
  324.,q_auto/w_1200/ 1200w,
  325.,q_auto/w_1600/ 1600w,
  326.,q_auto/w_2000/ 2000w"
  327. src=",q_auto/w_400/"
  328. sizes="100vw"
  329. alt="The thumb and index finger zone for mobile cradling"
  330. />
  332. <figcaption class="op-vertical-bottom">
  333. The good, OK and bad areas for mobile users that cradle their phones. (Image: <a href=''>UX Matters</a>) (<a href=''>View large version</a>)
  334. </figcaption>
  335. </figure>
  338. <p>Some users hold their phones with two hands. Because the horizontal orientation is more likely to be used for video, this won’t be relevant for mobile checkout. So, pay attention to how much space of that screen is feasibly within reach of the user’s thumb:</p>
  350. <figure >
  351. <img
  352. srcset=",q_auto/w_400/ 400w,
  353.,q_auto/w_800/ 800w,
  354.,q_auto/w_1200/ 1200w,
  355.,q_auto/w_1600/ 1600w,
  356.,q_auto/w_2000/ 2000w"
  357. src=",q_auto/w_400/"
  358. sizes="100vw"
  359. alt="The thumb zone for vertical and horizontal"
  360. />
  362. <figcaption class="op-vertical-bottom">
  363. The good, OK and bad areas for two-handed mobile users. (Image: <a href=''>UX Matters</a>) (<a href=''>View large version</a>)
  364. </figcaption>
  365. </figure>
  368. <p>In sum, we can use <a href="">Smashing Magazine’s breakdown</a> of where to focus content, regardless of left-hand, right-hand or two-handed holding of a smartphone:</p>
  380. <figure >
  381. <img
  382. srcset=",q_auto/w_400/ 400w,
  383.,q_auto/w_800/ 800w,
  384.,q_auto/w_1200/ 1200w,
  385.,q_auto/w_1600/ 1600w,
  386.,q_auto/w_2000/ 2000w"
  387. src=",q_auto/w_400/"
  388. sizes="100vw"
  389. alt="Where the ideal thumb zone is on mobile"
  390. />
  392. <figcaption class="op-vertical-bottom">
  393. A summary of where the good, OK and bad zones are on mobile devices. (Image: <a href=''>Smashing Magazine</a>) (<a href=''>View large version</a>)
  394. </figcaption>
  395. </figure>
  398. <p><a href="">JCPenney’s website</a> is a good example of how to do this:</p>
  410. <figure >
  411. <img
  412. srcset=",q_auto/w_400/ 400w,
  413.,q_auto/w_800/ 800w,
  414.,q_auto/w_1200/ 1200w,
  415.,q_auto/w_1600/ 1600w,
  416.,q_auto/w_2000/ 2000w"
  417. src=",q_auto/w_400/"
  418. sizes="100vw"
  419. alt="JCPenney’s form is in the thumb zone"
  420. />
  422. <figcaption class="op-vertical-bottom">
  423. JCPenney’s contact form starts midway down the page. (Image: <a href=''>JCPenney</a>) (<a href=''>View large version</a>)
  424. </figcaption>
  425. </figure>
  428. <p>While information is included at the top of the checkout page, the input fields don’t start until just below the middle of it &mdash; directly in the ideal thumb zone for users of any type. This ensures that visitors holding their phones in any manner and using different fingers to engage with it will have no issue reaching the form fields.</p>
  430. <h4>2. Minimize Content to Maximize Speed</h4>
  432. <p>We’ve been taught over and over again that minimal design is best for websites. This is especially true in mobile checkout, where an already slow or frustrating experience could easily push a customer over the edge, when all they want to do is be done with the purchase.</p>
  435.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  439. <p>To maximize speed during the mobile checkout process, keep the following tips in mind:</p>
  441. <ul>
  442. <li>Only add the essentials to checkout. This is not the time to try to upsell or cross-sell, promote social media or otherwise distract from the action at hand.</li>
  443. <li>Keep the checkout free of all images. The only eye-catching visuals that are really acceptable are trustmarks and calls to action (more on these below).</li>
  444. <li>Any text included on the page should be instructional or descriptive in nature.</li>
  445. <li>Avoid any special stylization of fonts. The less “wow” your checkout page has, the easier it will be for users to get through the process.</li>
  446. </ul>
  448. <p>Look to <a href="">Staples</a>’ website as an example of what a highly simple single-page checkout should look like:</p>
  460. <figure >
  461. <img
  462. srcset=",q_auto/w_400/ 400w,
  463.,q_auto/w_800/ 800w,
  464.,q_auto/w_1200/ 1200w,
  465.,q_auto/w_1600/ 1600w,
  466.,q_auto/w_2000/ 2000w"
  467. src=",q_auto/w_400/"
  468. sizes="100vw"
  469. alt="The single-page checkout for Staples"
  470. />
  472. <figcaption class="op-vertical-bottom">
  473. Staples has a single-page checkout with a minimal number of fields to fill out. (Image: <a href=''>Staples</a>) (<a href=''>View large version</a>)
  474. </figcaption>
  475. </figure>
  478. <p>As you can see, Staples doesn’t bog down the checkout process with product images, branding, navigation, internal links or anything else that might (1) distract from the task at hand, or (2) suck resources from the server while it attempts to process your customers’ requests.</p>
  480. <p>Not only will this checkout page be easy to get through, but it will load quickly and without issue every time &mdash; something customers will remember the next time they need to make a purchase. By keeping your checkout pages light in design, you ensure a speedy experience in all aspects.</p>
  482. <h4>3. Put Them at Ease With Trustmarks</h4>
  484. <p>A trustmark is any indicator on a website that lets customers know, “Hey, there’s absolutely nothing to worry about here. We’re keeping your information safe!”</p>
  486. <p>The one trustmark that every m-commerce website should have? An SSL certificate. Without one, the address bar will not display the lock sign or the green <code>https</code> domain name &mdash; both of which let customers know that the website has extra encryption.</p>
  488. <p>You can use other trustmarks at checkout as well.</p>
  500. <figure >
  501. <img
  502. srcset=",q_auto/w_400/ 400w,
  503.,q_auto/w_800/ 800w,
  504.,q_auto/w_1200/ 1200w,
  505.,q_auto/w_1600/ 1600w,
  506.,q_auto/w_2000/ 2000w"
  507. src=",q_auto/w_400/"
  508. sizes="100vw"
  509. alt="Big Chill uses a RapidSSL trust seal"
  510. />
  512. <figcaption class="op-vertical-bottom">
  513. Big Chill includes a RapidSSL trust seal to let customers know its data is encrypted. (Image: <a href=''>Big Chill</a>) (<a href=''>View large version</a>)
  514. </figcaption>
  515. </figure>
  518. <p>While you can use logos from <a href="">Norton Security</a>, <a href="">PCI compliance</a> and other security software to let customers know your website is protected, users might also be swayed by recognizable and well-trusted names. When you think about it, this isn’t much different than displaying corporate logos beside customer testimonials or in callouts that boast of your big-name connections. If you can leverage a partnership like the ones mentioned below, you can use the inherent trust there to your benefit.</p>
  520. <p>Take <a href="">6pm</a>, which uses a “Login with Amazon” option at checkout:</p>
  532. <figure >
  533. <img
  534. srcset=",q_auto/w_400/ 400w,
  535.,q_auto/w_800/ 800w,
  536.,q_auto/w_1200/ 1200w,
  537.,q_auto/w_1600/ 1600w,
  538.,q_auto/w_2000/ 2000w"
  539. src=",q_auto/w_400/"
  540. sizes="100vw"
  541. alt="6pm uses an Amazon trustmark"
  542. />
  544. <figcaption class="op-vertical-bottom">
  545. 6pm leverages the Amazon name as a trustmark. (Image: <a href=''>6pm</a>) (<a href=''>View large version</a>)
  546. </figcaption>
  547. </figure>
  550. <p>This is a smart move for a brand that most definitely does not have the brand-name recognition that a company like Amazon has. By giving customers a convenient option to log in with a brand that’s synonymous with speed, reliability and trust, the company might now become known for those same checkout qualities that Amazon is celebrated for.</p>
  552. <p>Then, there are mobile checkout pages like the one on <a href="">Sephora</a>:</p>
  564. <figure >
  565. <img
  566. srcset=",q_auto/w_400/ 400w,
  567.,q_auto/w_800/ 800w,
  568.,q_auto/w_1200/ 1200w,
  569.,q_auto/w_1600/ 1600w,
  570.,q_auto/w_2000/ 2000w"
  571. src=",q_auto/w_400/"
  572. sizes="100vw"
  573. alt="Sephora’s PayPal trustmark"
  574. />
  576. <figcaption class="op-vertical-bottom">
  577. Sephora uses a trusted payment gateway provider as a trustmark. (Image: <a href=''>Sephora</a>) (<a href=''>View large version</a>)
  578. </figcaption>
  579. </figure>
  582. <p>Sephora also uses this technique of leveraging another brand’s good name in order to build trust at checkout time. In this case, however, it presents customers with two clear options: Check out with us right now, or hop over to PayPal, which will take care of you securely. With security being a major concern that keeps mobile customers from converting, this kind of trustmark and payment method is a good move on Sephora’s part.</p>
  584. <h4>4. Provide Easier Editing</h4>
  586. <p>In general, never take a visitor (on any device) away from whatever they’re doing on your website. There are already enough distractions online; the last thing they need is for <em>you</em> to point them in a direction that keeps them from converting.</p>
  588. <p>At checkout, however, your customers might feel compelled to do this very thing if they decide they want a different color, size or quantity of an item in their shopping cart. Rather than let them backtrack through the website, give them an in-checkout editing option to keep them in place.</p>
  590. <p><a href="">Victoria’s Secret</a> does this well:</p>
  602. <figure >
  603. <img
  604. srcset=",q_auto/w_400/ 400w,
  605.,q_auto/w_800/ 800w,
  606.,q_auto/w_1200/ 1200w,
  607.,q_auto/w_1600/ 1600w,
  608.,q_auto/w_2000/ 2000w"
  609. src=",q_auto/w_400/"
  610. sizes="100vw"
  611. alt="Victoria’s Secret edit lightbox in checkout"
  612. />
  614. <figcaption class="op-vertical-bottom">
  615. Victoria’s Secret doesn’t force users away from checkout to edit items. (Image: <a href=''>Victoria’s Secret</a>) (<a href=''>View large version</a>)
  616. </figcaption>
  617. </figure>
  620. <p>When they first get to the checkout screen, customers will see a list of items they’re about to purchase. When the large “Edit” button beside each item is clicked, a lightbox (shown above) opens with the product’s variations. It’s basically the original product page, just superimposed on top of the checkout. Users can adjust their options and save their changes without ever having to leave the checkout page.</p>
  622. <p>If you find, in reviewing your website’s analytics, that users occasionally backtrack after hitting the checkout (you can see this in the sales funnel), add this built-in editing feature. By preventing this unnecessary movement backwards, you could save yourself lost conversions from confused or distracted customers.</p>
  624. <h4>5. Enable Express Checkout Options</h4>
  626. <p>When consumers check out on an e-commerce website through a desktop device, it probably isn’t a big deal if they have to input their user name, email address or payment information each time. Sure, if it can be avoided, they’ll find ways around it (like allowing the website to save their information or using a password manager such as LastPass).</p>
  628. <p>But on mobile, re-entering that information is a pain, especially if contact forms aren’t optimized well (more on that below). So, to ease the log-in and checkout process for mobile users, consider ways in which you can simplify the process:</p>
  630. <ul>
  631. <li>Allow for guest checkout.</li>
  632. <li>Allow for one-click expedited checkout.</li>
  633. <li>Enable one-click sign-in from a trusted source, like Facebook.</li>
  634. <li>Enable payment on a trusted payment provider’s website, like PayPal, Google Wallet or Stripe.</li>
  635. </ul>
  637. <p>One of the nice things about <a href="">Sephora</a>'s already convenient checkout process is that customers can automate the sign-in process going forward with a simple toggle:</p>
  649. <figure >
  650. <img
  651. srcset=",q_auto/w_400/ 400w,
  652.,q_auto/w_800/ 800w,
  653.,q_auto/w_1200/ 1200w,
  654.,q_auto/w_1600/ 1600w,
  655.,q_auto/w_2000/ 2000w"
  656. src=",q_auto/w_400/"
  657. sizes="100vw"
  658. alt="Sephora lets customers save sign-in information"
  659. />
  661. <figcaption class="op-vertical-bottom">
  662. Sephora enables return customers to stay signed in, to avoid this during checkout again. (Image: <a href=''>Sephora</a>) (<a href=''>View large version</a>)
  663. </figcaption>
  664. </figure>
  667. <p>When mobile customers are feeling the rush and want to get to the next stage of checkout, Sephora’s auto-sign-in feature would definitely come in handy and encourage customers to buy more frequently from the mobile website.</p>
  669. <p>Many mobile websites wait until the bottom of the login page to tell customers what kinds of options they have for checking out. But rather than surprise them late, <a href="">Victoria’s Secret</a> displays this information in big bold buttons right at the very top:</p>
  681. <figure >
  682. <img
  683. srcset=",q_auto/w_400/ 400w,
  684.,q_auto/w_800/ 800w,
  685.,q_auto/w_1200/ 1200w,
  686.,q_auto/w_1600/ 1600w,
  687.,q_auto/w_2000/ 2000w"
  688. src=",q_auto/w_400/"
  689. sizes="100vw"
  690. alt="Victoria’s Secret express checkout options"
  691. />
  693. <figcaption class="op-vertical-bottom">
  694. Victoria’s Secret simplifies and speeds up checkout by giving three attractive options. (Image: <a href=''>Victoria’s Secret</a>) (<a href=''>View large version</a>)
  695. </figcaption>
  696. </figure>
  699. <p>Customers have a choice of signing in with their account, checking out as a guest or going directly to PayPal. They are not surprised to discover later on that their preferred checkout or payment method isn’t offered.</p>
  701. <p>I also really love how Victoria’s Secret has chosen to do this. There’s something nice about the brightly colored “Sign In” button sitting beside the more muted “Check Out as a Guest” button. For one, it adds a hint of Victoria’s Secret brand colors to the checkout, which is always a nice touch. But the way it’s colored the buttons also makes clear what it wants the primary action to be (i.e. to create an account and sign in).</p>
  703. <h4>6. Add Breadcrumbs</h4>
  705. <p>When you send mobile customers to checkout, the last thing you want is to give them unnecessary distractions. That’s why the website’s standard navigation bar (or hamburger menu) is typically removed from this page.</p>
  707. <p>Nonetheless, the checkout process can be intimidating if customers don’t know what’s ahead. How many forms will they need to fill out? What sort of information is needed? Will they have a chance to review their order before submitting payment details?</p>
  709. <p>If you’ve designed a multi-page checkout, allay your customers’ fears by defining each step with clearly labeled breadcrumb navigation at the top of the page. In addition, this will give your checkout a cleaner design, reducing the number of clicks and scrolling per page.</p>
  711. <p><a href="">Hayneedle</a> has a beautiful example of breadcrumb navigation in action:</p>
  723. <figure >
  724. <img
  725. srcset=",q_auto/w_400/ 400w,
  726.,q_auto/w_800/ 800w,
  727.,q_auto/w_1200/ 1200w,
  728.,q_auto/w_1600/ 1600w,
  729.,q_auto/w_2000/ 2000w"
  730. src=",q_auto/w_400/"
  731. sizes="100vw"
  732. alt="Hayneedle checkout breadcrumb navigation"
  733. />
  735. <figcaption class="op-vertical-bottom">
  736. Hayneedle’s breadcrumbs are cleanly designed and easy to find. (Image: <a href=''>Hayneedle</a>) (<a href=''>View large version</a>)
  737. </figcaption>
  738. </figure>
  741. <p>You can see that three steps are broken out and clearly labeled. There’s absolutely no question here about what users will encounter in those steps either, which will help put their minds at ease. Three steps seems reasonable enough, and users will have a chance to review the order once more before completing the purchase.</p>
  743. <p><a href="">Sephora</a> has an alternative style of “breadcrumbs” in its checkout:</p>
  755. <figure >
  756. <img
  757. srcset=",q_auto/w_400/ 400w,
  758.,q_auto/w_800/ 800w,
  759.,q_auto/w_1200/ 1200w,
  760.,q_auto/w_1600/ 1600w,
  761.,q_auto/w_2000/ 2000w"
  762. src=",q_auto/w_400/"
  763. sizes="100vw"
  764. alt="Sephora’s numbered breadcrumbs navigation"
  765. />
  767. <figcaption class="op-vertical-bottom">
  768. Sephora’s numbered breadcrumbs appear as you complete each section. (Image: <a href=''>Sephora</a>) (<a href=''>View large version</a>)
  769. </figcaption>
  770. </figure>
  773. <p>Instead of placing each “breadcrumb” at the top of the checkout page, Sephora’s customers can see what the next step is, as well as how many more are to come as they work their way through the form.</p>
  775. <p>This is a good option to take if you’d rather not make the top navigation or the breadcrumbs sticky. Instead, you can prioritize the call to action (CTA), which you might find better motivates the customer to move down the page and complete their purchase.</p>
  777. <p>I think both of these breadcrumbs designs are valid, though. So, it might be worth A/B testing them if you’re unsure of which would lead to more conversions for your visitors.</p>
  779. <h4>7. Format the Checkout Form Wisely</h4>
  781. <p>Good mobile checkout form design follows a pretty strict formula, which isn’t surprising. While there are ways to bend the rules on desktop in terms of structuring the form, the number of steps per page, the inclusion of images and so on, you really don’t have that kind of flexibility on mobile.</p>
  783. <p>Instead, you will need to be meticulous when building the form:</p>
  785. <ul>
  786. <li>Design each field of the checkout form so that it stretches the full width of the website.</li>
  787. <li>Limit the fields to only what’s essential.</li>
  788. <li>Clearly label each field outside of and above it.</li>
  789. <li>Use at least a 16-point-pixel font.</li>
  790. <li>Format each field so that it’s large enough to tap into without zooming.</li>
  791. <li>Use a recognizable mark to indicate when something is required (like an asterisk).</li>
  792. <li>Always let users know when an error has been made immediately after the information has been inputted in a field.</li>
  793. <li>Place the call to action at the very bottom of the form.</li>
  794. </ul>
  796. <p>Because the checkout form is the most important element that moves customers through the checkout process, you can’t afford to mess around with a tried and true formula. If users can’t seamlessly get from top to bottom, if the fields are too difficult to engage with, or if the functionality of the form itself is riddled with errors, then you might as well kiss your mobile purchases (and maybe your purchases in general) goodbye.</p>
  798. <p><a href="">Crutchfield</a> shows how to create form fields that are very user-friendly on mobile:</p>
  810. <figure >
  811. <img
  812. srcset=",q_auto/w_400/ 400w,
  813.,q_auto/w_800/ 800w,
  814.,q_auto/w_1200/ 1200w,
  815.,q_auto/w_1600/ 1600w,
  816.,q_auto/w_2000/ 2000w"
  817. src=",q_auto/w_400/"
  818. sizes="100vw"
  819. alt="Large-sized form fields on the Crutchfield checkout"
  820. />
  822. <figcaption class="op-vertical-bottom">
  823. Form fields on the Crutchfield checkout page are large and difficult to miss. (Image: <a href=''>Crutchfield</a>) (<a href=''>View large version</a>)
  824. </figcaption>
  825. </figure>
  828. <p>As you can see, each field is large enough to click on (even with fat fingers). The bold outline around the currently selected field is also a nice touch. For a customer who is multitasking and or distracted by something around them, returning to the checkout form would be much easier with this type of format.</p>
  830. <p><a href="">Sephora</a>, again, handles mobile checkout the right way. In this case, I want to draw your attention to the grayed-out “Place Order” button:</p>
  842. <figure >
  843. <img
  844. srcset=",q_auto/w_400/ 400w,
  845.,q_auto/w_800/ 800w,
  846.,q_auto/w_1200/ 1200w,
  847.,q_auto/w_1600/ 1600w,
  848.,q_auto/w_2000/ 2000w"
  849. src=",q_auto/w_400/"
  850. sizes="100vw"
  851. alt="Smart use of the Sephora call to action in checkout"
  852. />
  854. <figcaption class="op-vertical-bottom">
  855. Sephora uses the call to action as a guide for customers who haven’t finished the form. (Image: <a href=''>Sephora</a>) (<a href=''>View large version</a>)
  856. </figcaption>
  857. </figure>
  860. <p>The button serves as an indicator to customers that they’re not quite ready to submit their purchase information yet, which is great. Even though the form is beautifully designed &mdash; everything is well labeled, the fields are large, and the form is logically organized &mdash; mobile users could accidentally scroll too far past a field and wouldn’t know it until clicking the call-to-action button.</p>
  862. <p>If you can keep users from receiving that dreaded “missing information” error, you’ll do a better job of holding onto their purchases.</p>
  864. <h4>8. Simplify Form Input</h4>
  866. <p>Digging a bit deeper into these contact forms, let’s look at how you can simplify the input of data on mobile:</p>
  868. <ul>
  869. <li>Allow customers to user their browser’s autocomplete functionality to fill in forms.</li>
  870. <li>Include a <code>tabindex</code> HTML directive to enable customers to tap an arrow up and down through the form. This keeps their thumbs within a comfortable range on the smartphone at all times, instead of constantly reaching up to tap into a new field.</li>
  871. <li>Add a checkbox that automatically copies the billing address information over to the shipping fields.</li>
  872. <li>Change the keyboard according to what kind of field is being typed in.</li>
  873. </ul>
  875. <p>One example of this is <a href="">Bass Pro Shops</a>’ mobile website:</p>
  887. <figure >
  888. <img
  889. srcset=",q_auto/w_400/ 400w,
  890.,q_auto/w_800/ 800w,
  891.,q_auto/w_1200/ 1200w,
  892.,q_auto/w_1600/ 1600w,
  893.,q_auto/w_2000/ 2000w"
  894. src=",q_auto/w_400/"
  895. sizes="100vw"
  896. alt="Bass Pro checkout form uses a smart keyboard"
  897. />
  899. <figcaption class="op-vertical-bottom">
  900. Each field in the Bass Pro checkout form provides users with the right keyboard type. (Image: <a href=''>Bass Pro Shops</a>) (<a href=''>View large version</a>)
  901. </figcaption>
  902. </figure>
  905. <p>For starters, the keyboard uses tab functionality (see the up and down arrows just above the keyboard). For customers with short fingers or who are impatient and just want to type away on the keyboard, the tabs help keep their hands in one place, thus speeding up checkout.</p>
  907. <p>Also, when customers tab into a numbers-only field (like for their phone number), the keyboard automatically changes, so they don’t have to switch manually. Again, this is another way to up the convenience of making a purchase on mobile.</p>
  909. <p><a href="">Amazon</a>’s mobile checkout includes a quick checkbox that streamlines customers’ submission of billing information:</p>
  921. <figure >
  922. <img
  923. srcset=",q_auto/w_400/ 400w,
  924.,q_auto/w_800/ 800w,
  925.,q_auto/w_1200/ 1200w,
  926.,q_auto/w_1600/ 1600w,
  927.,q_auto/w_2000/ 2000w"
  928. src=",q_auto/w_400/"
  929. sizes="100vw"
  930. alt="Amazon streamlines form input with address duplication"
  931. />
  933. <figcaption class="op-vertical-bottom">
  934. Amazon gives customers an easy way to duplicate their shipping address to billing. (Image: <a href=''>Amazon</a>) (<a href=''>View large version</a>)
  935. </figcaption>
  936. </figure>
  939. <p>As we’ve seen with mobile checkout form design, simpler is always better. Obviously, you will always need to collect certain details from customers each time (unless their account has saved that information). Nonetheless, if you can provide a quick toggle or checkbox that enables them to copy data over from one form to another, then do it.</p>
  941. <h4>9. Don’t Skimp on the CTA</h4>
  943. <p>When designing a desktop checkout, your main concerns with the CTA are things like strategic placement of the button and choosing an eye-catching color to draw attention to it.</p>
  945. <p>On mobile, however, you have to think about size, too &mdash; and not just how much space it takes up on the screen. Remember the thumb zone and the various ways in which users hold their phone. Ensure that the button is wide enough so that any user can easily click on it without having to change their hand position.</p>
  947. <p>So, your goal should be to design buttons that (1) sit at the bottom of the mobile checkout page and (2) stretch all the way from left to right, as is the case on <a href="">Staples</a>’ mobile website:</p>
  959. <figure >
  960. <img
  961. srcset=",q_auto/w_400/ 400w,
  962.,q_auto/w_800/ 800w,
  963.,q_auto/w_1200/ 1200w,
  964.,q_auto/w_1600/ 1600w,
  965.,q_auto/w_2000/ 2000w"
  966. src=",q_auto/w_400/"
  967. sizes="100vw"
  968. alt="Staple’s big blue CTA button"
  969. />
  971. <figcaption class="op-vertical-bottom">
  972. Staple’s bright blue CTA sticks out in an otherwise plain checkout. (Image: <a href=''>Staples</a>) (<a href=''>View large version</a>)
  973. </figcaption>
  974. </figure>
  977. <p>No matter who is making the purchase &mdash; a left-handed, a right-handed or a two-handed cradler &mdash; that button will be easy reach.</p>
  979. <p>Of all the mobile checkout enhancements we’ve covered today, the CTA is the easiest one to address. Make it big, give it a distinctive color, place it at the very bottom of the mobile screen, and make it span the full width. In other words, don’t make customers work hard to take the final step in a purchase.</p>
  981. <h4>10. Offer an Alternate Way Out</h4>
  983. <p>Finally, give customers an alternate way out.</p>
  985. <p>Let’s say they’re shopping on a mobile website, adding items to their cart, but something isn’t sitting right with them, and they don’t want to make the purchase. You’ve done everything you can to assure them along the way with a clean, easy and secure checkout experience, but they just aren’t confident in making a payment on their phone.</p>
  987. <p>Rather than merely hoping you don’t lose the purchase entirely, give them a chance to save it for later. That way, if they really are interested in buying your product, they can revisit on desktop and pull the trigger. It’s not ideal, because you do want to keep them in place on mobile, but the option is good for customers who just can’t be saved.</p>
  989. <p>As you can see on <a href="">L.L. Bean</a>’s mobile website, there is an option at checkout to “Move to Wish List”:</p>
  1001. <figure >
  1002. <img
  1003. srcset=",q_auto/w_400/ 400w,
  1004.,q_auto/w_800/ 800w,
  1005.,q_auto/w_1200/ 1200w,
  1006.,q_auto/w_1600/ 1600w,
  1007.,q_auto/w_2000/ 2000w"
  1008. src=",q_auto/w_400/"
  1009. sizes="100vw"
  1010. alt="L.L. Bean wish list option"
  1011. />
  1013. <figcaption class="op-vertical-bottom">
  1014. L.L. Bean gives customers another chance to move items to their wish list during checkout. (Image: <a href=''>L.L. Bean</a>) (<a href=''>View large version</a>)
  1015. </figcaption>
  1016. </figure>
  1019. <p>What’s nice about this is that L.L. Bean clearly doesn’t want browsing of the wish list or the removal of an item to be a primary action. If “Move to Wish List” were shown as a big bold CTA button, more customers might decide to take this seemingly safer alternative. As it’s designed now, it’s more of a, “Hey, we don’t want you to do anything you’re not comfortable with. This is here just in case.”</p>
  1021. <p>While fewer options are generally better in web design, this might be something to explore if your checkout has a high cart abandonment rate on mobile.</p>
  1023. <h3>Wrapping Up</h3>
  1025. <p>As more mobile visitors flock to your website, every step leading to conversion &mdash; including the checkout phase &mdash; needs to be optimized for convenience, speed and security. If your checkout is not adeptly designed to mobile users’ specific needs and expectations, you’re going to find that those conversion rates drop or shift back to desktop &mdash; and that’s not the direction you want things to go in, especially if Google is pushing us all towards a mobile-first world.</p>
  1027. <div class="signature">
  1028.  <img src="" alt="Smashing Editorial">
  1029.  <span>(da, ra, yk, al, il)</span>
  1030. </div>
  1034.  <div id="sponsors-article-end" data-impression="true" class="c-promo-box c-promo-box--ad c-promo-box--wide sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  1038. </div>
  1042.              </article>
  1043.            </body>
  1044.          </html>
  1045.        ]]></content:encoded>
  1046.      </item>
  1048.      <item>
  1051.          <author>Oleh Mryhlod</author>
  1053.        <title>How To Create An Audio/Video Recording App With React Native: An In-Depth Tutorial</title>
  1054.        <link></link>
  1055.        <pubDate>Thu, 19 Apr 2018 12:15:26 +0200</pubDate>
  1056.        <guid></guid>
  1057.        <description>React Native is a young technology, already gaining popularity among developers. It is a great option for smooth, fast, and efficient mobile app development. High-performance rates for mobile environments, code reuse, and a strong community: These are just some of the benefits React Native provides.
  1058. In this guide, I will share some insights about the high-level capabilities of React Native and the products you can develop with it in a short period of time.</description>
  1059.        <content:encoded><![CDATA[
  1060.          <html>
  1061.            <head>
  1062.              <meta charset="utf-8">
  1063.              <link rel="canonical" href="" />
  1064.              <title>How To Create An Audio/Video Recording App With React Native: An In-Depth Tutorial</title>
  1065.            </head>
  1066.            <body>
  1067.              <article>
  1068.                <header>
  1069.                  <h1>How To Create An Audio/Video Recording App With React Native: An In-Depth Tutorial</h1>
  1072.                    <address>Oleh Mryhlod</address>
  1074.                  <time datetime="2018-04-19T12:15:26&#43;02:00" class="op-published">2018-04-19T12:15:26+02:00</time>
  1075.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  1076.                </header>
  1077.                <p>React Native is a young technology, already gaining popularity among developers. It is a great option for smooth, fast, and efficient mobile app development. High-performance rates for mobile environments, code reuse, and a strong community: These are just some of the benefits React Native provides.</p>
  1079. <p>In this guide, I will share some insights about the high-level capabilities of React Native and the products you can develop with it in a short period of time.</p>
  1081. <p>We will delve into the step-by-step process of creating a video/audio recording app with React Native and <a href="">Expo</a>.  Expo is an open-source toolchain built around React Native for developing iOS and Android projects with React and JavaScript. It provides a bunch of native APIs maintained by native developers and the open-source community.</p>
  1083. <p>After reading this article, you should have all the necessary knowledge to create video/audio recording functionality with React Native.</p>
  1085. <p>Let's get right to it.</p>
  1087. <h3>Brief Description Of The Application</h3>
  1089. <p>The application you will learn to develop is called a multimedia notebook. I have implemented part of this functionality in an online job board application for the film industry. The main goal of this mobile app is to connect people who work in the film industry with employers. They can create a profile, add a video or audio introduction, and apply for jobs.</p>
  1091. <p>The application consists of three main screens that you can switch between with the help of a tab navigator:</p>
  1093. <ul>
  1094. <li>the audio recording screen,</li>
  1095. <li>the video recording screen,</li>
  1096. <li>a screen with a list of all recorded media and functionality to play back or delete them.</li>
  1097. </ul>
  1099. <p><em>Check out how this app works by <a href="">opening this link with Expo</a>.</em></p>
  1103. <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  1104.    <div class="container product-panel--book__container">
  1105.      <div class="panel__description panel__description--book">
  1106.    <p>Getting workflow <em>just</em> right ain't an easy task. So are proper estimates. Or alignment among different departments. That's why we've set up <strong>'this-is-how-I-work'-sessions</strong> — with smart cookies sharing what works well for them. A part of the <a href="">Smashing Membership</a>, of course.</p>
  1107.      <a href="" class="btn btn--green btn--large">
  1108.        Explore features&nbsp;→
  1109.      </a>
  1110.      </div>
  1111.      <div class="panel__image panel__image--book">
  1112.        <a href="" class="books__book__image">
  1113.        <div class="books__book__img">
  1114.          <img src="" alt="Smashing TV, with live sessions for professional designers and developers." width="310" height="400">
  1115.        </div>
  1116.      </a>
  1117.      </div>
  1118.    </div>
  1119.  </aside>
  1125. <div class="c-garfield-the-cat">
  1128. <p>First, download Expo to your mobile phone. There are two options to open the project :</p>
  1130. <ol>
  1131. <li>Open the link in the browser, scan the QR code with your mobile phone, and wait for the project to load.</li>
  1132. <li>Open the link with your mobile phone and click on “Open project using Expo”.</li>
  1133. </ol>
  1135. <p>You can also open the app in the browser. Click on “Open project in the browser”. If you have a paid account on <a href=""></a>, visit it and enter the code in the field to open the project. If you don’t have an account, click on “Open project” and wait in an account-level queue to open the project.</p>
  1137. <p>However, I recommend that you download the Expo app and open this project on your mobile phone to check out all of the features of the video and audio recording app.</p>
  1139. <p><em>You can find the full code for the media recording app in the <a href="">repository</a> on GitHub.</em></p>
  1141. <h4>Dependencies Used For App Development</h4>
  1143. <p>As mentioned, the media recording app is developed with React Native and Expo.</p>
  1145. <p>You can see the full list of dependencies in the repository’s <code>package.json</code> file.</p>
  1147. <p>These are the main libraries used:</p>
  1149. <ul>
  1150. <li>React-navigation, for navigating the application,</li>
  1151. <li>Redux, for saving the application’s state,</li>
  1152. <li>React-redux, which are React bindings for Redux,</li>
  1153. <li>Recompose, for writing the components’ logic,</li>
  1154. <li>Reselect, for extracting the state fragments from Redux.</li>
  1155. </ul>
  1157. <p>Let's look at the project's structure:</p>
  1169. <figure >
  1170. <img
  1171. srcset=",q_auto/w_400/ 400w,
  1172.,q_auto/w_800/ 800w,
  1173.,q_auto/w_1200/ 1200w,
  1174.,q_auto/w_1600/ 1600w,
  1175.,q_auto/w_2000/ 2000w"
  1176. src=",q_auto/w_400/"
  1177. sizes="70vw"
  1178. alt=""
  1179. />
  1181. <figcaption class="op-vertical-bottom">
  1182. <a href=''>Large preview</a>
  1183. </figcaption>
  1184. </figure>
  1187. <ul>
  1188. <li><code>src/index.js</code>: root app component imported in the <code>app.js</code> file;</li>
  1189. <li><code>src/components</code>: reusable components;</li>
  1190. <li><code>src/constants</code>: global constants;</li>
  1191. <li><code>src/styles</code>: global styles, colors, fonts sizes and dimensions.</li>
  1192. <li><code>src/utils</code>: useful utilities and recompose enhancers;</li>
  1193. <li><code>src/screens</code>: screens components;</li>
  1194. <li><code>src/store</code>: Redux store;</li>
  1195. <li><code>src/navigation</code>: application’s navigator;</li>
  1196. <li><code>src/modules</code>: Redux modules divided by entities as modules/audio, modules/video, modules/navigation.</li>
  1197. </ul>
  1199. <p>Let’s proceed to the practical part.</p>
  1201. <h3>Create Audio Recording Functionality With React Native</h3>
  1203. <p>First, it's important to сheck the <a href="">documentation for the Expo Audio API</a>, related to audio recording and playback. You can see all of the code in the <a href="">repository</a>. I recommend opening the code as you read this article to better understand the process.</p>
  1205. <p>When launching the application for the first time, you’ll need the user's permission for audio recording, which entails access to the microphone. Let's use <code>Expo.AppLoading</code> and ask permission for recording by using <code>Expo.Permissions</code> (see the <code>src/index.js</code>) during <code>startAsync</code>.</p>
  1207. <p><strong>Await</strong> <code>Permissions.askAsync(Permissions.AUDIO_RECORDING);</code></p>
  1209. <p>Audio recordings are displayed on a seperate screen whose UI changes depending on the state.</p>
  1211. <p>First, you can see the button “Start recording”. After it is clicked, the audio recording begins, and you will find the current audio duration on the screen. After stopping the recording, you will have to type the recording’s name and save the audio to the <strong>Redux store</strong>.</p>
  1213. <p>My audio recording UI looks like this:</p>
  1225. <figure >
  1226. <img
  1227. srcset=",q_auto/w_400/ 400w,
  1228.,q_auto/w_800/ 800w,
  1229.,q_auto/w_1200/ 1200w,
  1230.,q_auto/w_1600/ 1600w,
  1231.,q_auto/w_2000/ 2000w"
  1232. src=",q_auto/w_400/"
  1233. sizes="100vw"
  1234. alt=""
  1235. />
  1237. <figcaption class="op-vertical-bottom">
  1238. <a href=''>Large preview</a>
  1239. </figcaption>
  1240. </figure>
  1243. <p>I can save the audio in the <strong>Redux store</strong> in the following format:</p>
  1245. <pre><code class="language-javascript">audioItemsIds: [‘id1’, ‘id2’],
  1246. audioItems: {
  1247. ‘id1’: {
  1248.    id: string,
  1249.    title: string,
  1250.    recordDate: date string,
  1251.    duration: number,
  1252.    audioUrl: string,
  1253. }
  1254. },</code></pre>
  1256. <p>Let’s write the audio logic by using Recompose in the screen’s container <code>src/screens/RecordAudioScreenContainer</code>.</p>
  1258. <p>Before you start recording, customize the audio mode with the help of <code>Expo.Audio.set.AudioModeAsync</code> (mode), where mode is the dictionary with the following <strong>key-value pairs</strong>:</p>
  1260. <ul>
  1261. <li><code>playsInSilentModeIOS</code>: A boolean selecting whether your experience’s audio should play in silent mode on iOS. This value defaults to false.</li>
  1262. <li><code>allowsRecordingIOS</code>: A boolean selecting whether recording is enabled on iOS. This value defaults to false. Note: When this flag is set to true, playback may be routed to the phone receiver, instead of to the speaker.</li>
  1263. <li><code>interruptionModeIOS</code>: An enum selecting how your experience’s audio should interact with the audio from other apps on iOS.</li>
  1264. <li><code>shouldDuckAndroid</code>: A boolean selecting whether your experience’s audio should automatically be lowered in volume (“duck”) if audio from another app interrupts your experience. This value defaults to true. If false, audio from other apps will pause your audio.</li>
  1265. <li><code>interruptionModeAndroid</code>: An enum selecting how your experience’s audio should interact with the audio from other apps on Android.</li>
  1266. </ul>
  1268. <p><strong>Note</strong>: <em>You can learn more about the customization of <strong>AudioMode</strong> in <a href="">the documentation</a>.</em></p>
  1270. <p>I have used the following values in this app:</p>
  1272. <p><code>interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX</code>, &mdash; Our record interrupts audio from other apps on IOS.</p>
  1274. <p><code>playsInSilentModeIOS</code>: <strong>true</strong>,</p>
  1276. <p><code>shouldDuckAndroid</code>: <strong>true</strong>,</p>
  1278. <p><code>interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX</code> &mdash; Our record interrupts audio from other apps on Android.</p>
  1280. <p><code>allowsRecordingIOS</code> Will change to true before the audio recording and to false after its completion.</p>
  1282. <p>To implement this, let's write the handler <code>setAudioMode</code> with <strong>Recompose</strong>.</p>
  1284. <pre class="break-out"><code class="language-javascript">withHandlers({
  1285. setAudioMode: () => async ({ allowsRecordingIOS }) => {
  1286.   try {
  1287.     await Audio.setAudioModeAsync({
  1288.       allowsRecordingIOS,
  1289.       interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
  1290.       playsInSilentModeIOS: true,
  1291.       shouldDuckAndroid: true,
  1292.       interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
  1293.     });
  1294.   } catch (error) {
  1295.     console.log(error) // eslint-disable-line
  1296.   }
  1297. },
  1298. }),</code></pre>
  1300. <p>To record the audio, you’ll need to create an instance of the <code>Expo.Audio.Recording class</code>.</p>
  1302. <pre><code class="language-javascript">const recording = new Audio.Recording();</code></pre>
  1304. <p>After creating the recording instance, you will be able to receive the <strong>status of the Recording</strong> with the help of <code>recordingInstance.getStatusAsync()</code>.</p>
  1306. <p>The status of the recording is a dictionary with the following key-value pairs:</p>
  1308. <ul>
  1309. <li><code>canRecord:</code> a boolean.</li>
  1310. <li><code>isRecording:</code> a boolean describing whether the recording is currently recording.</li>
  1311. <li><code>isDoneRecording:</code> a boolean.</li>
  1312. <li><code>durationMillis:</code> current duration of the recorded audio.</li>
  1313. </ul>
  1315. <p>You can also set a function to be called at regular intervals with <code>recordingInstance.setOnRecordingStatusUpdate(onRecordingStatusUpdate).</code></p>
  1317. <p>To update the UI, you will need to call <code>setOnRecordingStatusUpdate</code> and set your own callback.</p>
  1319. <p>Let’s add some props and a recording callback to the container.</p>
  1321. <pre class="break-out"><code class="language-javascript">withStateHandlers({
  1322.    recording: null,
  1323.    isRecording: false,
  1324.    durationMillis: 0,
  1325.    isDoneRecording: false,
  1326.    fileUrl: null,
  1327.    audioName: '',
  1328.  }, {
  1329.    setState: () => obj => obj,
  1330.    setAudioName: () => audioName => ({ audioName }),
  1331.   recordingCallback: () => ({ durationMillis, isRecording, isDoneRecording }) =>
  1332.      ({ durationMillis, isRecording, isDoneRecording }),
  1333.  }),</code></pre>
  1335. <p>The callback setting for <code>setOnRecordingStatusUpdate</code> is:</p>
  1337. <p><code>recording.setOnRecordingStatusUpdate(props.recordingCallback);</code></p>
  1339. <p><code>onRecordingStatusUpdate</code> is called every 500 milliseconds by default. To make the UI update valid, set the 200 milliseconds interval with the help of <code>setProgressUpdateInterval</code>:</p>
  1341. <p><code>recording.setProgressUpdateInterval(200);</code></p>
  1343. <p>After creating an instance of this class, call <code>prepareToRecordAsync</code> to record the audio.</p>
  1345. <p><code>recordingInstance.prepareToRecordAsync(options)</code> loads the recorder into memory and prepares it for recording. It must be called before calling <code>startAsync()</code>. This method can be used if the <strong>recording instance</strong> has never been prepared.</p>
  1348.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  1352. <p>The parameters of this method include such options for the recording as sample rate, bitrate, channels, format, encoder and extension. You can find a list of all recording options in this <a href="">document</a>.</p>
  1354. <p>In this case, let’s use <code>Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY</code>.</p>
  1356. <p>After the recording has been prepared, you can start recording by calling the method <code>recordingInstance.startAsync()</code>.</p>
  1358. <p>Before creating a new <strong>recording instance</strong>, check whether it has been created before. <strong>The handler</strong> for beginning the recording looks like this:</p>
  1360. <pre class="break-out"><code class="language-javascript">onStartRecording: props => async () => {
  1361.      try {
  1362.        if (props.recording) {
  1363.          props.recording.setOnRecordingStatusUpdate(null);
  1364.          props.setState({ recording: null });
  1365.        }
  1367.        await props.setAudioMode({ allowsRecordingIOS: true });
  1369.        const recording = new Audio.Recording();
  1370.        recording.setOnRecordingStatusUpdate(props.recordingCallback);
  1371.        recording.setProgressUpdateInterval(200);
  1373.        props.setState({ fileUrl: null });
  1375. await recording.prepareToRecordAsync(Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY);
  1376.        await recording.startAsync();
  1378.        props.setState({ recording });
  1379.      } catch (error) {
  1380.        console.log(error) // eslint-disable-line
  1381.      }
  1382.    },</code></pre>
  1384. <p>Now you need to write a <strong>handler</strong> for the audio recording completion. After clicking the stop button, you have to stop the recording, disable it on iOS, receive and save the local URL of the recording, and set <code>OnRecordingStatusUpdate</code> and the <strong>recording instance to null</strong>:</p>
  1386. <pre class="break-out"><code class="language-javascript">onEndRecording: props => async () => {
  1387.      try {
  1388.        await props.recording.stopAndUnloadAsync();
  1389.        await props.setAudioMode({ allowsRecordingIOS: false });
  1390.      } catch (error) {
  1391.        console.log(error); // eslint-disable-line
  1392.      }
  1394.      if (props.recording) {
  1395.        const fileUrl = props.recording.getURI();
  1396.        props.recording.setOnRecordingStatusUpdate(null);
  1397.        props.setState({ recording: null, fileUrl });
  1398.      }
  1399.    },</code></pre>
  1401. <p>After this, type the audio name, click the <strong>“continue”</strong> button, and the audio note will be saved in the <strong>Redux store</strong>.</p>
  1403. <pre><code class="language-javascript">onSubmit: props => () => {
  1404.      if (props.audioName && props.fileUrl) {
  1405.        const audioItem = {
  1406.          id: uuid(),
  1407.          recordDate: moment().format(),
  1408.          title: props.audioName,
  1409.          audioUrl: props.fileUrl,
  1410.          duration: props.durationMillis,
  1411.        };
  1413.        props.addAudio(audioItem);
  1414.        props.setState({
  1415.          audioName: '',
  1416.          isDoneRecording: false,
  1417.        });
  1419.        props.navigation.navigate(screens.LibraryTab);
  1420.      }
  1421.    },</code></pre>
  1423. <figure><a href=""><img src="" width="384" height="680" alt="" /></a><figcaption>(<a href="">Large preview</a>)</figcaption></figure>
  1425. <h3>Audio Playback With React Native</h3>
  1427. <p>You can play the audio on the screen with the saved audio notes. To start the audio playback, click one of the items on the list. Below, you can see the audio player that allows you to track the current position of playback, to set the playback starting point and to toggle the playing audio.</p>
  1429. <p>Here’s what my audio playback UI looks like:</p>
  1441. <figure >
  1442. <img
  1443. srcset=",q_auto/w_400/ 400w,
  1444.,q_auto/w_800/ 800w,
  1445.,q_auto/w_1200/ 1200w,
  1446.,q_auto/w_1600/ 1600w,
  1447.,q_auto/w_2000/ 2000w"
  1448. src=",q_auto/w_400/"
  1449. sizes="100vw"
  1450. alt=""
  1451. />
  1453. <figcaption class="op-vertical-bottom">
  1454. <a href=''>Large preview</a>
  1455. </figcaption>
  1456. </figure>
  1459. <p><a href="">The Expo.Audio.Sound objects and Expo.Video components</a> share a unified imperative API for media playback.</p>
  1461. <p>Let's write the logic of the audio playback by using Recompose in the screen container <code>src/screens/LibraryScreen/LibraryScreenContainer</code>, as the audio player is available only on this screen.</p>
  1463. <p>If you want to display the player at any point of the application, I recommend writing the logic of the player and audio playback in <strong>Redux operations</strong> using <strong>redux-thunk</strong>.</p>
  1465. <p>Let's customize the audio mode in the same way we did for the audio recording. First, set <code>allowsRecordingIOS</code> to <strong>false</strong>.</p>
  1467. <pre class="break-out"><code class="language-javascript">lifecycle({
  1468.    async componentDidMount() {
  1469.      await Audio.setAudioModeAsync({
  1470.        allowsRecordingIOS: false,
  1471.        interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
  1472.        playsInSilentModeIOS: true,
  1473.        shouldDuckAndroid: true,
  1474.        interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
  1475.      });
  1476.    },
  1477.  }),</code></pre>
  1479. <p>We have created the <strong>recording instance</strong> for audio recording. As for audio playback, we need to create the <strong>sound instance</strong>. We can do it in two different ways:</p>
  1481. <ol>
  1482. <li><code>const playbackObject = new Expo.Audio.Sound();</code></li>
  1483. <li><code>Expo.Audio.Sound.create(source, initialStatus = {}, onPlaybackStatusUpdate = null, downloadFirst = true)</code></li>
  1484. </ol>
  1486. <p>If you use the first method, you will need to call <code>playbackObject.loadAsync()</code>, which loads the media from source into memory and prepares it for playing, after creation of the instance.</p>
  1488. <p>The second method is a static convenience method to construct and load a sound. It сreates and loads a sound from source with the optional <code>initialStatus</code>, <code>onPlaybackStatusUpdate</code> and <code>downloadFirst</code> parameters.</p>
  1490. <p>The source parameter is the source of the sound. It supports the following forms:</p>
  1492. <ul>
  1493. <li>a dictionary of the form <code>{ uri: 'http://path/to/file' }</code> with a network URL pointing to an audio file on the web;</li>
  1494. <li><code>require('path/to/file')</code> for an audio file asset in the source code directory;</li>
  1495. <li>an <a href="">Expo.Asset</a> object for an audio file asset.</li>
  1496. </ul>
  1498. <p><code>The initialStatus</code> parameter is the initial playback status. <code>PlaybackStatus</code> is the structure returned from all playback API calls describing the state of the <code>playbackObject</code> at that point of time. It is a dictionary with the key-value pairs. You can check all of the keys of the <code>PlaybackStatus</code> in the <a href="">documentation</a>.</p>
  1500. <p><code>onPlaybackStatusUpdate</code> is a function taking a single parameter, <code>PlaybackStatus</code>. It is called at regular intervals while the media is in the loaded state. The interval is 500 milliseconds by default. In my application, I set it to 50 milliseconds interval for a proper UI update.</p>
  1502. <p>Before creating the sound instance, you will need to implement the <code>onPlaybackStatusUpdate callback</code>. First, add some props to the screen container:</p>
  1504. <pre><code class="language-javascript">withClassVariableHandlers({
  1505.    playbackInstance: null,
  1506.    isSeeking: false,
  1507.    shouldPlayAtEndOfSeek: false,
  1508.    playingAudio: null,
  1509.  }, 'setClassVariable'),
  1510.  withStateHandlers({
  1511.    position: null,
  1512.    duration: null,
  1513.    shouldPlay: false,
  1514.    isLoading: true,
  1515.    isPlaying: false,
  1516.    isBuffering: false,
  1517.    showPlayer: false,
  1518.  }, {
  1519.    setState: () => obj => obj,
  1520.  }),</code></pre>
  1522. <p>Now, implement <code>onPlaybackStatusUpdate</code>. You will need to make several validations based on <code>PlaybackStatus</code> for a proper UI display:</p>
  1524. <pre class="break-out"><code class="language-javascript">withHandlers({
  1525.    soundCallback: props => (status) => {
  1526.      if (status.didJustFinish) {
  1527.        props.playbackInstance().stopAsync();
  1528.      } else if (status.isLoaded) {
  1529.        const position = props.isSeeking()
  1530.          ? props.position
  1531.          : status.positionMillis;
  1532.        const isPlaying = (props.isSeeking() || status.isBuffering)
  1533.          ? props.isPlaying
  1534.          : status.isPlaying;
  1535.        props.setState({
  1536.          position,
  1537.          duration: status.durationMillis,
  1538.          shouldPlay: status.shouldPlay,
  1539.          isPlaying,
  1540.          isBuffering: status.isBuffering,
  1541.        });
  1542.      }
  1543.    },
  1544.  }),</code></pre>
  1546. <p>After this, you have to implement a handler for the audio playback. If a sound instance is already created, you need to unload the media from memory by calling <code>playbackInstance.unloadAsync()</code> and clear <code>OnPlaybackStatusUpdate</code>:</p>
  1548. <pre class="break-out"><code class="language-javascript">loadPlaybackInstance: props => async (shouldPlay) => {
  1549.      props.setState({ isLoading: true });
  1551.      if (props.playbackInstance() !== null) {
  1552.        await props.playbackInstance().unloadAsync();
  1553.        props.playbackInstance().setOnPlaybackStatusUpdate(null);
  1554.        props.setClassVariable({ playbackInstance: null });
  1555.      }
  1556.      const { sound } = await Audio.Sound.create(
  1557.        { uri: props.playingAudio().audioUrl },
  1558.        { shouldPlay, position: 0, duration: 1, progressUpdateIntervalMillis: 50 },
  1559.        props.soundCallback,
  1560.      );
  1562.      props.setClassVariable({ playbackInstance: sound });
  1564.      props.setState({ isLoading: false });
  1565.    },</code></pre>
  1567. <p>Call the handler <code>loadPlaybackInstance(true)</code> by clicking the item in the list. It will automatically load and play the audio.</p>
  1569. <p>Let's add the pause and play functionality (toggle playing) to the audio player. If audio is already playing, you can pause it with the help of <code>playbackInstance.pauseAsync()</code>.  If audio is paused, you can resume playback from the paused point with the help of the <code>playbackInstance.playAsync()</code> method:</p>
  1571. <pre><code class="language-javascript">onTogglePlaying: props => () => {
  1572.      if (props.playbackInstance() !== null) {
  1573.        if (props.isPlaying) {
  1574.          props.playbackInstance().pauseAsync();
  1575.        } else {
  1576.          props.playbackInstance().playAsync();
  1577.        }
  1578.      }
  1579.    },</code></pre>
  1581. <p>When you click on the playing item, it should stop. If you want to stop audio playback and put it into the 0 playing position, you can use the method <code>playbackInstance.stopAsync()</code>:</p>
  1583. <pre><code class="language-javascript">onStop: props => () => {
  1584.      if (props.playbackInstance() !== null) {
  1585.        props.playbackInstance().stopAsync();
  1587.        props.setShowPlayer(false);
  1588.        props.setClassVariable({ playingAudio: null });
  1589.      }
  1590.    },</code></pre>
  1592. <p>The audio player also allows you to rewind the audio with the help of the slider. When you start sliding, the audio playback should be paused with <code>playbackInstance.pauseAsync()</code>.</p>
  1594. <p>After the sliding is complete, you can set the audio playing position with the help of <code>playbackInstance.setPositionAsync(value)</code>, or play back the audio from the set position with <code>playbackInstance.playFromPositionAsync(value)</code>:</p>
  1596. <pre class="break-out"><code class="language-javascript">onCompleteSliding: props => async (value) => {
  1597.      if (props.playbackInstance() !== null) {
  1598.        if (props.shouldPlayAtEndOfSeek) {
  1599.          await props.playbackInstance().playFromPositionAsync(value);
  1600.        } else {
  1601.          await props.playbackInstance().setPositionAsync(value);
  1602.        }
  1603.        props.setClassVariable({ isSeeking: false });
  1604.      }
  1605.    },</code></pre>
  1607. <p>After this, you can pass the props to the components <code>MediaList</code> and <code>AudioPlayer</code> (see the file <code>src/screens/LibraryScreen/LibraryScreenView</code>).</p>
  1609. <figure><a href=""><img src="" width="384" height="680" alt="" /></a></figure>
  1611. <h3>Video Recording Functionality With React Native</h3>
  1613. <p>Let's proceed to video recording.</p>
  1615. <p>We’ll use <code>Expo.Camera</code> for this purpose. <code>Expo.Camera</code> is a React component that renders a preview of the device’s front or back camera. <code>Expo.Camera</code> can also take photos and record videos that are saved to the app’s cache.</p>
  1617. <p>To record video, you need permission for access to the camera and microphone. Let's add the request for camera access as we did with the audio recording (in the file <code>src/index.js</code>):</p>
  1619. <pre><code class="language-javascript">await Permissions.askAsync(Permissions.CAMERA);</code></pre>
  1621. <p>Video recording is available on the “Video Recording” screen. After switching to this screen, the camera will turn on.</p>
  1623. <p>You can change the camera type (front or back) and start video recording. During recording, you can see its general duration and can cancel or stop it. When recording is finished, you will have to type the name of the video, after which it will be saved in the <strong>Redux store</strong>.</p>
  1625. <p>Here is what my video recording UI looks like:</p>
  1637. <figure >
  1638. <img
  1639. srcset=",q_auto/w_400/ 400w,
  1640.,q_auto/w_800/ 800w,
  1641.,q_auto/w_1200/ 1200w,
  1642.,q_auto/w_1600/ 1600w,
  1643.,q_auto/w_2000/ 2000w"
  1644. src=",q_auto/w_400/"
  1645. sizes="100vw"
  1646. alt=""
  1647. />
  1649. <figcaption class="op-vertical-bottom">
  1650. <a href=''>Large preview</a>
  1651. </figcaption>
  1652. </figure>
  1655. <p>Let’s write the video recording logic by using Recompose on the container screen
  1657. <code>src/screens/RecordVideoScreen/RecordVideoScreenContainer</code>.</p>
  1659. <p>You can see the full list of all props in the <code>Expo.Camera</code> component in <a href="">the document</a>.</p>
  1661. <p>In this application, we will use the following props for <code>Expo.Camera</code>.</p>
  1663. <ul>
  1664. <li><code>type</code>: The camera type is set (front or back).</li>
  1665. <li><code>onCameraReady</code>: This callback is invoked when the camera preview is set. You won't be able to start recording if the camera is not ready.</li>
  1666. <li><code>style</code>: This sets the styles for the camera container. In this case, the size is 4:3.</li>
  1667. <li><code>ref</code>: This is used for direct access to the camera component.</li>
  1668. </ul>
  1670. <p>Let's add the variable for saving the type and handler for its changing.</p>
  1672. <pre><code class="language-javascript">cameraType: Camera.Constants.Type.back,
  1673. toggleCameraType: state => () => ({
  1674.      cameraType: state.cameraType === Camera.Constants.Type.front
  1675.        ? Camera.Constants.Type.back
  1676.        : Camera.Constants.Type.front,
  1677.    }),</code></pre>
  1679. <p>Let's add the variable for saving the camera ready state and callback for <code>onCameraReady</code>.</p>
  1681. <pre><code class="language-javascript">isCameraReady: false,
  1683. setCameraReady: () => () => ({ isCameraReady: true }),</code></pre>
  1685. <p>Let's add the variable for saving the camera component reference and setter.</p>
  1687. <pre><code class="language-javascript">cameraRef: null,
  1689. setCameraRef: () => cameraRef => ({ cameraRef }),</code></pre>
  1691. <p>Let's pass these variables and handlers to the camera component.</p>
  1693. <pre><code class="language-javascript">&lt;Camera
  1694.          type={cameraType}
  1695.          onCameraReady={setCameraReady}
  1696.          style={}
  1697.          ref={setCameraRef}
  1698.        /></code></pre>
  1700. <p>Now, when calling <code>toggleCameraType</code> after clicking the button, the camera will switch from the front to the back.</p>
  1702. <p>Currently, we have access to the camera component via the reference, and we can start video recording with the help of <code>cameraRef.recordAsync()</code>.</p>
  1704. <p>The method <code>recordAsync</code> starts recording a video to be saved to the cache directory.</p>
  1706. <h5>Arguments:</h5>
  1708. <p>Options (object) &mdash; a map of options:</p>
  1710. <ul>
  1711. <li><code>quality</code> (VideoQuality): Specify the quality of recorded video. Usage: Camera.Constants.VideoQuality['<value>'], possible values: for 16:9 resolution 2160p, 1080p, 720p, 480p (Android only) and for 4:3 (the size is 640x480). If the chosen quality is not available for the device, choose the highest one.</li>
  1712. <li><code>maxDuration</code> (number): Maximum video duration in seconds.</li>
  1713. <li><code>maxFileSize</code> (number): Maximum video file size in bytes.</li>
  1714. <li><code>mute</code> (boolean): If present, video will be recorded with no sound.</li>
  1715. </ul>
  1717. <p><code>recordAsync</code> returns a promise that resolves to an object containing the video file’s URI property. You will need to save the file’s URI in order to play back the video hereafter. The promise is returned if <code>stopRecording</code> was invoked, one of <code>maxDuration</code> and <code>maxFileSize</code> is reached or the camera preview is stopped.</p>
  1719. <p>Because the ratio set for the camera component sides is 4:3, let's set the same format for the video quality.</p>
  1721. <p>Here is what the handler for starting video recording looks like (see the full code of the container in the repository):</p>
  1723. <pre class="break-out"><code class="language-javascript">onStartRecording: props => async () => {
  1724.      if (props.isCameraReady) {
  1725.        props.setState({ isRecording: true, fileUrl: null });
  1726.        props.setVideoDuration();
  1727.        props.cameraRef.recordAsync({ quality: '4:3' })
  1728.          .then((file) => {
  1729.            props.setState({ fileUrl: file.uri });
  1730.          });
  1731.      }
  1732.    },</code></pre>
  1734. <p>During the video recording, we can’t receive the recording status as we have done for audio. That's why I have created a function to set video duration.</p>
  1736. <p>To stop the video recording, we have to call the following function:</p>
  1738. <pre><code class="language-javascript">stopRecording: props => () => {
  1739.      if (props.isRecording) {
  1740.        props.cameraRef.stopRecording();
  1741.        props.setState({ isRecording: false });
  1742.        clearInterval(props.interval);
  1743.      }
  1744.    },</code></pre>
  1746. <p>Check out the entire process of video recording.</p>
  1748. <figure><a href=""><img src="" width="320" height="584" alt="" /></a></figure>
  1750. <h3>Video Playback Functionality With React Native</h3>
  1752. <p>You can play back the video on the “Library” screen. Video notes are located in the “Video” tab.</p>
  1754. <p>To start the video playback, click the selected item in the list. Then, switch to the playback screen, where you can watch or delete the video.</p>
  1756. <p>The UI for video playback looks like this:</p>
  1768. <figure >
  1769. <img
  1770. srcset=",q_auto/w_400/ 400w,
  1771.,q_auto/w_800/ 800w,
  1772.,q_auto/w_1200/ 1200w,
  1773.,q_auto/w_1600/ 1600w,
  1774.,q_auto/w_2000/ 2000w"
  1775. src=",q_auto/w_400/"
  1776. sizes="100vw"
  1777. alt=""
  1778. />
  1780. <figcaption class="op-vertical-bottom">
  1781. <a href=''>Large preview</a>
  1782. </figcaption>
  1783. </figure>
  1786. <p>To play back the video, use <code>Expo.Video</code>, a component that displays a video inline with the other React Native UI elements in your app.</p>
  1788. <p>The video will be displayed on the separate screen, PlayVideo.</p>
  1790. <p>You can check out all of the <a href="">props for Expo.Video here</a>.</p>
  1792. <p>In our application, the <code>Expo.Video</code> <strong>component</strong> uses native playback controls and looks like this:</p>
  1794. <pre><code class="language-javascript">&lt;Video
  1795.        source={{ uri: videoUrl }}
  1796.        style={}
  1797.        shouldPlay={isPlaying}
  1798.        resizeMode="contain"
  1799.        useNativeControls={isPlaying}
  1800.        onLoad={onLoad}
  1801.        onError={onError}
  1802.      /></code></pre>
  1804. <ul>
  1805. <li><code>source</code><br />
  1807. This is the source of the video data to display. The same forms as for Expo.Audio.Sound are supported.</li>
  1808. <li><code>resizeMode</code><br />
  1810. This is a string describing how the video should be scaled for display in the component view’s bounds. It can be “stretch”, “contain” or “cover”.</li>
  1811. <li><code>shouldPlay</code><br />
  1813. This boolean describes whether the media is supposed to play.</li>
  1814. <li><code>useNativeControls</code><br />
  1816. This boolean, if set to true, displays native playback controls (such as play and pause) within the video component.</li>
  1817. <li><code>onLoad</code><br />
  1819. This function is called once the video has been loaded.</li>
  1820. <li><code>onError</code><br />
  1822. This function is called if loading or playback has encountered a fatal error. The function passes a single error message string as a parameter.</li>
  1823. </ul>
  1825. <p>When the video is uploaded, the play button should be rendered on top of it.</p>
  1827. <p>When you click the play button, the video turns on and the native playback controls are displayed.</p>
  1829. <p>Let’s write the logic of the video using Recompose in the screen container <code>src/screens/PlayVideoScreen/PlayVideoScreenContainer</code>:</p>
  1831. <pre class="break-out"><code class="language-javascript">const defaultState = {
  1832.  isError: false,
  1833.  isLoading: false,
  1834.  isPlaying: false,
  1835. };
  1837. const enhance = compose(
  1838.  paramsToProps('videoUrl'),
  1839.  withStateHandlers({
  1840.    ...defaultState,
  1841.    isLoading: true,
  1842.  }, {
  1843.    onError: () => () => ({ ...defaultState, isError: true }),
  1844.    onLoad: () => () => defaultState,
  1845.   onTogglePlaying: ({ isPlaying }) => () => ({ ...defaultState, isPlaying: !isPlaying }),
  1846.  }),
  1847. );</code></pre>
  1849. <p>As previously mentioned, the <code>Expo.Audio.Sound</code> objects and <code>Expo.Video</code> components share a unified imperative API for media playback. That's why you can create custom controls and use more advanced functionality with the Playback API.</p>
  1851. <p>Check out the video playback process:</p>
  1853. <figure><a href=""><img src="" width="320" height="568" alt="" /></a></figure>
  1855. <p>See the full code for the application in the <a href="">repository</a>.</p>
  1857. <p>You can also install the app on your phone by using <a href="">Expo</a> and check out how it works in practice.</p>
  1859. <h3>Wrapping Up</h3>
  1861. <p>I hope you have enjoyed this article and have enriched your knowledge of React Native. You can use this audio and video recording tutorial to create your own custom-designed media player. You can also scale the functionality and add the ability to save media in the phone’s memory or on a server, synchronize media data between different devices, and share media with others.</p>
  1863. <p>As you can see, there is a wide scope for imagination. If you have any questions about the process of developing an audio or video recording app with React Native, feel free to drop a comment below.</p>
  1865. <div class="signature">
  1866.  <img src="" alt="Smashing Editorial">
  1867.  <span>(da, lf, ra, yk, al, il)</span>
  1868. </div>
  1872.  <div id="sponsors-article-end" data-impression="true" class="c-promo-box c-promo-box--ad c-promo-box--wide sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  1876. </div>
  1880.              </article>
  1881.            </body>
  1882.          </html>
  1883.        ]]></content:encoded>
  1884.      </item>
  1886.      <item>
  1889.          <author>Ricky Onsman</author>
  1891.        <title>Which Podcasts Should Web Designers And Developers Be Listening To?</title>
  1892.        <link></link>
  1893.        <pubDate>Wed, 18 Apr 2018 13:45:00 +0200</pubDate>
  1894.        <guid></guid>
  1895.        <description>We asked the Smashing community what podcasts they listened to, aiming to compile a shortlist of current podcasts for web designers and developers. We had what can only be called a very strong response &amp;mdash; both in number and in passion.
  1896. First, we winnowed out the podcasts that were on a broader theme (e.g. creativity, mentoring, leadership), on a narrower theme (e.g. on one specific WordPress theme) or on a completely different theme (e.</description>
  1897.        <content:encoded><![CDATA[
  1898.          <html>
  1899.            <head>
  1900.              <meta charset="utf-8">
  1901.              <link rel="canonical" href="" />
  1902.              <title>Which Podcasts Should Web Designers And Developers Be Listening To?</title>
  1903.            </head>
  1904.            <body>
  1905.              <article>
  1906.                <header>
  1907.                  <h1>Which Podcasts Should Web Designers And Developers Be Listening To?</h1>
  1910.                    <address>Ricky Onsman</address>
  1912.                  <time datetime="2018-04-18T13:45:00&#43;02:00" class="op-published">2018-04-18T13:45:00+02:00</time>
  1913.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  1914.                </header>
  1915.                <p>We asked the Smashing community what podcasts they listened to, aiming to compile a shortlist of current podcasts for web designers and developers. We had what can only be called a very strong response &mdash; both in number and in passion.</p>
  1917. <p>First, we winnowed out the podcasts that were on a broader theme (e.g. creativity, mentoring, leadership), on a narrower theme (e.g. on one specific WordPress theme) or on a completely different theme (e.g. car maintenance &mdash; I’m sure it was well-intentioned).</p>
  1919. <p>When we filtered out those that had produced no new content in the last three months or more (although then we did have to make some exceptions, as you’ll see), and ordered the rest according to how many times they were nominated, we had a graded shortlist of 55.</p>
  1921. <p>Agreed, that’s not a very short shortlist.</p>
  1923. <p>So, we broke it down into five more reasonably sized shortlists:</p>
  1925. <ul>
  1926. <li><a href="#podcasts-for-web-developers">Podcasts for web developers</a></li>
  1927. <li><a href="#podcasts-for-web-designers">Podcasts for web designers</a></li>
  1928. <li><a href="#podcasts-web-internet-technology">Podcasts on the web, the Internet and technology</a></li>
  1929. <li><a href="#business-podcasts-for-web-professionals">Business podcasts for web professionals</a></li>
  1930. <li><a href="#other-podcasts">Podcasts that don’t have recent episodes (but do have great archives)</a></li>
  1931. </ul>
  1933. <p>Obviously, it’s highly unlikely anyone could &mdash; or would want to &mdash; listen to every episode of every one of these podcasts. Still, we’re pretty sure that any web designer or developer will find a few podcasts in this lot that will suit their particular listening tastes.</p>
  1937. <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  1938.    <div class="container product-panel--book__container">
  1939.      <div class="panel__description panel__description--book">
  1940.    <p>Getting workflow <em>just</em> right ain't an easy task. So are proper estimates. Or alignment among different departments. That's why we've set up <strong>'this-is-how-I-work'-sessions</strong> — with smart cookies sharing what works well for them. A part of the <a href="">Smashing Membership</a>, of course.</p>
  1941.      <a href="" class="btn btn--green btn--large">
  1942.        Explore features&nbsp;→
  1943.      </a>
  1944.      </div>
  1945.      <div class="panel__image panel__image--book">
  1946.        <a href="" class="books__book__image">
  1947.        <div class="books__book__img">
  1948.          <img src="" alt="Smashing TV, with live sessions for professional designers and developers." width="310" height="400">
  1949.        </div>
  1950.      </a>
  1951.      </div>
  1952.    </div>
  1953.  </aside>
  1959. <div class="c-garfield-the-cat">
  1962. <p>A couple of caveats before we begin:</p>
  1964. <ul>
  1965. <li>We don’t claim to be comprehensive. These lists are drawn from suggestions from readers (not all of which were included) plus our own recommendations.</li>
  1966. <li>The descriptions are drawn from reader comments, summaries provided by the podcast provider and our own comments. Podcast running times and frequency are, by and large, approximate. The reality is podcasts tend to vary in length, and rarely stick to their stated schedule.</li>
  1967. <li>We’ve listed each podcast once only, even though several could qualify for more than one list.</li>
  1968. <li>We’ve excluded most videocasts. This is just for listening (videos probably deserve their own article).</li>
  1969. </ul>
  1971. <h3 id="podcasts-for-web-developers">Podcasts For Web Developers</h3>
  1973. <h4><a href="">Syntax</a></h4>
  1975. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Syntax" /></a><a href="">Wes Bos</a> and <a href="">Scott Tolinski</a> dive deep into web development topics, explaining how they work and talking about their own experiences. They cover from JavaScript frameworks like React, to the latest advancements in CSS to simplifying web tooling. 30-70 minutes. Weekly.</p>
  1977. <h4><a href="">Developer Tea</a></h4>
  1979. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Developer Tea" /></a>A podcast for developers designed to fit inside your tea break, a highly-concentrated, short, frequent podcast specifically for developers who like to learn on their tea (and coffee) break. The Spec Network also produces <a href="">Design Details</a>. 10-30 minutes. Every two days.</p>
  1981. <h4><a href="">Web Platform Podcast</a></h4>
  1983. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Web Platform Podcast" /></a>Covers the latest in browser features, standards, and the tools developers use to build for the web of today and beyond. Founded in 2014 by <a href="">Erik Isaksen</a>. Hosts <a href="">Danny</a>, <a href="">Amal</a>, <a href="">Leon</a>, and <a href="">Justin</a> are joined by a special guest to discuss the latest developments. 60 minutes. Weekly.</p>
  1985. <h4><a href="">Devchat Podcasts</a></h4>
  1987. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Devchat Podcasts" /></a>Fourteen podcasts with a range of hosts that each explore developments in a specific aspect of development or programming including Ruby, iOS, Angular, JavaScript, React, Rails, security, conference talks, and freelancing. 30-60 minutes. Weekly.</p>
  1989. <h4><a href="">The Bike Shed</a></h4>
  1991. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Bike Shed" /></a>Hosts <a href="">Derek Prior</a>, <a href="">Sean Griffin</a>, <a href="">Amanda Hill</a> and guests discuss their development experience and challenges with Ruby, Rails, JavaScript, and whatever else is drawing their attention, admiration, or ire at any particular moment. 30-45 minutes. Weekly.</p>
  1993. <h4><a href="">NodeUp</a></h4>
  1995. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="NodeUp" /></a>Hosted by Rod Vagg and a series of occasional co-hosts, this podcast features lengthy discussions with guests and panels about Node.js and Node-related topics. 30-90 minutes. Weekly / Monthly.</p>
  1997. <h4><a href="">.NET Rocks</a></h4>
  1999. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt=".NET Rocks" /></a><a href="!/carlfranklin">Carl Franklin</a> and <a href="!/richcampbell">Richard Campbell</a> host an internet audio talk show for anyone interested in programming on the Microsoft .NET platform, including basic information, tutorials, product developments, guests, tips and tricks. 60 minutes. Twice a week.</p>
  2001. <h4><a href="">Three Devs and a Maybe</a></h4>
  2003. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Three Devs and a Maybe" /></a>Join <a href="">Michael Budd</a>, <a href="">Fraser Hart</a>, <a href="">Lewis Cains</a>, and <a href="">Edd Mann</a> as they discuss software development, frequently joined by a guest on the show’s topic, ranging from daily developer life, PHP, frameworks, testing, good software design and programming languages. 45-60 minutes. Weekly.</p>
  2005. <h4><a href="">Weekly Dev Tips</a></h4>
  2007. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Weekly Dev Tips" /></a>Hosted by experienced software architect, trainer, and entrepreneur <a href="">Steve Smith</a>, Weekly Dev Tips offers a variety of technical and career tips for software developers. Each tip is quick and to the point, describing a problem and one or more ways to solve that problem. 5-10 minutes. Weekly.</p>
  2009. <h4><a href=""></a></h4>
  2011. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="" /></a>Dedicated to the tools, techniques, and technologies used in modern web development. Each episode, <a href="">Andrew Welch</a> and <a href="">Patrick Harrington</a> lead a cadre of hosts discussing the latest hotness, pet peeves, and the frontend development technologies we use. 60-90 minutes. Twice a week.</p>
  2013. <h4><a href="">CodeNewbie</a></h4>
  2015. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="CodeNewbie" /></a>Stories from people on their coding journey. New episodes published every Monday. The most supportive community of programmers and people learning to code. Founded by <a href="">Saron Yitbarek</a>. 30-60 minutes. Weekly.</p>
  2017. <h4><a href="">Front End Happy Hour</a></h4>
  2019. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Front End Happy Hour" /></a>A podcast featuring panels of engineers from <a href="">@Netflix</a>, <a href="">@Evernote</a>, <a href="">@Atlassian</a> and <a href="">@LinkedIn</a> talking over drinks about all things Front End development. 45-60 minutes. Every two weeks.</p>
  2021. <h4><a href="">Under the Radar</a></h4>
  2023. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Under the Radar" /></a>From development and design to marketing and support, Under the Radar is all about independent app development. Hosted by <a href="">David Smith</a> and <a href="">Marco Arment</a>. 30 minutes. Weekly.</p>
  2025. <h4><a href="">Hanselminutes</a></h4>
  2027. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Hanselminutes" /></a><a href="">Scott Hanselman</a> interviews movers and shakers in technology in this commute-time show. From Michio Kaku to Paul Lutus, Ward Cunningham to Kimberly Bryant, Hanselminutes is talk radio guaranteed not to waste your time. 30 minutes. Weekly.</p>
  2029. <h4><a href="">Fixate on Code</a></h4>
  2031. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Fixate on Code" /></a>Since October 2017, <a href="">Larry Botha</a> from South African design agency Fixate has been interviewing well known achievers in web design and development on how to help front end developers write better code. 30 minutes. Weekly.</p>
  2033. <h3 id="podcasts-for-web-designers">Podcasts For Web Designers</h3>
  2035. <h4><a href="">99% Invisible</a></h4>
  2037. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="99% Invisible" /></a>Design is everywhere in our lives, perhaps most importantly in the places where we’ve just stopped noticing. 99% Invisible is a weekly exploration of the process and power of design and architecture, from award winning producer <a href="">Roman Mars</a>. 20-45 minutes. Weekly.</p>
  2039. <h4><a href="">Design Details</a></h4>
  2041. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Design Details" /></a>A show about the people who design our favorite products, hosted by <a href="">Bryn Jackson</a> and <a href="">Brian Lovin</a>. The Spec Network also produces <a href="">Developer Tea</a>.  60-90 minutes. Weekly.</p>
  2043. <h4><a href="">Presentable</a></h4>
  2045. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Presentable" /></a>Host <a href="">Jeffrey Veen</a> brings over two decades of experience as a designer, developer, entrepreneur, and investor as he chats with guests about how we design and build the products that are shaping our digital future  and how design is changing the world. 45-60 minutes. Weekly.</p>
  2047. <h4><a href="">Responsive Web Design</a></h4>
  2049. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Responsive Web Design" /></a>In each episode, <a href="">Karen McGrane</a> and <a href="">Ethan Marcotte</a> (who coined the term “responsive web design”) interview the people who make responsive redesigns happen. 15-30 minutes. Weekly. (<strong>STOP PRESS</strong>: <em>Karen and Ethan issued their final episode of this podcast on 26 March 2018</em>.)</p>
  2051. <h4><a href="">RWD Podcast</a></h4>
  2053. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="RWD Podcast" /></a>Host <a href="">Justin Avery</a> explores new and emerging web technologies, chats with web industry leaders and digs into all aspects of responsive web design. 10-60 minutes. Weekly / Monthly.</p>
  2055. <h4><a href="">UXPodcast</a></h4>
  2057. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="UXPodcast" /></a>Business, technology and people in digital media. Moving the conversation beyond the traditional realm of User Experience. Hosted by <a href="">Per Axbom</a> and <a href="">James Royal-Lawson</a> from Sweden. 30-45 minutes. Every two weeks.</p>
  2059. <h4><a href="">UXpod</a></h4>
  2061. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="UXpod" /></a>A free-ranging set of discussions on matters of interest to people involved in user experience design, website design, and usability in general. <a href="">Gerry Gaffney</a> set this up to provide a platform for discussing topics of interest to UX practitioners. 30-45 minutes. Weekly / Monthly.</p>
  2063. <h4><a href="">UX-radio</a></h4>
  2065. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="UX-radio" /></a>A podcast about IA, UX and Design that features collaborative discussions with industry experts to inspire, educate and share resources with the community. Created by <a href="">Lara Fedoroff</a> and co-hosted with <a href="">Chris Chandler</a>. 30-45 minutes. Weekly / Monthly.</p>
  2067. <h4><a href="">User Defenders</a></h4>
  2069. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="User Defenders" /></a>Host <a href="">Jason Ogle</a> aims to highlight inspirational UX Designers leading the way in their craft, by diving deeper into who they are, and what makes them tick/successful, in order to inspire and equip those aspiring to do the same. 30-90 minutes. Weekly.</p>
  2071. <h4><a href="">The Drunken UX Podcast</a></h4>
  2073. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Drunken UX Podcast" /></a>Our hosts <a href="">Michael Fienen</a> and <a href="">Aaron Hill</a> look at issues facing websites and developers that impact the way we all use the web. “In the process, we’ll drink drinks, share thoughts, and hopefully make you laugh a little.” 60 minutes. Twice a week.</p>
  2075. <h4><a href="">UI Breakfast Podcast</a></h4>
  2077. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="UI Breakfast Podcast" /></a>Join <a href="">Jane Portman</a> for conversations about UI/UX design, products, marketing, and so much more, with awesome guests who are industry experts ready to share actionable knowledge. 30-60 minutes. Weekly.</p>
  2079. <h4><a href="">Efficiently Effective</a></h4>
  2081. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Efficiently Effective" /></a><a href="">Saskia Videler</a> keeps us up to date with what’s happening in the field of UX and content strategy, aiming to help content experts, UX professionals and others create better digital experiences.  25-40 minutes. Monthly.</p>
  2083. <h4><a href="">The Honest Designers Show</a></h4>
  2085. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Honest Designers Show" /></a>Hosts Tom Ross, Ian Barnard, Dustin Lee and Lisa Glanz have each found success in their creative fields and are here to give struggling designers a completely honest, under the hood look at what it takes to flourish in the modern world. 30-60 minutes. Weekly.</p>
  2087. <h4><a href="">Design Life</a></h4>
  2089. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Design Life" /></a>A podcast about design and side projects for motivated creators. Femke van Schoonhoven and Charli Prangley (serial side project addicts) saw a gap in the market for a conversational show hosted by two females about design and issues young creatives face. 30-45 minutes. Weekly.</p>
  2091. <h4><a href="">Layout FM</a></h4>
  2093. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Layout FM" /></a>A weekly podcast about design, technology, programming and everything else hosted by <a href="">Kevin Clark</a> and <a href="">Rafael Conde</a>. 60-90 minutes. Weekly.</p>
  2095. <h4><a href="">Bread Time</a></h4>
  2097. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Bread Time" /></a><a href="">Gabriel Valdivia</a> and <a href="">Charlie Deets</a> host this micro-podcast about design and technology, the impact of each on the other, and the impact of them both on all of us. 10-30 minutes. Weekly.</p>
  2099. <h4><a href="">The Deeply Graphic DesignCast</a></h4>
  2101. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Deeply Graphic DesignCast" /></a>Every episode covers a new graphic design-related topic, and a few relevant tangents along the way. <a href="">Wes McDowell</a> and his co-hosts also answer listener-submitted questions in every episode. 60 minutes. Every two weeks.</p>
  2103. <h3 id="podcasts-web-internet-technology">Podcasts On The Web, The Internet, And Technology</h3>
  2105. <h4><a href="">The Big Web Show</a></h4>
  2107. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Big Web Show" /></a>Veteran web designer and industry standards champion <a href="">Jeffrey Zeldman</a> is joined by special guests to address topics like web publishing, art direction, content strategy, typography, web technology, and more. 60 minutes. Weekly.</p>
  2109. <h4><a href="">ShopTalk</a></h4>
  2111. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="ShopTalk" /></a>A podcast about front end web design, development and UX. Each week Chris Coyier and Dave Rupert are joined by a special guest to talk shop and answer listener submitted questions. 60 minutes. Weekly.</p>
  2113. <h4><a href="">Boagworld</a></h4>
  2115. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Boagworld" /></a><a href="">Paul Boag</a> and <a href="">Marcus Lillington</a> are joined by a variety of guests to discuss a range of web design related topics. Fun, informative and quintessentially British, with content for designers, developers and website owners, something for everybody. 60 minutes. Weekly.</p>
  2117. <h4><a href="">The Changelog</a></h4>
  2119. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Changelog" /></a>Conversations with the hackers, leaders, and innovators of open source. Hosts <a href="">Adam Stacoviak</a> and <a href="">Jerod Santo</a> do in-depth interviews with the best and brightest software engineers, hackers, leaders, and innovators. 60-90 minutes. Weekly.</p>
  2121. <h4><a href="">Back to Front Show</a></h4>
  2123. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Back to Front Show" /></a>Topics under discussion hosted by <a href="">Keir Whitaker</a> and <a href="">Kieran Masterton</a> include remote working, working in the web industry, productivity, hipster beards and much more. Released irregularly but always produced with passion. 30-60 minutes. Weekly / Monthly.</p>
  2125. <h4><a href="">The Next Billion Seconds</a></h4>
  2127. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Next Billion Seconds" /></a>The coming “next billion seconds” are the most important in human history, as technology transforms the way we live and work. <a href="">Mark Pesce</a> talks to some of the brightest minds shaping our world. 30-60 minutes. Every two weeks.</p>
  2129. <h4><a href="">Toolsday</a></h4>
  2131. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Toolsday" /></a>Hosted by <a href="">Una Kravets</a> and <a href="">Chris Dhanaraj</a>, Toolsday is about the latest in tech tools, tips, and tricks. 30 minutes. Weekly.</p>
  2133. <h4><a href="">Reply All</a></h4>
  2135. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Reply All" /></a>A podcast about the internet, often delving deeper into modern life. Hosted by <a href="">PJ Vogt</a> and <a href="">Alex Goldman</a> from US narrative podcasting company Gimlet Media. 30-60 minutes. Weekly.</p>
  2137. <h4><a href="">CTRL+CLICK CAST</a></h4>
  2139. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="CTRL+CLICK CAST" /></a>Diverse voices from industry leaders and innovators, who tackle everything from design, code and CMS, to culture and business challenges. Focused, topical discussions hosted by <a href="">Lea Alcantara</a> and <a href="">Emily Lewis</a>. 60 minutes. Every two weeks.</p>
  2141. <h4><a href="">Modern Web</a></h4>
  2143. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Modern Web" /></a>Explores next generation frameworks, standards, and techniques. Hosted by <a href="">Tracy Lee</a>. Topics include EmberJS, ReactJS, AngularJS, ES2015, RxJS, functional reactive programming. 60 minutes. Weekly.</p>
  2145. <h4><a href="">Relative Paths</a></h4>
  2147. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Relative Paths" /></a>A UK based podcast on “web development and stuff like that” for web industry types. Hosted by <a href="">Mark Phoenix</a> and <a href="">Ben Hutchings</a>. 60 minutes. Every two weeks.</p>
  2150.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  2154. <h3 id="business-podcasts-for-web-professionals">Business Podcasts For Web Professionals</h3>
  2156. <h4><a href="">The Businessology Show</a></h4>
  2158. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Businessology Show" /></a>The Businessology Show is a podcast about the business of design and the design of business, hosted by CPA/coach <a href="">Jason Blumer</a>. 30 minutes. Monthly.</p>
  2160. <h4><a href="">CodePen Radio</a></h4>
  2162. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="CodePen Radio" /></a><a href="">Chris Coyier</a>, <a href="">Alex Vazquez</a>, and <a href="">Tim Sabat</a>, the co-founders of CodePen, talk about the ins and outs of running a small web software business. The good, the bad, and the ugly. 30 minutes. Weekly.</p>
  2164. <h4><a href="">BizCraft</a></h4>
  2166. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="BizCraft" /></a>Podcast about the business side of web design, recorded live almost every two weeks. Your hosts are <a href="">Carl Smith</a> of nGen Works and <a href="">Gene Crawford</a> of UnmatchedStyle. 45-60 minutes. Every two weeks.</p>
  2168. <h3 id="other-podcasts">Podcasts That Don’t Have Recent Episodes (But Do Have Great Archives)</h3>
  2170. <h4><a href="">Design Review Podcast</a></h4>
  2172. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Design Review Podcast" /></a>No chit-chat, just focused in-depth discussions about design topics that matter. <a href="">Jonathan Shariat</a> and <a href="">Chris Liu</a> are your hosts and bring to the table passion and years of experience. 30-60 minutes. Every two weeks. Last episode 26 November 2017.</p>
  2174. <h4><a href="">Style Guide Podcast</a></h4>
  2176. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Style Guide Podcast" /></a>A small batch series of interviews (20 in total) on Style Guides, hosted by <a href="">Anna Debenham</a> and <a href="">Brad Frost</a>, with high profile designer guests. 45 minutes. Weekly. Last episode 19 November 2017.</p>
  2178. <h4><a href="">True North</a></h4>
  2180. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="True North" /></a>Looks to uncover the stories of everyday people creating and designing, and highlight the research and testing that drives innovation. Produced by Loop11. 15-60 minutes. Every two weeks. Last episode 18 October 2017</p>
  2182. <h4><a href=""> Master Feed</a></h4>
  2184. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt=" Master Feed" /></a>Get all episodes from every show on the UIE network in this master feed: <em>UIE Book Corner</em> (with <a href="">Adam Churchill</a>) and <em>The UIE Podcast</em> (with <a href="">Jared Spool</a>) plus some archived older shows. 15-60 minutes. Weekly. Last episode 4 October 2017.</p>
  2186. <h4><a href="">Let’s Make Mistakes</a></h4>
  2188. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Let’s Make Mistakes" /></a>A podcast about design with your hosts, <a href="">Mike Monteiro</a>, <a href="">Liam Campbell</a>, <a href="">Steph Monette</a>, and <a href="">Seven Morris</a>, plus a range of guests who discuss good design, business and ethics. 45-60 minutes. Weekly / Monthly. Last episode 3 August 2017.</p>
  2190. <h4><a href="">Motion and Meaning</a></h4>
  2192. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Motion and Meaning" /></a>A podcast about motion for digital designers brought to you by <a href="">Val Head</a> and <a href="">Cennydd Bowles</a>, covering everything from the basic principles of animation through to advanced tools and techniques. 30 minutes. Monthly. Last episode 13 December 2016.</p>
  2194. <h4><a href="">The Web Ahead</a></h4>
  2196. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="The Web Ahead" /></a>Conversations with world experts on changing technologies and future of the web. The Web Ahead is your shortcut to keeping up. Hosted by <a href="">Jen Simmons</a>. 60-100 minutes. Monthly. Last episode 30 June 2016.</p>
  2198. <h4><a href="">Unfinished Business</a></h4>
  2200. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Unfinished Business" /></a>UK designer <a href="">Andy Clarke</a> and guests have plenty to talk about, mostly on and around web design, creative work and modern life. 60-90 minutes. Monthly. Last episode 28 June 2016. (<strong>STOP PRESS</strong>: <em>A new episode was issued on 20 March 2018. Looks like it’s back in action.</em>)</p>
  2202. <h4><a href="">Dollars to Donuts</a></h4>
  2204. <p><a href=""><img style="float: right; padding: 1em;" src="" width="180" height="180" alt="Dollars to Donuts" /></a>A podcast where <a href="">Steve Portigal</a> talks with the people who lead user research in their organizations. 50-75 minutes. Irregular. Last episode 10 May 2016.</p>
  2206. <h3>Any Other Good Ones Missing?</h3>
  2208. <p>As we noted, there are probably many other good podcasts out there for web designers and developers. If we’ve missed your favorite, let us know about it in the comments, or in the original threads on <a href="">Twitter</a> or <a href="">Facebook</a>.</p>
  2213. <div class="signature">
  2214.  <img src="" alt="Smashing Editorial">
  2215.  <span>(vf, ra, il)</span>
  2216. </div>
  2219. </div>
  2223.              </article>
  2224.            </body>
  2225.          </html>
  2226.        ]]></content:encoded>
  2227.      </item>
  2229.      <item>
  2232.          <author>Tim Noetzel</author>
  2234.        <title>How To Improve Your Design Process With Data-Based Personas</title>
  2235.        <link></link>
  2236.        <pubDate>Tue, 17 Apr 2018 13:40:40 +0200</pubDate>
  2237.        <guid></guid>
  2238.        <description>Most design and product teams have some type of persona document. Theoretically, personas help us better understand our users and meet their needs. The idea is that codifying what we’ve learned about distinct groups of users helps us make better design decisions. Referring to these documents ourselves and sharing them with non-design team members and external stakeholders should ultimately lead to a user experience more closely aligned with what real users actually need.</description>
  2239.        <content:encoded><![CDATA[
  2240.          <html>
  2241.            <head>
  2242.              <meta charset="utf-8">
  2243.              <link rel="canonical" href="" />
  2244.              <title>How To Improve Your Design Process With Data-Based Personas</title>
  2245.            </head>
  2246.            <body>
  2247.              <article>
  2248.                <header>
  2249.                  <h1>How To Improve Your Design Process With Data-Based Personas</h1>
  2252.                    <address>Tim Noetzel</address>
  2254.                  <time datetime="2018-04-17T13:40:40&#43;02:00" class="op-published">2018-04-17T13:40:40+02:00</time>
  2255.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  2256.                </header>
  2257.                <p>Most design and product teams have some type of persona document. Theoretically, personas help us better understand our users and meet their needs. The idea is that codifying what we’ve learned about distinct groups of users helps us make better design decisions. Referring to these documents ourselves and sharing them with non-design team members and external stakeholders should ultimately lead to a user experience more closely aligned with what real users actually need.</p>
  2259. <p>In reality, personas rarely prove equal to these expectations. On many teams, persona documents sit abandoned on hard drives, collecting digital dust while designers continue to create products based primarily on whim and intuition.</p>
  2261. <p>In contrast, well-researched personas serve as a proxy for the user. They help us check our work and ensure that we’re building things users really need.</p>
  2263. <p>In fact, the best personas don’t just describe users; they actually help designers predict their behavior. In her article on persona creation, Laura Klein <a href="">describes it perfectly</a>:</p>
  2265. <blockquote>“If you can create a predictive persona, it means you truly know not just what your users are like, but the exact factors that make it likely that a person will become and remain a happy customer.”</blockquote>
  2267. <p>In other words, <em>useful</em> personas actually help design teams make better decisions because they can predict with some accuracy how users will respond to potential product changes.</p>
  2269. <p>Obviously, for personas to facilitate these types of predictions, they need to be based on more than intuition and anecdotes. They need to be data-driven.</p>
  2271. <p>So, what do data-driven personas look like, and how do you make one?</p>
  2275.  <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber" data-remove="true">
  2276.    <div class="container product-panel--book__container">
  2277.      <div class="panel__description panel__description--book">
  2278.        <p>
  2279.          Is your pattern library up to date today? <em>Alla Kholmatova</em> has just finished a fully fledged book on <strong>Design Systems</strong> and how to get them right. With common traps, gotchas and the lessons she learned. Hardcover, eBook. <em>Just sayin'.</em>
  2280.        </p>
  2281.        <a href="">
  2282.          <button class="btn btn--green btn--large">
  2283.            Table of Contents&nbsp;&rarr;
  2284.          </button>
  2285.        </a>
  2286.      </div>
  2287.      <div class="panel__image panel__image--book">
  2288.        <a href="" class="books__book__image">
  2289.        <div class="books__book__img">
  2290.          <img src="">
  2291.        </div>
  2292.      </a>
  2293.      </div>
  2294.    </div>
  2295.  </aside>
  2315. <div class="c-garfield-the-cat">
  2318. <h3>Start With What You Think You Know</h3>
  2320. <p>The first step in creating data-driven personas is similar to the typical persona creation process. Write down your team’s hypotheses about what the key user groups are and what’s important to each group.</p>
  2322. <p>If your team is like most, some members will disagree with others about which groups are important, the particular makeup and qualities of each persona, and so on. This type of disagreement is healthy, but unlike the usual persona creation process you may be used to, you’re not going to get bogged down here.</p>
  2324. <p>Instead of debating the merits of each persona (and the various facets and permutations thereof), the important thing is to be specific about the different hypotheses you and your team have and write them down. You’re going to validate these hypotheses later, so it’s okay if your team disagrees at this stage. You may choose to focus on a few particular personas, but make sure to keep a backlog of other ideas as well.</p>
  2336. <figure >
  2337. <img
  2338. srcset=",q_auto/w_400/ 400w,
  2339.,q_auto/w_800/ 800w,
  2340.,q_auto/w_1200/ 1200w,
  2341.,q_auto/w_1600/ 1600w,
  2342.,q_auto/w_2000/ 2000w"
  2343. src=",q_auto/w_400/"
  2344. sizes="100vw"
  2345. alt="Hypothetical Personas"
  2346. />
  2348. <figcaption class="op-vertical-bottom">
  2349. First, start by recording all the hypotheses you have about key personas. You’ll refine these through user research in the next step. (<a href=''>Large preview</a>)
  2350. </figcaption>
  2351. </figure>
  2354. <p>I recommend aiming for a short, 1&ndash;2 sentence description of each hypothetical persona that details who they are, what root problem they hope to solve by using your product, and any other pertinent details.</p>
  2356. <p>You can use the traditional <a href="">user stories framework</a> for this. If you were creating hypothetical personas for Craigslist, one of these statements might read:</p>
  2358. <blockquote>“As a recent college grad, I want to find cheap furniture so I can furnish my new apartment.”</blockquote>
  2360. <p>Another might say:</p>
  2362. <blockquote>“As a homeowner with an extra bedroom, I want to find a responsible tenant to rent this space to so I can earn some extra income.”</blockquote>
  2364. <p>If you have existing data &mdash; things like user feedback emails, NPS scores, user interview notes, or analytics data &mdash; be sure to go over them and include relevant data points in your notes along with your user stories.</p>
  2366. <h3>Validate And Refine</h3>
  2368. <p>The next step is to validate and refine these hypotheses with user interviews. For each of your hypothetical personas, you’ll want to start by interviewing 5 to 10 people who fit that group.</p>
  2370. <p>You have three key goals for these interviews. For each group, you need to:</p>
  2372. <ol>
  2373. <li>Understand the context in which they need to solve the problem.</li>
  2374. <li>Confirm that members of the persona group agree that the problem you recorded is an urgent and painful one that they struggle to solve now.</li>
  2375. <li>Identify key predictors of whether a member of this persona is likely to become and remain an active user.</li>
  2376. </ol>
  2378. <p>The approach you take to these interviews may vary, but I recommend a hybrid approach between a traditional user interview, which is very non-leading, and a <a href="">Lean Problem</a> interview, which is deliberately leading.</p>
  2380. <p>Start with the traditional user interview approach and ask <a href="">behavior-based, non-leading questions</a>. In the Craigslist example, we might ask the recent college grad something like:</p>
  2382. <blockquote>“Tell me about the last time you purchased furniture. What did you buy? Where did you buy it?”</blockquote>
  2384. <p>These types of questions are great for establishing whether the interviewee recently experienced the problem in question, how they solved it, and whether they’re dissatisfied with their current solution.</p>
  2386. <p>Once you’ve finished asking these types of questions, move on to the <em>Lean Problem</em> portion of the interview. In this section, you want to tell a story about a time when you experienced the problem &mdash; establishing the various issues you struggled with and why it was frustrating &mdash; and see how they respond.</p>
  2388. <p>You might say something like this:</p>
  2390. <blockquote>“When I graduated college, I had to get new furniture because I wasn’t living in the dorm anymore. I spent forever looking at furniture stores, but they were all either ridiculously expensive or big-box stores with super-cheap furniture I knew would break in a few weeks. I really wanted to find good furniture at a reasonable price, but I couldn’t find anything and I eventually just bought the cheap stuff. It inevitably broke, and I had to spend even more money, which I couldn’t really afford. Does any of that resonate with you?”</blockquote>
  2393.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  2397. <p>What you’re looking for here is emphatic agreement. If your interviewee says "yes, that resonates" but doesn’t get much more excited than they were during the rest of the interview, the problem probably wasn’t that painful for them.</p>
  2409. <figure >
  2410. <img
  2411. srcset=",q_auto/w_400/ 400w,
  2412.,q_auto/w_800/ 800w,
  2413.,q_auto/w_1200/ 1200w,
  2414.,q_auto/w_1600/ 1600w,
  2415.,q_auto/w_2000/ 2000w"
  2416. src=",q_auto/w_400/"
  2417. sizes="100vw"
  2418. alt="Data-Driven Personas Interview Format"
  2419. />
  2421. <figcaption class="op-vertical-bottom">
  2422. You can validate or invalidate your persona hypotheses with a series of quick, 30-minute interviews. (<a href=''>Large preview</a>)
  2423. </figcaption>
  2424. </figure>
  2427. <p>On the other hand, if they get excited, empathize with your story, or give their own anecdote about the problem, you know you’ve found a problem they really care about and need to be solved.</p>
  2429. <p>Finally, make sure to ask any demographic questions you didn’t cover earlier, especially those around key attributes you think might be significant predictors of whether somebody will become and remain a user. For example, you might think that recent college grads who get high-paying jobs aren’t likely to become users because they can afford to buy furniture at retail; if so, be sure to ask about income.</p>
  2431. <p>You’re looking for predictable patterns. If you bring in 5 members of your persona and 4 of them have the problem you’re trying to solve and desperately want a solution, you’ve probably identified a key persona.</p>
  2433. <p>On the other hand, if you’re getting inconsistent results, you likely need to refine your hypothetical persona and repeat this process, using what you learn in your interviews to form new hypotheses to test. If you can’t consistently find users who have the problem you want to solve, it’s going to be nearly impossible to get millions of them to use your product. So don’t skimp on this step.</p>
  2435. <h3>Create Your Personas</h3>
  2437. <p>The penultimate step in this process is creating the actual personas themselves. This is where things get interesting. Unlike traditional personas, which are typically static, your data-driven personas will be living, breathing documents.</p>
  2439. <p>The goal here is to combine the lessons you learned in the previous step &mdash; about who the user is and what they need &mdash; with data that shows how well the latest iteration of your product is serving their needs.</p>
  2441. <p>At my company <a href="">Swish</a>, each one of our personas includes two sections with the following data:</p>
  2443. <table class="tablesaw break-out" data-tablesaw-mode="swipe" data-tablesaw-minimap>
  2444.    <thead>
  2445.        <tr>
  2446.            <th data-tablesaw-priority="persist">Predictive User Data</th>
  2447.            <th>Product Performance Data</th>
  2448.        </tr>
  2449.    </thead>
  2450.    <tbody>
  2451.        <tr>
  2452.            <td>Description of the user including predictive demographics.</td>
  2453.            <td>The percentage of our <em>current</em> user base the persona represents.</td>
  2454.        </tr>
  2455.        <tr>
  2456.            <td>Quotes from at least 3 actual users that describe the <a href="">jobs-to-be-done</a>.</td>
  2457.            <td>Latest <a href="">activation, retention, and referral rates</a> for the persona.</td>
  2458.        </tr>
  2459.        <tr>
  2460.            <td>The percentage of the <em>potential</em> user base the persona represents.</td>
  2461.            <td>Current NPS Score for the persona.</td>
  2462.        </tr>
  2463.    </tbody>
  2464. </table>
  2466. <p>If you’re looking for more ideas for data to include, check out <a href="">Coryndon Luxmoore’s presentation</a> on how his team created data-driven personas at Buildium.</p>
  2468. <p>It may take some time for your team to produce all this information, but it’s okay to start with what you have and improve the personas over time. Your personas won’t be sitting on a shelf. Every time you release a new feature or change an existing one, you should measure the results and update your personas accordingly.</p>
  2470. <h3>Integrate Your Personas Into Your Workflow</h3>
  2472. <p>Now that you’ve created your personas, it’s time to actually use them in your day-to-day design process. Here are 4 opportunities to use your new data-driven personas: </p>
  2474. <ol>
  2475. <li><strong>At Standups</strong><br />At Swish, our standups are a bit different. We start these meetings by reviewing the activation, retention, and referral metrics for each persona. This ensures that &mdash; as we discuss yesterday’s progress and today’s obstacles &mdash; we remain focused on what really matters: how well we’re serving our users.</li>
  2476. <li><strong>During Prioritization</strong><br />Your data-driven personas are a great way to keep team members honest as you discuss new features and changes. When you know how much of your user base the persona represents and how well you’re serving them, it quickly becomes obvious whether a potential feature could actually make a difference. Suddenly deciding what to work on won’t require hours of debate or horse-trading.</li>
  2477. <li><strong>At Design Reviews</strong><br />Your data-driven personas are a great way to keep team members honest as you discuss new designs. When team members can creditably represent users with actual quotes from user interviews, their feedback quickly becomes less subjective and more useful.</li>
  2478. <li><strong>When Onboarding New Team Members</strong><br />New hires inevitably bring a host of implicit biases and assumptions about the user with them when they start. By including your data-driven personas in their onboarding documents, you can get new team members up to speed much more quickly and ensure they understand the hard-earned lessons your team learned along the way.</li>
  2479. </ol>
  2481. <h3>Keeping Your Personas Up To Date</h3>
  2483. <p>It’s vitally important to keep your personas up-to-date so your team members can continue to rely on them to guide their design thinking.</p>
  2485. <p>As your product improves, it’s simple to update NPS scores and performance data. I recommend doing this monthly at a minimum; if you’re working on an early-stage, rapidly-changing product, you’ll get better mileage by updating these stats weekly instead.</p>
  2487. <p>It’s also important to check in with members of your personas periodically to make sure your predictive data stays relevant. As your product evolves and the competitive landscape changes, your users’ views about their problems will change as well. If your growth starts to plateau, another round of interviews may help to unlock insights you didn’t find the first time. Even if everything is going well, try to check in with members of your personas &mdash; both current users of your product and some non-users &mdash; every 6 to 12 months.</p>
  2489. <h3>Wrapping Up</h3>
  2491. <p>Building data-driven personas is a challenging project that takes time and dedication. You won’t uncover the insights you need or build the conviction necessary to unify your team with a week-long throwaway project.</p>
  2493. <p>But if you put in the time and effort necessary, the results will speak for themselves. Having the type of clarity that data-driven personas provide makes it far easier to iterate quickly, improve your user experience, and build a product your users love.</p>
  2495. <h4>Further Reading</h4>
  2497. <p>If you’re interested in learning more, I highly recommend checking out the linked articles above, as well as the following resources:</p>
  2499. <ul>
  2500. <li>“<a href="">Running Lean: How to Iterate from Plan A to a Plan That Works</a>,” Ash Maurya</li>
  2501. <li>“<a href="">How to Build Robust User Personas in Under a Month</a>,” Tony Zambito, ConversionXL</li>
  2502. <li>“<a href="">Resurrecting Dead Personas</a>,” Meg Dickey-Kurdziolek, A List Apart</li>
  2503. <li>“<a href="">A Closer Look At Personas: A Guide To Developing The Right Ones</a>,” Shlomo Goltz, Smashing Magazine.</li>
  2504. </ul>
  2506. <div class="signature">
  2507.  <img src="" alt="Smashing Editorial">
  2508.  <span>(rb, ra, yk, il)</span>
  2509. </div>
  2513.  <div id="sponsors-article-end" data-impression="true" class="c-promo-box c-promo-box--ad c-promo-box--wide sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  2517. </div>
  2521.              </article>
  2522.            </body>
  2523.          </html>
  2524.        ]]></content:encoded>
  2525.      </item>
  2527.      <item>
  2530.          <author>Rachel Andrew</author>
  2532.        <title>Best Practices With CSS Grid Layout</title>
  2533.        <link></link>
  2534.        <pubDate>Mon, 16 Apr 2018 13:35:19 +0200</pubDate>
  2535.        <guid></guid>
  2536.        <description>An increasingly common question &amp;mdash; now that people are using CSS Grid Layout in production &amp;mdash; seems to be “What are the best practices?” The short answer to this question is to use the layout method as defined in the specification. The particular parts of the spec you choose to use, and indeed how you combine Grid with other layout methods such as Flexbox, is down to what works for the patterns you are trying to build and how you and your team want to work.</description>
  2537.        <content:encoded><![CDATA[
  2538.          <html>
  2539.            <head>
  2540.              <meta charset="utf-8">
  2541.              <link rel="canonical" href="" />
  2542.              <title>Best Practices With CSS Grid Layout</title>
  2543.            </head>
  2544.            <body>
  2545.              <article>
  2546.                <header>
  2547.                  <h1>Best Practices With CSS Grid Layout</h1>
  2550.                    <address>Rachel Andrew</address>
  2552.                  <time datetime="2018-04-16T13:35:19&#43;02:00" class="op-published">2018-04-16T13:35:19+02:00</time>
  2553.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  2554.                </header>
  2557. <p>An increasingly common question &mdash; now that people are using CSS Grid Layout in production &mdash; seems to be “What are the best practices?” The short answer to this question is to use the layout method as defined in the specification. The particular parts of the spec you choose to use, and indeed how you combine Grid with other layout methods such as Flexbox, is down to what works for the patterns you are trying to build and how you and your team want to work.</p>
  2559. <p>Looking deeper, I think perhaps this request for “best practices” perhaps indicates a lack of confidence in using a layout method that is very different from what came before. Perhaps a concern that we are using Grid for things it wasn’t designed for, or not using Grid when we should be. Maybe it comes down to worries about supporting older browsers, or in how Grid fits into our development workflow.</p>
  2561. <p>In this article, I’m going to try and cover some of the things that either could be described as best practices, and some things that you probably don’t need to worry about.</p>
  2563. <h3 id="the-survey">The Survey</h3>
  2565. <p>To help inform this article, I wanted to find out how other people were using Grid Layout in production, what were the challenges they faced, what did they really enjoy about it? Were there common questions, problems or methods being used. To find out, I put together a quick survey, asking questions about how people were using Grid Layout, and in particular, what they most liked and what they found challenging.</p>
  2567. <p>In the article that follows, I’ll be referencing and directly quoting some of those responses. I’ll also be linking to lots of other resources, where you can find out more about the techniques described. As it turned out, there was far more than one article worth of interesting things to unpack in the survey responses. I’ll address some of the other things that came up in a future post.</p>
  2571. <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  2572.    <div class="container product-panel--book__container">
  2573.      <div class="panel__description panel__description--book">
  2574.    <p>Nope, we can't do any magic tricks, but we have articles, <a href="">books</a> and <a href="">webinars</a> featuring techniques we all can use to improve our work. <a href="">Smashing Members</a> get a seasoned selection of magic front-end tricks — e.g. <strong>live designing sessions</strong> and perf audits, too. <em>Just sayin'</em>! ;-)</p>
  2576.      <a href="" class="btn btn--green btn--large">
  2577.        Explore Smashing Wizardry&nbsp;→
  2578.      </a>
  2579.      </div>
  2580.      <div class="panel__image panel__image--book">
  2581.        <a href="" class="books__book__image">
  2582.        <div class="books__book__img">
  2583.          <img src="" alt="Smashing Cat, just preparing to do some magic stuff." width="310" height="400">
  2584.        </div>
  2585.      </a>
  2586.      </div>
  2587.    </div>
  2588.  </aside>
  2594. <div class="c-garfield-the-cat">
  2597. <h3 id="accessibility">Accessibility</h3>
  2599. <p>If there is any part of the Grid specification that you need to take care when using, it is when using anything that could cause content re-ordering:</p>
  2601. <blockquote>“Authors must use order and the grid-placement properties only for visual, not logical, reordering of content. Style sheets that use these features to perform logical reordering are non-conforming.”<br /><br />&mdash; <a href="">Grid Specification: Re-ordering and Accessibility</a></blockquote>
  2603. <p>This is not unique to Grid, however, the ability to rearrange content so easily in two dimensions makes it a bigger problem for Grid. However, if using any method that allows content re-ordering &mdash; be that Grid, Flexbox or even absolute positioning &mdash; you need to take care not to disconnect the visual experience from how the content is structured in the document. Screen readers (and people navigating around the document using a keyboard only) are going to be following the order of items in the source.</p>
  2605. <p>The places where you need to be particularly careful are when using <code>flex-direction</code> to reverse the order in Flexbox; the <code>order</code> property in Flexbox or Grid; any placement of Grid items using any method, if it moves items out of the logical order in the document; and using the dense packing mode of <code>grid-auto-flow</code>.</p>
  2607. <p>For more information on this issue, see the following resources:</p>
  2609. <ul>
  2610. <li><a href="">Grid Layout and Accessibility - MDN</a></li>
  2611. <li><a href="">Flexbox and the keyboard navigation disconnect</a></li>
  2612. </ul>
  2614. <h3 id="which-grid-layout-methods-should-i-use">Which Grid Layout Methods Should I Use?</h3>
  2616. <blockquote>”With so much choice in Grid, it was a challenge to stick to a consistent way of writing it (e.g. naming grid lines or not, defining grid-template-areas, fallbacks, media queries) so that it would be maintainable by the whole team.”<br /><br />&mdash; <a href="">Michelle Barker</a></blockquote>
  2618. <p>When you first take a look at Grid, it might seem overwhelming with so many different ways of creating a layout. Ultimately, however, it all comes down to things being positioned from one line of the grid to another. You have choices based on the of layout you are trying to achieve, as well as what works well for your team and the site you are building.</p>
  2620. <p>There is no right or wrong way. Below, I will pick up on some of the common themes of confusion. I&rsquo;ve also already covered many other potential areas of confusion in a previous article “<a href="">Grid Gotchas and Stumbling Blocks</a>.”</p>
  2622. <h4 id="should-i-use-an-implicit-or-explicit-grid">Should I Use An Implicit Or Explicit Grid?</h4>
  2624. <p>The grid you define with <code>grid-template-columns</code> and <code>grid-template-rows</code> is known as the Explicit Grid. The Explicit Grid enables the naming of lines on the Grid and also gives you the ability to target the end line of the grid with <code>-1</code>. You’ll choose an Explicit Grid to do either of these things and in general when you have a layout all designed and know exactly where your grid lines should go and the size of the tracks.</p>
  2626. <p>I use the Implicit Grid most often for row tracks. I want to define the columns but then rows will just be auto-sized and grow to contain the content. You can control the Implicit Grid to some extent with <code>grid-auto-columns</code> and <code>grid-auto-rows</code>, however, you have less control than if you are defining everything.</p>
  2628. <p>You need to decide whether you know exactly how much content you have and therefore the number of rows and columns &mdash; in which case you can create an Explicit Grid. If you do not know how much content you have, but simply want rows or columns created to hold whatever there is, you will use the Implicit Grid.</p>
  2630. <p>Nevertheless, it&rsquo;s possible to combine the two. In the below CSS, I have defined three columns in the Explicit Grid and three rows, so the first three rows of content will be the following:</p>
  2632. <ul>
  2633. <li>A track of at least 200px in height, but expanding to take content taller,</li>
  2634. <li>A track fixed at 400px in height,</li>
  2635. <li>A track of at least 300px in height (but expands).</li>
  2636. </ul>
  2638. <p>Any further content will go into a row created in the Implicit Grid, and I am using the <code>grid-auto-rows</code> property to make those tracks at least 300px tall, expanding to <code>auto</code>.</p>
  2640. <pre><code class="language-css">.grid {  
  2641.  display: grid;  
  2642.  grid-template-columns: 1fr 3fr 1fr;  
  2643.  grid-template-rows: minmax(200px auto) 400px minmax(300px, auto);  
  2644.  grid-auto-rows: minmax(300px, auto);  
  2645.  grid-gap: 20px;  
  2646. }</code></pre>
  2648. <h4 id="a-flexible-grid-with-a-flexible-number-of-columns">A Flexible Grid With A Flexible Number Of Columns</h4>
  2650. <p>By using Repeat Notation, autofill, and minmax you can create a pattern of as many tracks as will fit into a container, thus removing the need for Media Queries to some extent. This technique can be found in <a href="">this video tutorial</a>, and also demonstrated along with similar ideas in my recent article “<a href="">Using Media Queries For Responsive Design In 2018</a>.”</p>
  2652. <p>Choose this technique when you are happy for content to drop below earlier content when there is less space, and are happy to allow a lot of flexibility in sizing. You have specifically asked for your columns to display with a minimum size, and to <strong>auto fill</strong>.</p>
  2654. <p>There were a few comments in the survey that made me wonder if people were choosing this method when they really wanted a grid with a fixed number of columns. If you are ending up with an unpredictable number of columns at certain breakpoints, you might be better to set the number of columns &mdash; and redefine it with media queries as needed &mdash; rather than using <code>auto-fill</code> or <code>auto-fit</code>.</p>
  2657.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  2661. <h4 id="which-method-of-track-sizing-should-i-use">Which Method Of Track Sizing Should I Use?</h4>
  2663. <p>I described track sizing in detail in my article “<a href="">How Big Is That Box? Understanding Sizing In Grid Layout</a>,” however, I often get questions as to which method of track sizing to use. Particularly, I get asked about the difference between percentage sizing and the <code>fr</code> unit.</p>
  2665. <p>If you simply use the <code>fr</code> unit as specced, then it differs from using a percentage because it distributes available space. If you place a larger item into a track then the way the <code>fr</code> until will work is to allow that track to take up more space and distribute what is left over.</p>
  2667. <pre><code class="language-css">.grid {
  2668.  display: grid;
  2669.  grid-template-columns: 1fr 1fr 1fr;
  2670.  grid-gap: 20px;
  2671. }
  2672. </code></pre>
  2684. <figure >
  2685. <a href="">
  2686. <img
  2687. srcset=",q_auto/w_400/ 400w,
  2688.,q_auto/w_800/ 800w,
  2689.,q_auto/w_1200/ 1200w,
  2690.,q_auto/w_1600/ 1600w,
  2691.,q_auto/w_2000/ 2000w"
  2692. src=",q_auto/w_400/"
  2693. sizes="100vw"
  2694. alt="A three column layout, the first column is wider"
  2695. />
  2696. </a>
  2698. <figcaption class="op-vertical-bottom">
  2699. The first column is wider as Grid has assigned it more space.
  2700. </figcaption>
  2701. </figure>
  2704. <p>To cause the <code>fr</code> unit to distribute <strong>all</strong> of the space in the grid container you need to give it a minimum size of <code>0</code> using <code>minmax()</code>.</p>
  2706. <pre><code class="language-css">.grid {
  2707.    display: grid;
  2708.    grid-template-columns: minmax(0,1fr) minmax(0,1fr) minmax(0,1fr);
  2709.    grid-gap: 20px;
  2710. }</code></pre>
  2722. <figure >
  2723. <a href="">
  2724. <img
  2725. srcset=",q_auto/w_400/ 400w,
  2726.,q_auto/w_800/ 800w,
  2727.,q_auto/w_1200/ 1200w,
  2728.,q_auto/w_1600/ 1600w,
  2729.,q_auto/w_2000/ 2000w"
  2730. src=",q_auto/w_400/"
  2731. sizes="100vw"
  2732. alt="three equal columns with the first overflowing"
  2733. />
  2734. </a>
  2736. <figcaption class="op-vertical-bottom">
  2737. Forcing a 0 minimum may cause overflows
  2738. </figcaption>
  2739. </figure>
  2742. <p>So you can choose to use <code>fr</code> in either of these scenarios: ones where you do want space distribution from a basis of auto (the default behavior), and those where you want equal distribution. I would typically use the <code>fr</code> unit as it then works out the sizing for you, and enables the use of fixed width tracks or gaps. The only time I use a percentage instead is when I am adding grid components to an existing layout that uses other layout methods too. If I want my grid components to line up with a float- or flex-based layout which is using percentages, using them in my grid layout means everything uses the same sizing method.</p>
  2744. <h4 id="auto-place-items-or-set-their-position">Auto-Place Items Or Set Their Position?</h4>
  2746. <p>You will often find that you only need to place one or two items in your layout, and the rest fall into place based on content order. In fact, this is a really good test that you haven’t disconnected the source and visual display. If things pretty much drop into position based on auto-placement, then they are probably in a good order.</p>
  2748. <p>Once I have decided where everything goes, however, I do tend to assign a position to everything. This means that I don’t end up with strange things happening if someone adds something to the document and grid auto-places it somewhere unexpected, thus throwing out the layout. If everything is placed, Grid will put that item into the next available empty grid cell. That might not be exactly where you want it, but sat down at the end of your layout is probably better than popping into the middle and pushing other things around.</p>
  2753.  <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber" data-remove="true">
  2754.    <div class="container product-panel--book__container">
  2755.      <div class="panel__description panel__description--book">
  2756.        <p>
  2757.          Is your pattern library up to date today? <em>Alla Kholmatova</em> has just finished a fully fledged book on <strong>Design Systems</strong> and how to get them right. With common traps, gotchas and the lessons she learned. Hardcover, eBook. <em>Just sayin'.</em>
  2758.        </p>
  2759.        <a href="">
  2760.          <button class="btn btn--green btn--large">
  2761.            Table of Contents&nbsp;&rarr;
  2762.          </button>
  2763.        </a>
  2764.      </div>
  2765.      <div class="panel__image panel__image--book">
  2766.        <a href="" class="books__book__image">
  2767.        <div class="books__book__img">
  2768.          <img src="">
  2769.        </div>
  2770.      </a>
  2771.      </div>
  2772.    </div>
  2773.  </aside>
  2778. <h4 id="which-positioning-method-to-use">Which Positioning Method To Use?</h4>
  2780. <p>When working with Grid Layout, ultimately everything comes down to placing items from one line to another. Everything else is essentially a helper for that.</p>
  2782. <p>Decide with your team if you want to name lines, use Grid Template Areas, or if you are going to use a combination of different types of layout. I find that I like to use Grid Template Areas for small components in particular. However, there is no right or wrong. Work out what is best for you.</p>
  2784. <h3 id="grid-in-combination-with-other-layout-mechanisms">Grid In Combination With Other Layout Mechanisms</h3>
  2786. <p>Remember that Grid Layout isn’t the one true layout method to rule them all, it’s designed for a certain type of layout &mdash; namely two-dimensional layout. Other layout methods still exist and you should consider each pattern and what suits it best.</p>
  2788. <p>I think this is actually quite hard for those of us used to hacking around with layout methods to make them do something they were not really designed for. It is a really good time to take a step back, look at the layout methods for the tasks they were designed for, and remember to use them for those tasks.</p>
  2790. <p>In particular, no matter how often I write about Grid versus Flexbox, I will be asked which one people <em>should</em> use. There are many patterns where either layout method makes perfect sense and it really is up to you. No-one is going to shout at you for selecting Flexbox over Grid, or Grid over Flexbox.</p>
  2792. <p>In my own work, I tend to use Flexbox for components where I want the natural size of items to strongly control their layout, essentially pushing the other items around. I also often use Flexbox because I want alignment, given that the Box Alignment properties are only available to use in Flexbox and Grid. I might have a Flex container with one child item, in order that I can align that child.</p>
  2794. <p>A sign that perhaps Flexbox isn’t the layout method I should choose is when I start adding percentage widths to flex items and setting <code>flex-grow</code> to 0. The reason to add percentage widths to flex items is often because I’m trying to line them up in two dimensions (lining things up in two dimensions is exactly what Grid is for). However, try both, and see which seems to suit the content or design pattern best. You are unlikely to be causing any problems by doing so.</p>
  2796. <h3 id="nesting-grid-and-flex-items">Nesting Grid And Flex Items</h3>
  2798. <p>This also comes up a lot, and there is absolutely no problem with making a Grid Item also a Grid Container, thus nesting one grid inside another. You can do the same with Flexbox, making a Flex Item and Flex Container. You can also make a Grid Item and Flex Container or a Flex Item a Grid Container &mdash; none of these things are a problem!</p>
  2800. <p>What we can’t currently do is nest one grid inside another and have the nested grid use the grid tracks defined on the overall parent. This would be very useful and is what the subgrid proposals in <a href="">Level 2 of the Grid Specification</a> hope to solve. A nested grid currently becomes a new grid so you would need to be careful with sizing to ensure it aligns with any parent tracks.</p>
  2802. <h3 id="you-can-have-many-grids-on-one-page">You Can Have Many Grids On One Page</h3>
  2804. <p>A comment popped up a few times in the survey which surprised me, there seems to be an idea that a grid should be confined to the main layout, and that many grids on one page were perhaps not a good thing. <strong>You can have as many grids as you like!</strong> Use grid for big things and small things, if it makes sense laid out as a grid then use Grid.</p>
  2806. <h3 id="fallbacks-and-supporting-older-browsers">Fallbacks And Supporting Older Browsers</h3>
  2808. <blockquote>“Grid used in conjunction with @supports has enabled us to better control the number of layout variations we can expect to see. It has also worked really well with our progressive enhancement approach meaning we can reward those with modern browsers without preventing access to content to those not using the latest technology.”<br /><br />&mdash; <a href="">Joe Lambert</a> working on <a href=""></a></blockquote>
  2810. <p>In the survey, many people mentioned older browsers, however, there was a reasonably equal split between those who felt that supporting older browsers was hard and those who felt it was easy due to Feature Queries and the fact that Grid overrides other layout methods. I’ve written at length about the mechanics of creating these fallbacks in “<a href="">Using CSS Grid: Supporting Browsers Without Grid</a>.”</p>
  2812. <p>In general, modern browsers are far more interoperable than their earlier counterparts. We tend to see far fewer actual “browser bugs” and if you use HTML and CSS correctly, then you will generally find that what you see in one browser is the same as in another.</p>
  2814. <p>We do, of course, have situations in which one browser has not yet shipped support for a certain specification, or some parts of a specification. With Grid, we have been very fortunate in that browsers shipped Grid Layout in a very complete and interoperable way within a short time of each other. Therefore, our considerations for testing tend to be to need to test browsers with Grid and without Grid. You may also have chosen to use the <code>-ms</code> prefixed version in IE10 and IE11, which would then require testing as a third type of browser.</p>
  2816. <p>Browsers which support modern Grid Layout (not the IE version) also support Feature Queries. This means that you can test for Grid support before using it.</p>
  2818. <h3 id="testing-browsers-that-don-t-support-grid">Testing Browsers That Don’t Support Grid</h3>
  2820. <p>When using fallbacks for browsers without support for Grid Layout (or using the <code>-ms</code> prefixed version for IE10 and 11), you will want to test how those browsers render Grid Layout. To do this, you need a way to view your site in an example browser.</p>
  2822. <p>I would not take the approach of breaking your Feature Query by checking for support of something nonsensical, or misspelling the value <code>grid</code>. This approach will only work if your stylesheet is incredibly simple, and you have put absolutely everything to do with your Grid Layout inside the Feature Queries. This is a very fragile and time-consuming way to work, especially if you are extensively using Grid. In addition, an older browser will not just lack support for Grid Layout, there will be other CSS properties unsupported too. If you are looking for “best practice” then setting yourself up so you are in a good position to test your work is high up there!</p>
  2824. <p>There are a couple of straightforward ways to set yourself up with a proper method of testing your fallbacks. The easiest method &mdash; if you have a reasonably fast internet connection and don’t mind paying a subscription fee &mdash; is to use a service such as BrowserStack. This is a service that enables viewing of websites (even those in development on your computer) on a whole host of real browsers. BrowserStack does offer <a href="">free accounts for open-source projects</a>.</p>
  2836. <figure >
  2837. <a href="">
  2838. <img
  2839. srcset=",q_auto/w_400/ 400w,
  2840.,q_auto/w_800/ 800w,
  2841.,q_auto/w_1200/ 1200w,
  2842.,q_auto/w_1600/ 1600w,
  2843.,q_auto/w_2000/ 2000w"
  2844. src=",q_auto/w_400/"
  2845. sizes="100vw"
  2846. alt="Screenshot of the download page"
  2847. />
  2848. </a>
  2850. <figcaption class="op-vertical-bottom">
  2851. You can download Virtual Machines for testing from Microsoft.
  2852. </figcaption>
  2853. </figure>
  2856. <p>To test locally, my suggestion would be to use a Virtual Machine with your target browser installed. Microsoft offers free <a href="">Virtual Machine downloads</a> with versions of IE back to IE8, and also Edge. You can also install onto the VM an older version of a browser with no Grid support at all. <a href="">For example by getting a copy of Firefox 51 or below</a>. After installing your elderly Firefox, be sure to <a href="">turn off automatic updates as explained here</a> as otherwise it will quietly update itself!</p>
  2858. <p>You can then test your site in IE11 and in non-supporting Firefox on one VM (a far less fragile solution than misspelling values). Getting set up might take you an hour or so, but you’ll then be in a really good place to test your fallbacks.</p>
  2860. <h3 id="unlearning-old-habits">Unlearning Old Habits</h3>
  2862. <blockquote>“It was my first time to use Grid Layout, so there were a lot of concepts to learn and properties understand. Conceptually, I found the most difficult thing to unlearn all the stuff I had done for years, like clearing floats and packing everything in container divs.”<br /><br />&mdash; <a href="">Hidde</a> working on <a href=""></a></blockquote>
  2864. <p>Many of the people responding to the survey mentioned the need to unlearn old habits and how learning Layout would be easier for people completely new to CSS. I tend to agree. When teaching people in person complete beginners have little problem using Grid while experienced developers try hard to return grid to a one-dimensional layout method. I’ve seen attempts at “grid systems” using CSS Grid which add back in the row wrappers needed for a float or flex-based grid.</p>
  2866. <p><strong>Don’t be afraid to try out new techniques</strong>. If you have the ability to test in a few browsers and remain mindful of potential issues of accessibility, you really can’t go too far wrong. And, if you find a great way to create a certain pattern, let everyone else know about it. We are all new to using Grid in production, so there is certainly plenty to discover and share.</p>
  2868. <blockquote>“Grid Layout is the most exciting CSS development since media queries. It's been so well thought through for real-world developer needs and is an absolute joy to use in production - for designers and developers alike.”<br /><br />&mdash; <a href="">Trys Mudford</a> working on <a href=""></a></blockquote>
  2870. <p>To wrap up, here is a very short list of current best practices! If you have discovered things that do or don’t work well in your own situation, add them to the comments.</p>
  2872. <ol>
  2873. <li>Be very aware of the possibility of content re-ordering. Check that you have not disconnected the visual display from the document order.</li>
  2874. <li>Test using real target browsers with a local or remote Virtual Machine.</li>
  2875. <li>Don’t forget that older layout methods are still valid and useful. Try different ways to achieve patterns. Don’t be hung up on having to use Grid.</li>
  2876. <li>Know that as an experienced front-end developer you are likely to have a whole set of preconceptions about how layout works. Try to look at these new methods anew rather than forcing them back into old patterns.</li>
  2877. <li>Keep trying things out. We’re all new to this. Test your work and share what you discover.</li>
  2878. </ol>
  2883. <div class="signature">
  2884.  <img src="" alt="Smashing Editorial">
  2885.  <span>(il)</span>
  2886. </div>
  2889. </div>
  2893.              </article>
  2894.            </body>
  2895.          </html>
  2896.        ]]></content:encoded>
  2897.      </item>
  2899.      <item>
  2902.          <author>Anselm Hannemann</author>
  2904.        <title>Monthly Web Development Update 4/2018: On Effort, Bias, And Being Productive</title>
  2905.        <link></link>
  2906.        <pubDate>Fri, 13 Apr 2018 14:30:19 +0200</pubDate>
  2907.        <guid></guid>
  2908.        <description>These days, it is one of the biggest challenges to think long-term. In a world where we live with devices that last only a few months or a few years maybe, where we buy stuff to throw it away only days or weeks later, the term ‘effort’ gains a new meaning.
  2909. Recently, I was reading an essay on ‘Yatnah’, ‘Effort’. I spent a lot of time outside in nature in the past weeks and created a small acre to grow some vegetables.</description>
  2910.        <content:encoded><![CDATA[
  2911.          <html>
  2912.            <head>
  2913.              <meta charset="utf-8">
  2914.              <link rel="canonical" href="" />
  2915.              <title>Monthly Web Development Update 4/2018: On Effort, Bias, And Being Productive</title>
  2916.            </head>
  2917.            <body>
  2918.              <article>
  2919.                <header>
  2920.                  <h1>Monthly Web Development Update 4/2018: On Effort, Bias, And Being Productive</h1>
  2923.                    <address>Anselm Hannemann</address>
  2925.                  <time datetime="2018-04-13T14:30:19&#43;02:00" class="op-published">2018-04-13T14:30:19+02:00</time>
  2926.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  2927.                </header>
  2928.                <p>These days, it is one of the biggest challenges to think long-term. In a world where we live with devices that last only a few months or a few years maybe, where we buy stuff to throw it away only days or weeks later, the term ‘effort’ gains a new meaning.</p>
  2930. <p>Recently, I was reading <a href="">an essay on ‘Yatnah’</a>, ‘Effort’. I spent a lot of time outside in nature in the past weeks and created a small acre to grow some vegetables. I also attended a workshop to learn the craft of grafting fruit trees. When you cut a tree, you realize that our fast-living, short-term lifestyle is very different from how nature works. I grafted a tree that is supposed to grow for decades now, and if you cut a tree that has been there for forty years, it’ll take another forty to grow one that will be similarly tall.</p>
  2932. <p>I’d love that we all try to <strong>create more long-lasting work</strong>, software that works in a decade, and in order to do so, put effort into learning how we can make that happen. So long, I’ll leave you with this quote and a bunch of interesting articles.</p>
  2934. <blockquote>“In our modern world it can be tempting to throw effort away and replace it with a few phrases of positive thinking. But there is just no substitute for practice”.<br /><br />&mdash; Kino Macgregor</blockquote>
  2938.  <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  2939.    <div class="container product-panel--book__container">
  2940.      <div class="panel__description panel__description--book">
  2941.    <p>Getting the process <em>just</em> right ain't an easy task. That's why we've set up <strong>'this-is-how-I-work'-sessions</strong> — with smart cookies sharing what works really well for them. A part of the <a href="">Smashing Membership</a>, of course.</p>
  2942.      <a href="" class="btn btn--green btn--large">
  2943.        Explore features&nbsp;→
  2944.      </a>
  2945.      </div>
  2946.      <div class="panel__image panel__image--book">
  2947.        <a href="" class="books__book__image">
  2948.        <div class="books__book__img">
  2949.          <img src="" alt="Smashing TV, with live sessions for professional designers and developers." width="310" height="400">
  2950.        </div>
  2951.      </a>
  2952.      </div>
  2953.    </div>
  2954.  </aside>
  2960. <div class="c-garfield-the-cat">
  2963. <h3>News</h3>
  2965. <ul>
  2966. <li>The <a href="">Safari Technology Preview 52</a> removes support for all NPAPI plug-ins other than Adobe Flash and adds support for <code>preconnect</code> link headers.</li>
  2967. <li><a href="">Chrome 66 Beta</a> brings the CSS Typed Object Model, Async Clipboard API, AudioWorklets, and support to use <code>calc()</code>, <code>min()</code>, and <code>max()</code> in Media Queries. Additionally, <code>select</code> and <code>textarea</code> fields now support the <code>autocomplete</code> attribute, and the <code>catch</code> clause of a <code>try</code> statement can be used without a parameter from now on.</li>
  2968. <li>iOS 11.3 is available to the public now, and, as already announced, the release <a href="">brings support for Progressive Web Apps to iOS</a>. Maximiliano Firtman shares what this means, what works and what doesn’t work (yet).</li>
  2969. <li>Safari 11.1 is now available for everyone. Here is a <a href="">summary of all the new WebKit features</a> it includes.</li>
  2970. </ul>
  2972. <figure><a href=""><img src="" width="800" height="599" alt="Progressive Web App on iOS" /></a><figcaption><a href="">Progressive Web Apps for iOS are here</a>. Full screen, offline capable, and even visible in the iPad’s dock. (<a href="">Image credit</a>)</figcaption></figure>
  2974. <h3>General</h3>
  2976. <ul>
  2977. <li>Anil Dash reflects on what the web was intended to be and how today’s web differs from this: “At a time when millions are losing trust in the web’s biggest sites, it’s worth revisiting the idea that the web was supposed to be made out of countless little sites. Here’s a <a href="">look at the neglected technologies that were supposed to make it possible</a>.”</li>
  2978. <li>Morten Rand-Hendriksen wrote about <a href="">using ethics in web design</a> and what questions we should ask ourselves when suggesting a solution, creating a design, or a new feature. Especially when we think we’re making something ‘smart’, it’s important to put the question whether it actually helps people first.</li>
  2979. <li>A lot of protest and discussion came along with the <a href="">Facebook / Cambridge Analytica affair</a>, most of them pointing out the technological problems with Facebook’s permission model. But the crux lies in how Facebook designed their company and which ethical baseline they set. If we don’t want something like this to happen again, <a href="">it’s upon us to design the service we want</a>.</li>
  2980. <li>Brendan Dawes shares <a href="">why he thinks URLs are a masterpiece</a> and a user experience by themselves.</li>
  2981. <li>Charlie Owen’s talk transcription of “<a href="">Dear Developer, The Web Isn’t About You</a>” is a good summary of why we as developers need to think beyond what’s good for us and consider what serves the users and how we can achieve that instead.</li>
  2982. </ul>
  2984. <h3>UI/UX</h3>
  2986. <ul>
  2987. <li>B. Kaan Kavuştuk shares his thoughts about why we won’t be able to build a perfect design or codebase on the first try, no matter how much experience we have. Instead, it’s <a href="">the constant small improvements that pave the way to perfection</a>.</li>
  2988. <li>Trine Falbe <a href="">introduces us to Ethical Design</a> with a practical getting-started guide. It shows alternatives and things to think about when building a business or product. It doesn’t matter much if you’re the owner, a developer, a designer or a sales person, this is about serving users and setting the ground for real and sustainable trust.</li>
  2989. <li>Josh Lovejoy shares his <a href="">learnings from working on inclusive tech solutions</a> and why it takes more than good intention to create fair, inclusive technology. This article goes into depth of why human judgment is very difficult and often based on bias, and why it isn’t easy to design and develop algorithms that treat different people equally because of this.</li>
  2990. <li>The HSB (Hue, Saturation, Brightness) color system isn’t especially new, but a lot of people still don’t understand its advantages. Erik D. Kennedy <a href="">explains its principles and advantages</a> step-by-step.</li>
  2991. <li>While there’s more discussion about inclusive design these days, it’s often seen under the accessibility hat or as technical decisions. Robert del Prado now shares <a href="">how important inclusive design thinking is</a> and why it’s much more about the generic user than some specific people with specific disabilities. Inclusive design brings people together, regardless of who they are, where they live, and what they can afford. And isn’t it the goal of every product to be successful by acquiring as many people as possible? Maybe we need to discuss this with marketing people as well.</li>
  2992. <li>Anton Lovchikov shares ways to <a href="">improve optical adjustments in components</a>. It’s an interesting study on how very small changes can make quite a difference.</li>
  2993. </ul>
  2995. <figure><a href=""><img src="" width="800" height="450" alt="Fair Is Not The Default" /></a><figcaption>Afraid or angry? Which emotion we think the baby is showing depends on whether we think it’s a girl or a boy. Josh Lovejoy explains <a href="">how personal bias and judgments like this one lead to unfair products</a>. (<a href="">Image credit</a>)</figcaption></figure>
  2997. <h3>Tooling</h3>
  2999. <ul>
  3000. <li>Brian Schrader found an unknown feature in Git which is very helpful to test ideas quickly: <a href="">Git Notes</a> lets us add, remove, or read notes attached to objects, without touching the objects themselves and without needing to commit the current state.</li>
  3001. <li>For many projects, I prefer to use npm scripts over calling gulp or direct webpack tasks. Michael Kühnel <a href="">shares some useful tricks for npm scripts</a>, including how to allow CLI option parameters or how to watch tasks and alert notices on error.</li>
  3002. <li>Anton Sten explains why <a href="">new tools don’t always equal productivity</a>. We all love new design tools, and new ones such as Sketch, Figma, Xd, or Invision Studio keep popping up. But despite these tools solving a lot of common problems and making some things easier, productivity is mostly about what works for your problem and not what is newest. If you need to create a static mockup and Photoshop is what you know best, why not use it?</li>
  3003. <li>There’s a <a href="">new, fast DNS service available by Cloudflare</a>. Finally, a better alternative to the much used Google DNS servers, it is available under <code></code>. The new DNS is the fastest, and probably one of the most secure ones, too, out there. Cloudflare put a lot of effort into encrypting the service and partnering up with Mozilla to make DNS over HTTPS work to close a big privacy gap that until now leaked all your browsing data to the DNS provider.</li>
  3004. <li>I heard a lot about iOS machine learning already, but despite the interesting fact that they’re able to do this on the device without sending everything to a cloud, I haven’t found out how to make use of this for apps, yet. Luckily, Manu Rink put together a nice guide in which she explains <a href="">machine learning in iOS for beginners</a>.</li>
  3005. <li>There’s great news for the Git GUI fans: <a href="">Tower now offers a new beta version</a> that includes pull request support, interactive rebase workflows, quick actions, reflog, and search. An amazing update that makes working with the software much faster than before, and even for me as a command line lover it’s a nice option.</li>
  3006. </ul>
  3008. <figure><a href=""><img src="" width="800" height="674" alt="Machine Learning In iOS For The Noob" /></a><figcaption>Manu Rink shows <a href="">how machine learning in iOS works</a> by building an offline handwritten text recognition. (<a href="">Image credit</a>)</figcaption></figure>
  3010. <h3>Security</h3>
  3012. <ul>
  3013. <li>HTTP Strict Transport Security (HSTS), especially with preloading, has long been considered one of the best security features to ensure that a browser should connect only securely to a hostname. However, advertisers have found a way to track users with HSTS and using it as a persistent cross-site identifier (known as “super cookie”). <a href="">The WebKit developers reacted now</a>, and in order to protect the privacy of their users, they weakened the reliability of HSTS by limiting the hostname scope and ignoring an HSTS state for subresource requests to blocked domains.</li>
  3014. <li>PagerDuty just published an <a href="">open-source version of their internal security training material</a>, full of interesting and easy to understand explanations about common security issues and strategies. This is especially useful as you can give it to people without technical experience.</li>
  3015. <li>Christoph Rumpel shares how he found <a href="">a way to use his Content Security Policy with the Laravel Response Caching package</a>.</li>
  3016. <li>While Argon2 is the current best practice algorithm to use for hashing (passwords, for example), there are a couple of things developers need to prepare for. For example, <a href="">it’s easy to DOS yourself using Argon2</a>, so you need to rate limit queries.</li>
  3017. <li>James Fisher shares an interesting way to <a href="">scam Gmail users, as demonstrated at the example of Netflix</a>.</li>
  3018. </ul>
  3023. <h3>Web Performance</h3>
  3025. <ul>
  3026. <li>This week, a discussion popped up on whether the technique of <a href="">serving compressive images</a> is still a good idea. Tim Kadlec took it as a trigger to revisit it. He now concludes that <a href="">we should not use the compressive image technique anymore</a> because of its big memory footprint and rely on new responsive image technologies such as the <code>&lt;picture&gt;</code> element or <code>srcset</code> and <code>sizes</code> attributes instead.</li>
  3027. <li>Eric Portis shares the under-the-hood principles of the <code>w</code> descriptors and <code>sizes</code> attribute for images. A pretty technical but revealing post that makes you <a href="">finally understand the magic behind these new responsive image attributes</a>.</li>
  3028. <li>Tim Oxley shares <a href="">why he prefers to return early and avoid <code>else</code></a> wherever possible. This is something I’ve been doing at the beginning of my career, then lost at some point, but returned to it again recently. Especially the reduced complexity and simpler logic in functions is a key advantage for me here.</li>
  3029. <li>Jeremy Wagner shares best practices on <a href="">how to build a lazy loading mechanism for images and videos</a>. It’s definitely not the quickest solution but the resource shares how to build the best experience and performance based on the latest technologies available in browsers.</li>
  3030. </ul>
  3032. <h3>Accessibility</h3>
  3034. <ul>
  3035. <li>Marcy Sutton explains <a href="">what’s new in Axe 3.0</a> which now supports Shadow DOM and which you can run in your automated test suite.</li>
  3036. <li>Patrick H. Laucke shares <a href="">what the new <code>:focus-visible</code> CSS pseudo-selector is about</a> and how we need to write it to ensure backwards compatibility with browsers that don’t support it yet.</li>
  3037. <li>Marco Zehe introduces us to the <a href="">new Accessibility Inspector in Firefox Developer Tools</a>. This is great news and helps make inspecting accessibility issues way easier than it used to be.</li>
  3038. </ul>
  3040. <h3>CSS</h3>
  3042. <ul>
  3043. <li>Amber Wilson shares some insights into what it feels like to be thrown into a complex project in order to do the styling there. She rightly says that “<a href="">nobody said CSS is easy</a>” and expresses how important it is that we as developers face inconvenient situations in order to grow our knowledge.</li>
  3044. <li>Ana Tudor is known for her special CSS skills. Now she explores and describes how we can achieve <a href="">scooped corners in CSS</a> with some clever tricks.</li>
  3045. </ul>
  3047. <figure><a href=""><img src="" width="800" height="318" alt="Scooped Corners" /></a><figcaption>Scooped corners? Ana Tudor shows <a href="">how to do it</a>. (<a href="">Image credit</a>)</figcaption></figure>
  3049. <h3>JavaScript</h3>
  3051. <ul>
  3052. <li><a href="">WebKit got an upgrade for the Clipboard API</a>, and the team gives some very interesting insights into how it works and how Safari will handle some of the common challenges with clipboard data (e.g. images).</li>
  3053. <li>If you work with key value stores that live only in the frontend, <a href="">IDB-Keyval</a> is a great lightweight library that simplifies working with IndexedDB and localStorage.</li>
  3054. <li>Ever wanted to create graphics from your data with a hand-drawn, sketchy look on a website? <a href="">Rough.js</a> lets you do just that. It’s usually Canvas-based (for better performance and less data) but can also draw SVG paths.</li>
  3055. <li>If you need a drag-and-drop reorder module, there’s a smooth and accessible solution available now: <a href="">dragon-drop</a>.</li>
  3056. <li>For many years, we could only get CSS values in their computed value and even that wasn’t flexible or nice to work with. But now CSS has a proper object-based API for working with values in JavaScript: the <a href="">CSS Typed Object Model</a>. It’s only available in the upcoming Chrome 66 yet but definitely a promising feature I’d love to use in my code soon.</li>
  3057. <li>The React.js documentation now has an extra section that explains how to easily and <a href="">programmatically manage focus states to ensure your UI is accessible</a>.</li>
  3058. <li>James Milner shares how we can <a href="">use abortable fetch to cancel requests</a>.</li>
  3059. <li>There are a few articles about Web Push Notifications out there already, but Oleksii Rudenko’s <a href="">getting-started guide</a> is a great primer that explains the principles very well.</li>
  3060. <li>In the past years, we got a lot of new features on the JavaScript platform. And since it’s hard to remember all the new stuff, Raja Rao DV summed up <a href="">“Everything new in ECMAScript 2016, 2017, and 2018”</a>.</li>
  3061. </ul>
  3063. <h3>Work &amp; Life</h3>
  3065. <ul>
  3066. <li>To raise awareness for how common such situations are for all of us, James Bennett shares an embarrassing situation <a href="">where he made a simple mistake that took him a long time to find out</a>. It’s not just me making mistakes, it’s not just you, and not just James &mdash; all of us make mistakes, and as embarrassing as they seem to be in that particular situation, there’s nothing to feel bad about.</li>
  3067. <li>Adam Blanchard says “<a href="">People are machines. We need maintenance, too.</a>” and creates a comparison for engineers to understand why we need to take care of ourselves and also why we need people who take care of us. This is an insight into what People Engineers do, and why it’s so important for companies to hire such people to ensure a team is healthy.</li>
  3068. <li>If there’s one thing we don’t talk much about in the web industry, it’s retirement. Jan Chipchase now wrote <a href="">a lot of interesting thoughts all about retirement</a>.</li>
  3069. <li>Rebecca Downes shares some <a href="">insights into her PhD on remote teams</a>, revealing under which circumstances remote teams are great and under which they’re not.</li>
  3070. </ul>
  3072. <figure><a href=""><img src="" width="800" height="390" alt="What would people engineers do" /></a><figcaption>People need maintenance, too. That’s where the <a href="">People Engineer</a> comes in. (<a href="">Image credit</a>)</figcaption></figure>
  3074. <h3>Going Beyond…</h3>
  3076. <ul>
  3077. <li>Now that we discuss the problems of centralized services like Facebook and Google, decentralization is seen as the savior of the independent web. But I’m sure that <a href="">if we don’t try to solve the underlying humanitarian issue with technology, nothing will change</a>.</li>
  3078. <li>You might have read the news about the first fatal crash with a self-driving car. A sad milestone that shows <a href="">how unreliable this technology can be</a> and how far away we still are from being able to rely on such systems.</li>
  3079. <li>A decade ago, smart devices promised to change the way we think and interact, and they have – but not by making us smarter. Eric Andrew-Gee explores the scientific <a href="">evidence that digital distraction is damaging our minds</a>.</li>
  3080. <li>Fred Pearce wrote about <a href="">how we can make the world’s largest data centers more efficient</a>. If you wonder why this would be the desired goal, it’s important to know that these data centers are responsible for 3% of the overall global CO2 emissions &mdash; as much as the airline industry.</li>
  3081. <li>“<a href="">A disused coal power station will reopen to solely power crypto</a> currencies.” I have no additional words for this.</li>
  3082. </ul>
  3084. <p>We hope you enjoyed this Web Development Update. The next one is scheduled for Friday, May 18th. Stay tuned.</p>
  3086. <div class="signature">
  3087.  <img src="" alt="Smashing Editorial">
  3088.  <span>(cm)</span>
  3089. </div>
  3092. </div>
  3097.  <div id="sponsors-article-end" data-impression="true" class="c-promo-box c-promo-box--ad c-promo-box--wide sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  3101.              </article>
  3102.            </body>
  3103.          </html>
  3104.        ]]></content:encoded>
  3105.      </item>
  3107.      <item>
  3110.          <author>Nils Schütte</author>
  3112.        <title>Automating Your Feature Testing With Selenium WebDriver</title>
  3113.        <link></link>
  3114.        <pubDate>Thu, 12 Apr 2018 12:45:54 +0200</pubDate>
  3115.        <guid></guid>
  3116.        <description>This article is for web developers who wish to spend less time testing the front end of their web applications but still want to be confident that every feature works fine. It will save you time by automating repetitive online tasks with Selenium WebDriver. You will find a step-by-step example for automating and testing the login function of WordPress, but you can also adapt the example for any other login form.</description>
  3117.        <content:encoded><![CDATA[
  3118.          <html>
  3119.            <head>
  3120.              <meta charset="utf-8">
  3121.              <link rel="canonical" href="" />
  3122.              <title>Automating Your Feature Testing With Selenium WebDriver</title>
  3123.            </head>
  3124.            <body>
  3125.              <article>
  3126.                <header>
  3127.                  <h1>Automating Your Feature Testing With Selenium WebDriver</h1>
  3130.                    <address>Nils Schütte</address>
  3132.                  <time datetime="2018-04-12T12:45:54&#43;02:00" class="op-published">2018-04-12T12:45:54+02:00</time>
  3133.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  3134.                </header>
  3137. <p>This article is for web developers who wish to spend less time testing the front end of their web applications but still want to be confident that every feature works fine. It will save you time by automating repetitive online tasks with Selenium WebDriver. You will find a step-by-step example for automating and testing the login function of WordPress, but you can also adapt the example for any other login form.</p>
  3139. <h3 id="what-is-selenium-and-how-can-it-help-you">What Is Selenium And How Can It Help You?</h3>
  3141. <p>Selenium is a framework for the automated testing of web applications. Using Selenium, you can basically automate every task in your browser as if a real person were to execute the task. The interface used to send commands to the different browsers is called Selenium WebDriver. Implementations of this interface are available for every major browser, including Mozilla Firefox, Google Chrome and Internet Explorer.</p>
  3143. <h3 id="automating-your-feature-testing-with-selenium-webdriver">Automating Your Feature Testing With Selenium WebDriver</h3>
  3145. <p>Which type of web developer are you? Are you the disciplined type who tests all key features of your web application after each deployment. If so, you are probably annoyed by how much time this repetitive testing consumes. Or are you the type who just doesn’t bother with testing key features and always thinks, &ldquo;I should test more, but I’d rather develop new stuff.&rdquo; If so, you probably only find bugs by chance or when your client or boss complains about them.</p>
  3147. <p>I have been working for a well-known online retailer in Germany for quite a while, and I always belonged to the second category: It was so exciting to think of new features for the online shop, and I didn’t like at all going over all of the previous features again after each new software deployment. So, the strategy was more or less to hope that all key features would work.</p>
  3151. <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  3152.    <div class="container product-panel--book__container">
  3153.      <div class="panel__description panel__description--book">
  3154.    <p>Nope, we can't do any magic tricks, but we have articles, <a href="">books</a> and <a href="">webinars</a> featuring techniques we all can use to improve our work. <a href="">Smashing Members</a> get a seasoned selection of magic front-end tricks — e.g. <strong>live designing sessions</strong> and perf audits, too. <em>Just sayin'</em>! ;-)</p>
  3156.      <a href="" class="btn btn--green btn--large">
  3157.        Explore Smashing Wizardry&nbsp;→
  3158.      </a>
  3159.      </div>
  3160.      <div class="panel__image panel__image--book">
  3161.        <a href="" class="books__book__image">
  3162.        <div class="books__book__img">
  3163.          <img src="" alt="Smashing Cat, just preparing to do some magic stuff." width="310" height="400">
  3164.        </div>
  3165.      </a>
  3166.      </div>
  3167.    </div>
  3168.  </aside>
  3174. <div class="c-garfield-the-cat">
  3177. <p>One day, we had a serious drop in our conversion rate and started digging in our web analytics tools to find the source of this drop. It took quite a while before we found out that our checkout did not work properly since the previous software deployment.</p>
  3179. <p>This was the day when I started to do some research about automating our testing process of web applications, and I stumbled upon Selenium and its WebDriver. Selenium is basically a framework that allows you to automate web browsers. WebDriver is the name of the key interface that allows you to send commands to all major browsers (mobile and desktop) and work with them as a real user would.</p>
  3181. <h3 id="preparing-the-first-test-with-selenium-webdriver">Preparing The First Test With Selenium WebDriver</h3>
  3183. <p>First, I was a little skeptical of whether Selenium would suit my needs because the framework is most commonly used in Java, and I am certainly not a Java expert. Later, I learned that being a Java expert is not necessary to take advantage of the power of the Selenium framework.</p>
  3185. <p>As a simple first test, I tested the login of one of my WordPress projects. Why WordPress? Just because using the WordPress login form is an example that everybody can follow more easily than if I were to refer to some custom web application.</p>
  3187. <p>What do you need to start using Selenium WebDriver? Because I decided to use the most common implementation of Selenium in Java, I needed to set up my little Java environment.</p>
  3189. <p>If you want to follow my example, you can use the Java environment of your choice. If you haven’t set one up yet, I suggest <a href="">installing Eclipse</a> and making sure you are able to run a simple <a href="">&ldquo;Hello world&rdquo; script in Java</a>.</p>
  3191. <p>Because I wanted to test the login in Chrome, I made sure that the Chrome browser was already installed on my machine. That’s all I did in preparation.</p>
  3193. <h3 id="downloading-the-chromedriver">Downloading The ChromeDriver</h3>
  3195. <p>All major browsers provide their own implementation of the WebDriver interface. Because I wanted to test the WordPress login in Chrome, I needed to get the WebDriver implementation of Chrome: <a href="">ChromeDriver.</a></p>
  3197. <p>I extracted the ZIP archive and stored the executable file <code>chromedriver.exe</code> in a location that I could remember for later.</p>
  3199. <h3 id="setting-up-our-selenium-project-in-eclipse">Setting Up Our Selenium Project In Eclipse</h3>
  3201. <p>The steps I took in Eclipse are probably pretty basic to someone who works a lot with Java and Eclipse. But for those like me, who are not so familiar with this, I will go over the individual steps:</p>
  3203. <ol>
  3204.    <li>Open Eclipse.</li>
  3205.    <li>Click the "New" icon.<br />
  3206.        <figure><a href=""><img src="" width="323" height="88" alt="Creating a new project in Eclipse" /></a><figcaption>Creating a new project in Eclipse</figcaption></figure>
  3207.    </li>
  3208.    <li>Choose the wizard to create a new "Java Project," and click “Next.”<br />
  3209.        <figure><a href=""><img src="" width="541" height="514" alt="Chosing the java-project wizard" /></a><figcaption>Choose the java-project wizard.</figcaption></figure>
  3210.    </li>
  3211.    <li>Give your project a name, and click "Finish."<br />
  3212.        <figure><a href=""><img src="" width="574" height="729" alt="Eclipse project wizard" /></a><figcaption>The eclipse project wizard</figcaption></figure>
  3213.    </li>
  3214.    <li>Now you should see your new Java project on the left side of the screen.<br />
  3215.        <figure><a href=""><img src="" width="324" height="85" alt="Java project successfully created" /></a><figcaption>We successfully created a project to run the Selenium WebDriver.</figcaption></figure>
  3216.    </li>
  3217. </ol>
  3219. <h3 id="adding-the-selenium-library-to-our-project">Adding The Selenium Library To Our Project</h3>
  3221. <p>Now we have our Java project, but Selenium is still missing. So, next, we need to bring the Selenium framework into our Java project. Here are the steps I took:</p>
  3223. <ol>
  3224.    <li>Download the <a href="">latest version</a> of the Java Selenium library.<br/>
  3225.        <figure><a href=""><img src="" width="571" height="134" alt="Downloading the Selenium library" /></a><figcaption>Download the Selenium library.</figcaption></figure>
  3226.    </li>
  3227.    <li>Extract the archive, and store the folder in a place you can remember easily.</li>
  3228.    <li>Go back to Eclipse, and go to "Project" &rarr; “Properties.”<br />
  3229.        <figure><a href=""><img src="" width="228" height="248" alt="Eclipse Properties" /></a><figcaption>Go to properties to integrate the Selenium WebDriver in you project.</figcaption></figure>
  3230.    </li>
  3231.    <li>In the dialog, go to "Java Build Path" and then to register “Libraries.”</li>
  3232.    <li>Click on "Add External JARs."<br />
  3233.        <figure><a href=""><img src="" width="802" height="558" alt="Adding the Selenium lib to your Java build path." /></a><figcaption> Add the Selenium lib to your Java build path.</figcaption></figure>
  3234.    </li>
  3235.    <li>Navigate to the just downloaded folder with the Selenium library. Highlight all <code>.jar</code> files and click "Open."<br />
  3236.        <figure><a href=""><img src="" width="586" height="150" alt="Selecting the correct files of the Selenium lib." /></a><figcaption>Select all files of the lib to add to your project.</figcaption></figure>
  3237.    </li>
  3238.    <li>Repeat this for all <code>.jar</code> files in the subfolder <code>libs</code> as well.</li>
  3239.    <li>Eventually, you should see all <code>.jar</code> files in the libraries of your project:<br />
  3240.        <figure><a href=""><img src="" width="756" height="562" alt="Selenium WebDriver framework successfully integrated into your project" /></a><figcaption>The Selenium WebDriver framework has now been successfully integrated into your project!</figcaption></figure>
  3241.    </li>
  3242. </ol>
  3244. <p>That’s it! Everything we’ve done until now is a one-time task. You could use this project now for all of your different tests, and you wouldn’t need to do the whole setup process for every test case again. Kind of neat, isn’t it?</p>
  3246. <h3 id="creating-our-testing-class-and-letting-it-open-the-chrome-browser">Creating Our Testing Class And Letting It Open the Chrome Browser</h3>
  3249.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  3253. <p>Now we have our Selenium project, but what next? To see whether it works at all, I wanted to try something really simple, like just opening my Chrome browser.</p>
  3255. <p>To do this, I needed to create a new Java class from which I could execute my first test case. Into this executable class, I copied a few Java code lines, and believe it or not, it worked! Magically, the Chrome browser opened and, after a few seconds, closed all by itself.</p>
  3257. <p>Try it yourself:</p>
  3259. <ol>
  3260.    <li>Click on the "New" button again (while you are in your new project’s folder).<br />
  3261.        <figure><a href=""><img src="" width="323" height="88" alt="New class in eclipse" /></a><figcaption>Create a new class to run the Selenium WebDriver.</figcaption></figure>
  3262.    </li>
  3263.    <li>Choose the "Class" wizard, and click “Next.”<br />
  3264.        <figure><a href=""><img src="" width="540" height="515" alt="New class wizard in eclipse" /></a><figcaption>Choose the Java class wizard to create a new class.</figcaption></figure>
  3265.    </li>
  3266.    <li>Name your class (for example, "RunTest"), and click “Finish.”<br />
  3267.        <figure><a href=""><img src="" width="551" height="656" alt="Eclipse Java Class wizard" /></a><figcaption>The eclipse Java Class wizard.</figcaption></figure>
  3268.    </li>
  3269.    <li>Replace all code in your new class with the following code. The only thing you need to change is the path to <code>chromedriver.exe</code> on your computer:<br />
  3270. <pre class="break-out"><code class="language-bash">import org.openqa.selenium.WebDriver;
  3271. import;
  3273. /**
  3274. * @author Nils Schuette via
  3275. */
  3276. public class RunTest {
  3277.    static WebDriver webDriver;
  3278.    /**
  3279.     * @param args
  3280.     * @throws InterruptedException
  3281.     */
  3282.    public static void main(final String[] args) throws InterruptedException {
  3283.        // Telling the system where to find the chrome driver
  3284.        System.setProperty(
  3285.                "",
  3286.                "C:/PATH/TO/chromedriver.exe");
  3288.        // Open the Chrome browser
  3289.        webDriver = new ChromeDriver();
  3291.        // Waiting a bit before closing
  3292.        Thread.sleep(7000);
  3294.        // Closing the browser and WebDriver
  3295.        webDriver.close();
  3296.        webDriver.quit();
  3297.    }
  3298. }
  3299. </code></pre></li>
  3300. <li>Save your file, and click on the play button to run your code.<br />
  3301.    <figure><a href=""><img src="" width="693" height="254" alt="Run Eclipse project" /></a><figcaption>Running your first Selenium WebDriver project.</figcaption></figure>
  3302. </li>
  3303. <li>If you have done everything correctly, the code should open a new instance of the Chrome browser and close it shortly thereafter.<br />
  3304.    <figure><a href=""><img src="" width="1207" height="780" alt="Chrome Browser blank window" /></a><figcaption>The Chrome Browser opens itself magically. (<a href="">Large preview</a>)</figcaption></figure>
  3305. </li>
  3306. </ol>
  3308. <h3 id="testing-the-wordpress-admin-login">Testing The WordPress Admin Login</h3>
  3310. <p>Now I was optimistic that I could automate my first little feature test. I wanted the browser to navigate to one of my WordPress projects, login to the admin area and verify that the login was successful. So, what commands did I need to look up?</p>
  3312. <ol>
  3313. <li>Navigate to the login form,</li>
  3314. <li>Locate the input fields,</li>
  3315. <li>Type the username and password into the input fields,</li>
  3316. <li>Hit the login button,</li>
  3317. <li>Compare the current page’s headline to see if the login was successful.</li>
  3318. </ol>
  3320. <p>Again, after I had done all the necessary updates to my code and clicked on the run button in Eclipse, my browser started to magically work itself through the WordPress login. I successfully ran my first automated website test!</p>
  3322. <p>If you want to try this yourself, replace all of the code of your Java class with the following. I will go through the code in detail afterwards. Before executing the code, you must replace four values with your own:</p>
  3324. <ol>
  3325. <li><p>The location of your <code>chromedriver.exe</code> file (as above),</p></li>
  3327. <li><p>The URL of the WordPress admin account that you want to test,</p></li>
  3329. <li><p>The WordPress username,</p></li>
  3331. <li><p>The WordPress password.</p></li>
  3332. </ol>
  3334. <p>Then, save and let it run again. It will open Chrome, navigate to the login of your WordPress website, login and check whether the <code>h1</code> headline of the current page is &ldquo;Dashboard.&rdquo;</p>
  3336. <pre class="break-out"><code class="language-bash">import org.openqa.selenium.By;
  3337. import org.openqa.selenium.WebDriver;
  3338. import;
  3340. /**
  3341. * @author Nils Schuette via
  3342. */
  3343. public class RunTest {
  3344.    static WebDriver webDriver;
  3345.    /**
  3346.     * @param args
  3347.     * @throws InterruptedException
  3348.     */
  3349.    public static void main(final String[] args) throws InterruptedException {
  3350.        // Telling the system where to find the chrome driver
  3351.        System.setProperty(
  3352.                "",
  3353.                "C:/PATH/TO/chromedriver.exe");
  3355.        // Open the Chrome browser
  3356.        webDriver = new ChromeDriver();
  3358.        // Maximize the browser window
  3359.        webDriver.manage().window().maximize();
  3361.        if (testWordpresslogin()) {
  3362.            System.out.println("Test Wordpress Login: Passed");
  3363.        } else {
  3364.            System.out.println("Test Wordpress Login: Failed");
  3366.        }
  3368.        // Close the browser and WebDriver
  3369.        webDriver.close();
  3370.        webDriver.quit();
  3371.    }
  3373.    private static boolean testWordpresslogin() {
  3374.        try {
  3375.            // Open
  3376.            webDriver.navigate().to("");
  3378.            // Type in the username
  3379.            webDriver.findElement("user_login")).sendKeys("YOUR_USERNAME");
  3381.            // Type in the password
  3382.            webDriver.findElement("user_pass")).sendKeys("YOUR_PASSWORD");
  3384.            // Click the Submit button
  3385.            webDriver.findElement("wp-submit")).click();
  3387.            // Wait a little bit (7000 milliseconds)
  3388.            Thread.sleep(7000);
  3390.            // Check whether the h1 equals “Dashboard”
  3391.            if (webDriver.findElement(By.tagName("h1")).getText()
  3392.                    .equals("Dashboard")) {
  3393.                return true;
  3394.            } else {
  3395.                return false;
  3396.            }
  3398.        // If anything goes wrong, return false.
  3399.        } catch (final Exception e) {
  3400.            System.out.println(e.getClass().toString());
  3401.            return false;
  3402.        }
  3403.    }
  3404. }
  3405. </code></pre>
  3407. <p>If you have done everything correctly, your output in the Eclipse console should look something like this:</p>
  3409. <figure><a href=""><img src="" width="829" height="174" alt="Eclipse console test result." /></a><figcaption>The Eclipse console states that our first test has passed. (<a href="">Large preview</a>)</figcaption></figure>
  3411. <h3 id="understanding-the-code">Understanding The Code</h3>
  3413. <p>Because you are probably a web developer and have at least a basic understanding of other programming languages, I am sure you already grasp the basic idea of the code: We have created a separate method, <code>testWordpressLogin</code>, for the specific test case that is called from our main method.</p>
  3415. <p>Depending on whether the method returns true or false, you will get an output in your console telling you whether this specific test passed or failed.</p>
  3417. <p>This is not necessary, but this way you can easily add many more test cases to this class and still have readable code.</p>
  3419. <p>Now, step by step, here is what happens in our little program:</p>
  3421. <ol>
  3422.    <li>First, we tell our program where it can find the specific WebDriver for Chrome.<br />
  3423.        <pre class="break-out"><code class="language-bash">System.setProperty("","C:/PATH/TO/chromedriver.exe");</code></pre>
  3424.    </li>
  3425.    <li>We open the Chrome browser and maximize the browser window.<br />
  3426.        <pre class="break-out"><code class="language-bash">webDriver = new ChromeDriver();
  3427. webDriver.manage().window().maximize();</code></pre>
  3428. </li>
  3429. <li>This is where we jump into our submethod and check whether it returns true or false.<br />
  3430.    <pre class="break-out"><code class="language-bash">if (testWordpresslogin()) …</code></pre>
  3431. </li>
  3432. <li>The following part in our submethod might not be intuitive to understand:<br />The <code>try{…}catch{…}</code> blocks. If everything goes as expected, only the code in <code>try{…}</code> will be executed, but if anything goes wrong while executing <code>try{…}</code>, then the execution continuous in <code>catch{}</code>. Whenever you try to locate an element with <code>findElement</code> and the browser is not able to locate this element, it will throw an exception and execute the code in <code>catch{…}</code>. In my example, the test will be marked as "failed" whenever something goes wrong and the <code>catch{}</code> is executed.</li>
  3433. <li>In the submethod, we start by navigating to our WordPress admin area and locating the fields for the username and the password by looking for their IDs. Also, we type the given values in these fields.<br />
  3434.    <pre class="break-out"><code class="language-bash">webDriver.navigate().to("");
  3435. webDriver.findElement("user_login")).sendKeys("YOUR_USERNAME");
  3436. webDriver.findElement("user_pass")).sendKeys("YOUR_PASSWORD");</code></pre>
  3437. <br />
  3438. <figure><a href=""><img src="" width="460" height="454" alt="Wordpress login form" /></a><figcaption>Selenium fills out our login form</figcaption></figure>
  3439. </li>
  3440. <li>After filling in the login form, we locate the submit button by its ID and click it.<br />
  3441.    <pre class="break-out"><code class="language-bash">webDriver.findElement("wp-submit")).click();</code></pre>
  3442. </li>
  3443. <li>In order to follow the test visually, I include a 7-second pause here (7000 milliseconds = 7 seconds).<br />
  3444.    <pre class="break-out"><code class="language-bash">Thread.sleep(7000);</code></pre>
  3445. </li>
  3446. <li>If the login is successful, the <code>h1</code> headline of the current page should now be "Dashboard," referring to the WordPress admin area. Because the <code>h1</code> headline should exist only once on every page, I have used the tag name here to locate the element. In most other cases, the tag name is not a good locator because an HTML tag name is rarely unique on a web page. After locating the <code>h1</code>, we extract the text of the element with <code>getText()</code> and check whether it is equal to the string “Dashboard.” If the login is not successful, we would not find “Dashboard” as the current <code>h1</code>. Therefore, I’ve decided to use the <code>h1</code> to check whether the login is successful.<br />
  3447.    <pre class="break-out"><code class="language-javascript">if (webDriver.findElement(By.tagName("h1")).getText().equals("Dashboard"))
  3448.    {
  3449.        return true;
  3450.    } else {
  3451.        return false;
  3452.    }
  3453. </code></pre>
  3454. <br />
  3455. <figure><a href=""><img src="" width="1096" height="346" alt="Wordpress Dashboard" /></a><figcaption>Letting the WebDriver check, whether we have arrived on the Dashboard: Test passed! (<a href="">Large preview</a>)</figcaption></figure>
  3456. </li>
  3457. <li>If anything has gone wrong in the previous part of the submethod, the program would have jumped directly to the following part. The <code>catch</code> block will print the type of exception that happened to the console and afterwards return <code>false</code> to the main method.<br />
  3458.    <pre class="break-out"><code class="language-javascript">catch (final Exception e) {
  3459.            System.out.println(e.getClass().toString());
  3460.            return false;
  3461.        }</code></pre>
  3462. </li>
  3463. </ol>
  3465. <h3 id="adapting-the-test-case">Adapting The Test Case</h3>
  3467. <p>This is where it gets interesting if you want to adapt and add test cases of your own. You can see that we always call methods of the <code>webDriver</code> object to do something with the Chrome browser.</p>
  3469. <p>First, we maximize the window:</p>
  3471. <pre class="break-out"><code class="language-bash">webDriver.manage().window().maximize();</code></pre>
  3473. <p>Then, in a separate method, we navigate to our WordPress admin area:</p>
  3475. <pre class="break-out"><code class="language-bash">webDriver.navigate().to("");</code></pre>
  3477. <p>There are other methods of the <code>webDriver</code> object we can use. Besides the two above, you will probably use this one a lot:</p>
  3479. <pre class="break-out"><code class="language-bash">webDriver.findElement(By. …)</code></pre>
  3481. <p>The <code>findElement</code> method helps us find different elements in the DOM. There are different options to find elements:</p>
  3483. <ul>
  3484. <li><code></code></li>
  3485. <li><code>By.cssSelector</code></li>
  3486. <li><code>By.className</code></li>
  3487. <li><code>By.linkText</code></li>
  3488. <li><code></code></li>
  3489. <li><code>By.xpath</code></li>
  3490. </ul>
  3492. <p>If possible, I recommend using <code></code> because the ID of an element should always be unique (unlike, for example, the <code>className</code>), and it is usually not affected if the structure of your DOM changes (unlike, say, the <code>xPath</code>).</p>
  3494. <p><strong>Note</strong>: <em>You can read more about the different options for locating elements with WebDriver over <a href="">here</a>.</em></p>
  3496. <p>As soon as you get ahold of an element using the <code>findElement</code> method, you can call the different available methods of the element. The most common ones are <code>sendKeys</code>, <code>click</code> and <code>getText</code>.</p>
  3498. <p>We’re using <code>sendKeys</code> to fill in the login form:</p>
  3500. <pre class="break-out"><code class="language-bash">webDriver.findElement("user_login")).sendKeys("YOUR_USERNAME");</code></pre>
  3502. <p>We have used <code>click</code> to submit the login form by clicking on the submit button:</p>
  3504. <pre class="break-out"><code class="language-bash">webDriver.findElement("wp-submit")).click();</code></pre>
  3506. <p>And <code>getText</code> has been used to check what text is in the <code>h1</code> after the submit button is clicked:</p>
  3508. <pre class="break-out"><code class="language-bash">webDriver.findElement(By.tagName("h1")).getText()</code></pre>
  3510. <p><strong>Note</strong>: <em>Be sure to check out <a href="">all the available methods that you can use</a> with an element.</em></p>
  3512. <h3 id="conclusion">Conclusion</h3>
  3514. <p>Ever since I discovered the power of Selenium WebDriver, my life as a web developer has changed. I simply love it. The deeper I dive into the framework, the more possibilities I discover &mdash; running one test simultaneously in Chrome, Internet Explorer and Firefox or even on my smartphone, or taking screenshots automatically of different pages and comparing them. Today, I use Selenium WebDriver not only for testing purposes, but also to <a href="">automate repetitive tasks on the web</a>. Whenever I see an opportunity to automate my work on the web, I simply copy my initial WebDriver project and adapt it to the next task.</p>
  3516. <p>If you think that Selenium WebDriver is for you, I recommend looking at <a href="">Selenium’s documentation</a> to find out about all of the possibilities of Selenium (such as <a href="">running tasks simultaneously</a> on several (mobile) devices with Selenium Grid).</p>
  3518. <p>I look forward to hearing whether you find WebDriver as useful as I do!</p>
  3523. <div class="signature">
  3524.  <img src="" alt="Smashing Editorial">
  3525.  <span>(rb, ra, al, il)</span>
  3526. </div>
  3529. </div>
  3533.              </article>
  3534.            </body>
  3535.          </html>
  3536.        ]]></content:encoded>
  3537.      </item>
  3539.      <item>
  3542.          <author>Lou Franco</author>
  3544.        <title>Will SiriKit’s Intents Fit Your App? If So, Here’s How To Use Them</title>
  3545.        <link></link>
  3546.        <pubDate>Wed, 11 Apr 2018 17:00:44 +0200</pubDate>
  3547.        <guid></guid>
  3548.        <description>Since iOS 5, Siri has helped iPhone users send messages, set reminders and look up restaurants with Apple’s apps. Starting in iOS 10, we have been able to use Siri in some of our own apps as well.
  3549. In order to use this functionality, your app must fit within Apple’s predefined Siri “domains and intents.” In this article, we’ll learn about what those are and see whether our apps can use them.</description>
  3550.        <content:encoded><![CDATA[
  3551.          <html>
  3552.            <head>
  3553.              <meta charset="utf-8">
  3554.              <link rel="canonical" href="" />
  3555.              <title>Will SiriKit’s Intents Fit Your App? If So, Here’s How To Use Them</title>
  3556.            </head>
  3557.            <body>
  3558.              <article>
  3559.                <header>
  3560.                  <h1>Will SiriKit’s Intents Fit Your App? If So, Here’s How To Use Them</h1>
  3563.                    <address>Lou Franco</address>
  3565.                  <time datetime="2018-04-11T17:00:44&#43;02:00" class="op-published">2018-04-11T17:00:44+02:00</time>
  3566.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  3567.                </header>
  3570. <p>Since iOS 5, Siri has helped iPhone users send messages, set reminders and look up restaurants with Apple’s apps. Starting in iOS 10, we have been able to use Siri in some of our own apps as well.</p>
  3572. <p>In order to use this functionality, your app must fit within Apple’s predefined Siri “domains and intents.” In this article, we’ll learn about what those are and see whether our apps can use them. We’ll take a simple app that is a to-do list manager and learn how to add Siri support. We’ll also go through the Apple developer website’s guidelines on configuration and Swift code for a new type of extension that was introduced with SiriKit: the <em>Intents</em> extension.</p>
  3574. <p>When you get to the coding part of this article, you will need Xcode (at least version 9.x), and it would be good if you are familiar with iOS development in Swift because we’re going to add Siri to a small working app. We’ll go through the steps of setting up a extension on Apple’s developer website and of adding the Siri extension code to the app.</p>
  3576. <h3 id="hey-siri-why-do-i-need-you">“Hey Siri, Why Do I Need You?”</h3>
  3578. <p>Sometimes I use my phone while on my couch, with both hands free, and I can give the screen my full attention. Maybe I’ll text my sister to plan our mom’s birthday or reply to a question in Trello. I can see the app. I can tap the screen. I can type.</p>
  3580. <p>But I might be walking around my town, listening to a podcast, when a text comes in on my watch. My phone is in my pocket, and I can’t easily answer while walking.</p>
  3584.  <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  3585.    <div class="container product-panel--book__container">
  3586.      <div class="panel__description panel__description--book">
  3587.    <p>Getting the process <em>just</em> right ain't an easy task. That's why we've set up <strong>'this-is-how-I-work'-sessions</strong> — with smart cookies sharing what works really well for them. A part of the <a href="">Smashing Membership</a>, of course.</p>
  3588.      <a href="" class="btn btn--green btn--large">
  3589.        Explore features&nbsp;→
  3590.      </a>
  3591.      </div>
  3592.      <div class="panel__image panel__image--book">
  3593.        <a href="" class="books__book__image">
  3594.        <div class="books__book__img">
  3595.          <img src="" alt="Smashing TV, with live sessions for professional designers and developers." width="310" height="400">
  3596.        </div>
  3597.      </a>
  3598.      </div>
  3599.    </div>
  3600.  </aside>
  3606. <div class="c-garfield-the-cat">
  3609. <p>With Siri, I can hold down my headphone’s control button and say, “Text my sister that I’ll be there by two o’clock.” Siri is great when you are on the go and can’t give full attention to your phone or when the interaction is minor, but it requires several taps and a bunch of typing.</p>
  3611. <p>This is fine if I want to use Apple apps for these interactions. But some categories of apps, like messaging, have very popular alternatives. Other activities, such as booking a ride or reserving a table in a restaurant, are not even possible with Apple’s built-in apps but are perfect for Siri.</p>
  3613. <h3 id="apple-s-approach-to-voice-assistants">Apple’s Approach To Voice Assistants</h3>
  3615. <p>To enable Siri in third-party apps, Apple had to decide on a mechanism to take the sound from the user’s voice and somehow get it to the app in a way that it could fulfill the request. To make this possible, Apple requires the user to mention the app’s name in the request, but they had several options of what to do with the rest of the request.</p>
  3617. <ul>
  3618. <li><strong>It could have sent a sound file to the app.</strong><br />
  3619. The benefit of this approach is that the app could try to handle literally any request the user might have for it. Amazon or Google might have liked this approach because they already have sophisticated voice-recognition services. But most apps would not be able to handle this very easily.</li>
  3620. <li><strong>It could have turned the speech into text and sent that.</strong><br />
  3621. Because many apps don’t have sophisticated natural-language implementations, the user would usually have to stick to very particular phrases, and non-English support would be up to the app developer to implement.</li>
  3622. <li><strong>It could have asked you to provide a list of phrases that you understand.</strong><br />
  3623. This mechanism is closer to what Amazon does with Alexa (in its “skills” framework), and it enables far more uses of Alexa than SiriKit can currently handle. In an Alexa skill, you provide phrases with placeholder variables that Alexa will fill in for you. For example, “Alexa, remind me at <code>$TIME$</code> to <code>$REMINDER$</code>” &mdash; Alexa will run this phrase against what the user has said and tell you the values for <code>TIME</code> and <code>REMINDER</code>. As with the previous mechanism, the developer needs to do all of the translation, and there isn’t a lot of flexibility if the user says something slightly different.</li>
  3624. <li><strong>It could define a list of requests with parameters and send the app a structured request.</strong><br />
  3625. This is actually what Apple does, and the benefit is that it can support a variety of languages, and it does all of the work to try to understand all of the ways a user might phrase a request. The big downside is that you can only implement handlers for requests that Apple defines. This is great if you have, for example, a messaging app, but if you have a music-streaming service or a podcast player, you have no way to use SiriKit right now.</li>
  3626. </ul>
  3628. <p>Similarly, there are three ways for apps to talk back to the user: with sound, with text that gets converted, or by expressing the kind of thing you want to say and letting the system figure out the exact way to express it. The last solution (which is what Apple does) puts the burden of translation on Apple, but it gives you limited ways to use your own words to describe things.</p>
  3630. <p>The kinds of requests you can handle are defined in SiriKit’s domains and intents. An intent is a type of request that a user might make, like texting a contact or finding a photo. Each intent has a list of parameters &mdash; for example, texting requires a contact and a message.</p>
  3632. <p>A domain is just a group of related intents. Reading a text and sending a text are both in the messaging domain. Booking a ride and getting a location are in the ride-booking domain. There are domains for making VoIP calls, starting workouts, searching for photos and a few more things. SiriKit’s documentation contains a <a href="">full list of domains and their intents</a>.</p>
  3634. <p>A common criticism of Siri is that it seems unable to handle requests as well as Google and Alexa, and that the third-party voice ecosystem enabled by Apple’s competitors is richer.</p>
  3636. <p>I agree with those criticisms. If your app doesn’t fit within the current intents, then you can’t use SiriKit, and there’s nothing you can do. Even if your app does fit, you can’t control all of the words Siri says or understands; so, if you have a particular way of talking about things in your app, you can’t always teach that to Siri.</p>
  3638. <p>The hope of iOS developers is both that Apple will greatly expand its list of intents and that its natural language processing becomes much better. If it does that, then we will have a voice assistant that works without developers having to do translation or understand all of the ways of saying the same thing. And implementing support for structured requests is actually fairly simple to do &mdash; a lot easier than building a natural language parser.</p>
  3640. <p>Another big benefit of the intents framework is that it is not limited to Siri and voice requests. Even now, the Maps app can generate an intents-based request of your app (for example, a restaurant reservation). It does this programmatically (not from voice or natural language). If Apple allowed apps to discover each other’s exposed intents, we’d have a much better way for apps to work together, (as opposed to <a href="">x-callback style URLs</a>).</p>
  3642. <p>Finally, because an intent is a structured request with parameters, there is a simple way for an app to express that parameters are missing or that it needs help distinguishing between some options. Siri can then ask follow-up questions to resolve the parameters without the app needing to conduct the conversation.</p>
  3644. <h3 id="the-ride-booking-domain">The Ride-Booking Domain</h3>
  3646. <p>To understand domains and intents, let’s look at the <a href="">ride-booking domain</a>. This is the domain that you would use to ask Siri to get you a Lyft car.</p>
  3648. <p>Apple defines how to ask for a ride and how to get information about it, but there is actually no built-in Apple app that can actually handle this request. This is one of the few domains where a SiriKit-enabled app is required.</p>
  3650. <p>You can invoke one of the intents via voice or directly from Maps. Some of the intents for this domain are:</p>
  3652. <ul>
  3653. <li><strong>Request a ride</strong><br />
  3654. Use this one to book a ride. You’ll need to provide a pick-up and drop-off location, and the app might also need to know your party’s size and what kind of ride you want. A sample phrase might be, “Book me a ride with &lt;appname&gt;.”</li>
  3655. <li><strong>Get the ride’s status</strong><br />
  3656. Use this intent to find out whether your request was received and to get information about the vehicle and driver, including their location. The Maps app uses this intent to show an updated image of the car as it is approaching you.</li>
  3657. <li><strong>Cancel a ride</strong><br />
  3658. Use this to cancel a ride that you have booked.</li>
  3659. </ul>
  3661. <p>For any of this intents, Siri might need to know more information. As you’ll see when we implement an intent handler, your Intents extension can tell Siri that a required parameter is missing, and Siri will prompt the user for it.</p>
  3663. <p>The fact that intents can be invoked programmatically by Maps shows how intents might enable inter-app communication in the future.</p>
  3665. <p><strong>Note</strong>: <em>You can get a <a href="">full list of domains and their intents</a> on Apple’s developer website. There is also a <a href="">sample Apple app with many domains and intents implemented</a>, including ride-booking.</em></p>
  3667. <h3 id="adding-lists-and-notes-domain-support-to-your-app">Adding Lists And Notes Domain Support To Your App</h3>
  3669. <p>OK, now that we understand the basics of SiriKit, let’s look at how you would go about adding support for Siri in an app that involves a lot of configuration and a class for each intent you want to handle.</p>
  3671. <p>The rest of this article consists of the detailed steps to add Siri support to an app. There are five high-level things you need to do:</p>
  3673. <ol>
  3674. <li>Prepare to add a new extension to the app by creating provisioning profiles with new entitlements for it on Apple’s developer website.</li>
  3675. <li>Configure your app (via its <code>plist</code>) to use the entitlements.</li>
  3676. <li>Use Xcode’s template to get started with some sample code.</li>
  3677. <li>Add the code to support your Siri intent.</li>
  3678. <li>Configure Siri’s vocabulary via <code>plist</code>s.</li>
  3679. </ol>
  3681. <p>Don’t worry: We’ll go through each of these, explaining extensions and entitlements along the way.</p>
  3683. <p>To focus on just the Siri parts, I’ve prepared a simple to-do list manager, List-o-Mat.</p>
  3685. <figure><a href=""><img src="" width="552" height="850" alt="An animated GIF showing a demo of List-o-Mat" /></a><figcaption>Making lists in List-o-Mat (<a href="">Large preview</a>)</figcaption></figure>
  3687. <p><em>You can find the <a href="">full source of the sample, List-o-Mat, on GitHub</a>.</em></p>
  3689. <p>To create it, all I did was start with the Xcode Master-Detail app template and make both screens into a <code>UITableView</code>. I added a way to add and delete lists and items, and a way to check off items as done. All of the navigation is generated by the template.</p>
  3691. <p>To store the data, I used the <code>Codable</code> protocol, (<a href="">introduced at WWDC 2017</a>), which turns structs into JSON and saves it in a text file in the <code>documents</code> folder.</p>
  3694.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  3698. <p>I’ve deliberately kept the code very simple. If you have any experience with Swift and making view controllers, then you should have no problem with it.</p>
  3700. <p>Now we can go through the steps of adding SiriKit support. The high-level steps would be the same for any app and whichever domain and intents you plan to implement. We’ll mostly be dealing with Apple’s developer website, editing <code>plist</code>s and writing a bit of Swift.</p>
  3702. <p>For List-o-Mat, we’ll focus on the <a href="">lists and notes domain</a>, which is broadly applicable to things like note-taking apps and to-do lists.</p>
  3704. <p>In the lists and notes domain, we have the following intents that would make sense for our app.</p>
  3706. <ul>
  3707. <li>Get a list of tasks.</li>
  3708. <li>Add a new task to a list.</li>
  3709. </ul>
  3711. <p>Because the interactions with Siri actually happen outside of your app (maybe even when you app is not running), iOS uses an extension to implement this.</p>
  3713. <h3 id="the-intents-extension">The Intents Extension</h3>
  3715. <p>If you have not worked with extensions, you’ll need to know three main things:</p>
  3717. <ol>
  3718. <li>An extension is a separate process. It is delivered inside of your app’s bundle, but it runs completely on its own, with its own sandbox.</li>
  3719. <li>Your app and extension can communicate with each other by being in the same app group. The easiest way is via the group’s shared sandbox folders (so, they can read and write to the same files if you put them there).</li>
  3720. <li>Extensions require their own app IDs, profiles and entitlements.</li>
  3721. </ol>
  3723. <p>To add an extension to your app, start by logging into your <a href="">developer account</a> and going to the “Certificates, Identifiers, &amp; Profiles” section.</p>
  3725. <h4 id="updating-your-apple-developer-app-account-data">Updating Your Apple Developer App Account Data</h4>
  3727. <p>In our Apple developer account, the first thing we need to do is create an app group. Go to the “App Groups” section under “Identifiers” and add one.</p>
  3729. <figure class="break-out"><a href=""><img src="" width="1406" height="1126" alt="A screenshot of the Apple developer website dialog for registering an app group" /></a><figcaption>Registering an app group (<a href="">Large preview</a>)</figcaption></figure>
  3731. <p>It must start with <code>group</code>, followed by your usual reverse domain-based identifier. Because it has a prefix, you can use your app’s identifier for the rest.</p>
  3733. <p>Then, we need to update our app’s ID to use this group and to enable Siri:</p>
  3735. <ol>
  3736.    <li>Go to the “App IDs” section and click on your app’s ID;</li>
  3737.    <li>Click the “Edit” button;</li>
  3738.    <li>Enable app groups (if not enabled for another extension).<br />
  3739.        <figure class="break-out"><a href=""><img src="" width="709" height="252" alt="A screenshot of Apple developer website enabling app groups for an app ID" /></a><figcaption>Enable app groups (<a href="">Large preview</a>)</figcaption></figure>
  3740.    </li>
  3741.    <li>Then configure the app group by clicking the “Edit” button. Choose the app group from before.<br />
  3742.        <figure class="break-out"><a href=""><img src="" width="1342" height="280" alt="A screenshot of the Apple developer website dialog to set the app group name" /></a><figcaption>Set the name of the app group (<a href="">Large preview</a>)</figcaption></figure>
  3743.    </li>
  3744.    <li>Enable SiriKit.<br />
  3745.        <figure class="break-out"><a href=""><img src="" width="445" height="72" alt="A screenshot of SiriKit being enabled" /></a><figcaption>Enable SiriKit (<a href="">Large preview</a>)</figcaption></figure>
  3746.    </li>
  3747.    <li>Click “Done” to save it.</li>
  3748. </ol>
  3750. <p>Now, we need to create a new app ID for our extension:</p>
  3752. <ol>
  3753.    <li>In the same “App IDs” section, add a new app ID. This will be your app’s identifier, with a suffix. Do <em>not</em> use just <code>Intents</code> as a suffix because this name will become your module’s name in Swift and would then conflict with the real <code>Intents</code>.<br />
  3754.        <figure class="break-out"><a href=""><img src="" width="1332" height="552" alt="A screenshot of the Apple developer screen to create an app ID" /></a><figcaption>Create an app ID for the Intents extension (<a href="">Large preview</a>)</figcaption></figure>
  3755.    </li>
  3756.    <li>Enable this app ID for app groups as well (and set up the group as we did before).</li>
  3757. </ol>
  3759. <p>Now, create a development provisioning profile for the Intents extension, and regenerate your app’s provisioning profile. Download and install them as you would normally do.</p>
  3761. <p>Now that our profiles are installed, we need to go to Xcode and update the app’s entitlements.</p>
  3763. <h4 id="updating-your-app-s-entitlements-in-xcode">Updating Your App’s Entitlements In Xcode</h4>
  3765. <p>Back in Xcode, choose your project’s name in the project navigator. Then, choose your app’s main target, and go to the “Capabilities” tab. In there, you will see a switch to turn on Siri support.</p>
  3767. <figure class="break-out"><a href=""><img src="" width="1082" height="367" alt="A screenshot of Xcode’s entitlements screen showing SiriKit is enabled" /></a><figcaption>Enable SiriKit in your app's entitlements. (<a href="">Large preview</a>)</figcaption></figure>
  3769. <p>Further down the list, you can turn on app groups and configure it.</p>
  3771. <figure><a href=""><img src="" alt="A screenshot of Xcode's entitlements screen showing the app group is enabled and configured" width="464" height="214" /></a><figcaption>Configure the app's app group (<a href="">Large preview</a>)</figcaption></figure>
  3773. <p>If you have set it up correctly, you’ll see this in your app’s <code>.entitlements</code> file:</p>
  3775. <figure class="break-out"><a href=""><img src="" width="1084" height="222" alt="A screenshot of the App's plist showing that the entitlements are set" /></a><figcaption>The plist shows the entitlements that you set (<a href="">Large preview</a>)</figcaption></figure>
  3777. <p>Now, we are finally ready to add the Intents extension target to our project.</p>
  3779. <h4 id="adding-the-intents-extension">Adding The Intents Extension</h4>
  3781. <p>We’re finally ready to add the extension. In Xcode, choose “File” &rarr; “New Target.” This sheet will pop up:</p>
  3783. <figure><a href=""><img src="" width="1462" height="1052" alt="A screenshot showing the Intents extension in the New Target dialog in Xcode" /></a><figcaption>Add the Intents extension to your project (<a href="">Large preview</a>)</figcaption></figure>
  3785. <p>Choose “Intents Extension” and click the “Next” button. Fill out the following screen:</p>
  3787. <figure class="break-out"><a href=""><img src="" width="1078" height="572" alt="A screeenshot from Xcode showing how you configure the Intents extension" /></a><figcaption>Configure the Intents extension (<a href="">Large preview</a>)</figcaption></figure>
  3789. <p>The product name needs to match whatever you made the suffix in the intents app ID on the Apple developer website.</p>
  3791. <p>We are choosing not to add an intents UI extension. This isn’t covered in this article, but you could add it later if you need one. Basically, it’s a way to put your own branding and display style into Siri’s visual results.</p>
  3793. <p>When you are done, Xcode will create an intents handler class that we can use as a starting part for our Siri implementation.</p>
  3795. <h3 id="the-intents-handler-resolve-confirm-and-handle">The Intents Handler: Resolve, Confirm And Handle</h3>
  3797. <p>Xcode generated a new target that has a starting point for us.</p>
  3799. <p>The first thing you have to do is set up this new target to be in the same app group as the app. As before, go to the “Capabilities” tab of the target, and turn on app groups, and configure it with your group name. Remember, apps in the same group have a sandbox that they can use to share files with each other. We need this in order for Siri requests to get to our app.</p>
  3801. <p>List-o-Mat has a function that returns the group document folder. We should use it whenever we want to read or write to a shared file.</p>
  3803. <pre class="break-out"><code class="language-javascript">func documentsFolder() -> URL? {
  3804.    return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "")
  3805. }
  3806. </code></pre>
  3808. <p>For example, when we save the lists, we use this:</p>
  3810. <pre class="break-out"><code class="language-javascript">func save(lists: Lists) {
  3811.    guard let docsDir = documentsFolder() else {
  3812.        fatalError("no docs dir")
  3813.    }
  3815.    let url = docsDir.appendingPathComponent(fileName, isDirectory: false)
  3817.    // Encode lists as JSON and save to url
  3818. }
  3819. </code></pre>
  3821. <p>The Intents extension template created a file named <code>IntentHandler.swift</code>, with a class named <code>IntentHandler</code>. It also configured it to be the intents’ entry point in the extension’s <code>plist</code>.</p>
  3823. <figure class="break-out"><a href=""><img src="" width="577" height="29" alt="A screenshot from Xcode showing how the IntentHandler is configured as an entry point" /></a><figcaption>The intent extension plist configures IntentHandler as the entry point</figcaption></figure>
  3825. <p>In this same <code>plist</code>, you will see a section to declare the intents we support. We’re going to start with the one that allows searching for lists, which is named <code>INSearchForNotebookItemsIntent</code>. Add it to the array under <code>IntentsSupported</code>.</p>
  3827. <figure class="break-out"><a href=""><img src="" width="1066" height="182" alt="A screenshot in Xcode showing that the extension plist should list the intents it handles" /></a><figcaption>Add the intent’s name to the intents plist (<a href="">Large preview</a>)</figcaption></figure>
  3829. <p>Now, go to <code>IntentHandler.swift</code> and replace its contents with this code:</p>
  3831. <pre class="break-out"><code class="language-javascript">import Intents
  3833. class IntentHandler: INExtension {
  3834.    override func handler(for intent: INIntent) -> Any? {
  3835.        switch intent {
  3836.        case is INSearchForNotebookItemsIntent:
  3837.            return SearchItemsIntentHandler()
  3838.        default:
  3839.            return nil
  3840.        }
  3841.    }
  3842. }
  3843. </code></pre>
  3845. <p>The <code>handler</code> function is called to get an object to handle a specific intent. You can just implement all of the protocols in this class and return <code>self</code>, but we’ll put each intent in its own class to keep it better organized.</p>
  3847. <p>Because we intend to have a few different classes, let’s give them a common base class for code that we need to share between them:</p>
  3849. <pre><code class="language-javascript">class ListOMatIntentsHandler: NSObject {
  3850. }
  3851. </code></pre>
  3853. <p>The intents framework requires us to inherit from <code>NSObject</code>. We’ll fill in some methods later.</p>
  3855. <p>We start our search implementation with this:</p>
  3857. <pre><code class="language-javascript">class SearchItemsIntentHandler: ListOMatIntentsHandler,
  3858.                                                       INSearchForNotebookItemsIntentHandling {
  3859. }
  3860. </code></pre>
  3862. <p>To set an intent handler, we need to implement three basic steps</p>
  3864. <ol>
  3865. <li><strong>Resolve</strong> the parameters.<br />
  3866. Make sure required parameters are given, and disambiguate any you don’t fully understand.</li>
  3867. <li><strong>Confirm</strong> that the request is doable.<br />
  3868. This is often optional, but even if you know that each parameter is good, you might still need access to an outside resource or have other requirements.</li>
  3869. <li><strong>Handle</strong> the request.<br />
  3870. Do the thing that is being requested.</li>
  3871. </ol>
  3873. <p><code>INSearchForNotebookItemsIntent</code>, the first intent we’ll implement, can be used as a task search. The kinds of requests we can handle with this are, “In List-o-Mat, show the grocery store list” or “In List-o-Mat, show the store list.”</p>
  3875. <p>Aside: “List-o-Mat” is actually a bad name for a SiriKit app because Siri has a hard time with hyphens in apps. Luckily, SiriKit allows us to have alternate names and to provide pronunciation. In the app’s <code>Info.plist</code>, add this section:</p>
  3877. <figure><a href=""><img src="" width="566" height="78" alt="A screenshot from Xcode showing that the app plist can add alternate app names and pronunciations" /></a><figcaption>Add alternate app name's and pronunciation guides to the app plist</figcaption></figure>
  3879. <p>This allows the user to say “list oh mat” and for that to be understood as a single word (without hyphens). It doesn’t look ideal on the screen, but without it, Siri sometimes thinks “List” and “Mat” are separate words and gets very confused.</p>
  3881. <h4 id="resolve-figuring-out-the-parameters">Resolve: Figuring Out The Parameters</h4>
  3883. <p>For a search for notebook items, there are several parameters:</p>
  3885. <ol>
  3886. <li>the item type (a task, a task list, or a note),</li>
  3887. <li>the title of the item,</li>
  3888. <li>the content of the item,</li>
  3889. <li>the completion status (whether the task is marked done or not),</li>
  3890. <li>the location it is associated with,</li>
  3891. <li>the date it is associated with.</li>
  3892. </ol>
  3894. <p>We require only the first two, so we’ll need to write resolve functions for them. <code>INSearchForNotebookItemsIntent</code> has methods for us to implement.</p>
  3896. <p>Because we only care about showing task lists, we’ll hardcode that into the resolve for item type. In <code>SearchItemsIntentHandler</code>, add this:</p>
  3898. <pre class="break-out"><code class="language-javascript">func resolveItemType(for intent: INSearchForNotebookItemsIntent,
  3899.                         with completion: @escaping (INNotebookItemTypeResolutionResult) -> Void) {
  3901.    completion(.success(with: .taskList))
  3902. }
  3903. </code></pre>
  3905. <p>So, no matter what the user says, we’ll be searching for task lists. If we wanted to expand our search support, we’d let Siri try to figure this out from the original phrase and then just use <code>completion(.needsValue())</code> if the item type was missing. Alternatively, we could try to guess from the title by seeing what matches it. In this case, we would complete with success when Siri knows what it is, and we would use <code>completion(.notRequired())</code> when we are going to try multiple possibilities.</p>
  3907. <p>Title resolution is a little trickier. What we want is for Siri to use a list if it finds one with an exact match for what you said. If it’s unsure or if there is more than one possibility, then we want Siri to ask us for help in figuring it out. To do this, SiriKit provides a set of resolution enums that let us express what we want to happen next.</p>
  3909. <p>So, if you say “Grocery Store,” then Siri would have an exact match. But if you say “Store,” then Siri would present a menu of matching lists.</p>
  3911. <p>We’ll start with this function to give the basic structure:</p>
  3913. <pre class="break-out"><code class="language-javascript">func resolveTitle(for intent: INSearchForNotebookItemsIntent, with completion: @escaping (INSpeakableStringResolutionResult) -> Void) {
  3914.    guard let title = intent.title else {
  3915.        completion(.needsValue())
  3916.        return
  3917.    }
  3919.    let possibleLists = getPossibleLists(for: title)
  3920.    completeResolveListName(with: possibleLists, for: title, with: completion)
  3921. }
  3922. </code></pre>
  3924. <p>We’ll implement <code>getPossibleLists(for:)</code> and <code>completeResolveListName(with:for:with:)</code> in the <code>ListOMatIntentsHandler</code> base class.</p>
  3926. <p><code>getPossibleLists(for:)</code> needs to try to fuzzy match the title that Siri passes us with the actual list names.</p>
  3928. <pre class="break-out"><code class="language-javascript">public func getPossibleLists(for listName: INSpeakableString) -> [INSpeakableString] {
  3929.    var possibleLists = [INSpeakableString]()
  3930.    for l in loadLists() {
  3931.        if == listName.spokenPhrase.lowercased() {
  3932.            return [INSpeakableString(spokenPhrase:]
  3933.        }
  3934.        if || listName.spokenPhrase.lowercased() == "all" {
  3935.            possibleLists.append(INSpeakableString(spokenPhrase:
  3936.        }
  3937.    }
  3938.    return possibleLists
  3939. }
  3940. </code></pre>
  3942. <p>We loop through all of our lists. If we get an exact match, we’ll return it, and if not, we’ll return an array of possibilities. In this function, we’re simply checking to see whether the word the user said is contained in a list name (so, a pretty simple match). This lets “Grocery” match “Grocery Store.” A more advanced algorithm might try to match based on words that sound the same (for example, with the <a href="">Soundex algorithm</a>),</p>
  3944. <p><code>completeResolveListName(with:for:with:)</code> is responsible for deciding what to do with this list of possibilities.</p>
  3946. <pre class="break-out"><code class="language-javascript">public func completeResolveListName(with possibleLists: [INSpeakableString], for listName: INSpeakableString, with completion: @escaping (INSpeakableStringResolutionResult) -> Void) {
  3947.    switch possibleLists.count {
  3948.    case 0:
  3949.        completion(.unsupported())
  3950.    case 1:
  3951.        if possibleLists[0].spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() {
  3952.            completion(.success(with: possibleLists[0]))
  3953.        } else {
  3954.            completion(.confirmationRequired(with: possibleLists[0]))
  3955.        }
  3956.    default:
  3957.        completion(.disambiguation(with: possibleLists))
  3958.    }
  3959. }
  3960. </code></pre>
  3962. <p>If we got an exact match, we tell Siri that we succeeded. If we got one inexact match, we tell Siri to ask the user if we guessed it right.</p>
  3964. <p>If we got multiple matches, then we use <code>completion(.disambiguation(with: possibleLists))</code> to tell Siri to show a list and let the user pick one.</p>
  3966. <p>Now that we know what the request is, we need to look at the whole thing and make sure we can handle it.</p>
  3968. <h4 id="confirm-check-all-of-your-dependencies">Confirm: Check All Of Your Dependencies</h4>
  3970. <p>In this case, if we have resolved all of the parameters, we can always handle the request. Typical <code>confirm()</code> implementations might check the availability of external services or check authorization levels.</p>
  3972. <p>Because <code>confirm()</code> is optional, we could just do nothing, and Siri would assume we could handle any request with resolved parameters. To be explicit, we could use this:</p>
  3974. <pre class="break-out"><code class="language-javascript">func confirm(intent: INSearchForNotebookItemsIntent, completion: @escaping (INSearchForNotebookItemsIntentResponse) -> Void) {
  3975.    completion(INSearchForNotebookItemsIntentResponse(code: .success, userActivity: nil))
  3976. }
  3977. </code></pre>
  3979. <p>This means we can handle anything.</p>
  3981. <h4 id="handle-do-it">Handle: Do It</h4>
  3983. <p>The final step is to handle the request.</p>
  3985. <pre class="break-out"><code class="language-javascript">func handle(intent: INSearchForNotebookItemsIntent, completion: @escaping (INSearchForNotebookItemsIntentResponse) -> Void) {
  3986.    guard
  3987.        let title = intent.title,
  3988.        let list = loadLists().filter({ $ == title.spokenPhrase.lowercased()}).first
  3989.    else {
  3990.        completion(INSearchForNotebookItemsIntentResponse(code: .failure, userActivity: nil))
  3991.        return
  3992.    }
  3994.    let response = INSearchForNotebookItemsIntentResponse(code: .success, userActivity: nil)
  3995.    response.tasks = {
  3996.        return INTask(title: INSpeakableString(spokenPhrase: $,
  3997.                      status: $0.done ? INTaskStatus.completed : INTaskStatus.notCompleted,
  3998.                      taskType: INTaskType.notCompletable,
  3999.                      spatialEventTrigger: nil,
  4000.                      temporalEventTrigger: nil,
  4001.                      createdDateComponents: nil,
  4002.                      modifiedDateComponents: nil,
  4003.                      identifier: "\(\t\($")
  4004.    }
  4005.    completion(response)
  4006. }
  4007. </code></pre>
  4009. <p>First, we find the list based on the title. At this point, <code>resolveTitle</code> has already made sure that we’ll get an exact match. But if there’s an issue, we can still return a failure.</p>
  4011. <p>When we have a failure, we have the option of passing a user activity. If your app uses <a href="">Handoff</a> and has a way to handle this exact type of request, then Siri might try deferring to your app to try the request there. It will not do this when we are in a voice-only context (for example, you started with “Hey Siri”), and it doesn’t guarantee that it will do it in other cases, so don’t count on it.</p>
  4013. <p>This is now ready to test. Choose the intent extension in the target list in Xcode. But before you run it, edit the scheme.</p>
  4015. <figure><a href=""><img src="" width="326" height="116" alt="A screenshot from Xcode showing how to edit a scheme" /></a><figcaption>Edit the scheme of the the intent to add a sample phrase for debugging.</figcaption></figure>
  4017. <p>That brings up a way to provide a query directly:</p>
  4019. <figure class="break-out"><a href=""><img src="" width="710" height="286" alt="A screenshot from Xcode showing the edit scheme dialog" /></a><figcaption>Add the sample phrase to the Run section of the scheme. (<a href="">Large preview</a>)</figcaption></figure>
  4021. <p>Notice, I am using “ListOMat” because of the hyphens issue mentioned above. Luckily, it’s pronounced the same as my app’s name, so it should not be much of an issue.</p>
  4023. <p>Back in the app, I made a “Grocery Store” list and a “Hardware Store” list. If I ask Siri for the “store” list, it will go through the disambiguation path, which looks like this:</p>
  4025. <figure><a href=""><img src="" width="602" height="884" alt="An animated GIF showing Siri handling a request to show the Store list" /></a><figcaption>Siri handles the request by asking for clarification. (<a href="">Large preview</a>)</figcaption></figure>
  4027. <p>If you say “Grocery Store,” then you’ll get an exact match, which goes right to the results.</p>
  4029. <h3 id="adding-items-via-siri">Adding Items Via Siri</h3>
  4031. <p>Now that we know the basic concepts of resolve, confirm and handle, we can quickly add an intent to add an item to a list.</p>
  4033. <p>First, add <code>INAddTasksIntent</code> to the extension’s plist:</p>
  4035. <figure><a href=""><img src="" width="588" height="110" alt="A screenshot in XCode showing the new intent being added to the plist" /></a><figcaption>Add the INAddTasksIntent to the extension plist (<a href="">Large preview</a>)</figcaption></figure>
  4037. <p>Then, update our <code>IntentHandler</code>’s <code>handle</code> function.</p>
  4039. <pre><code class="language-javascript">override func handler(for intent: INIntent) -> Any? {
  4040.    switch intent {
  4041.    case is INSearchForNotebookItemsIntent:
  4042.        return SearchItemsIntentHandler()
  4043.    case is INAddTasksIntent:
  4044.        return AddItemsIntentHandler()
  4045.    default:
  4046.        return nil
  4047.    }
  4048. }
  4049. </code></pre>
  4051. <p>Add a stub for the new class:</p>
  4053. <pre class="break-out"><code class="language-javascript">class AddItemsIntentHandler: ListOMatIntentsHandler, INAddTasksIntentHandling {
  4054. }
  4055. </code></pre>
  4057. <p>Adding an item needs a similar <code>resolve</code> for searching, except with a target task list instead of a title.</p>
  4059. <pre class="break-out"><code class="language-javascript">func resolveTargetTaskList(for intent: INAddTasksIntent, with completion: @escaping (INTaskListResolutionResult) -> Void) {
  4061.    guard let title = intent.targetTaskList?.title else {
  4062.        completion(.needsValue())
  4063.        return
  4064.    }
  4066.    let possibleLists = getPossibleLists(for: title)
  4067.    completeResolveTaskList(with: possibleLists, for: title, with: completion)
  4068. }
  4069. </code></pre>
  4071. <p><code>completeResolveTaskList</code> is just like <code>completeResolveListName</code>, but with slightly different types (a task list instead of the title of a task list).</p>
  4073. <pre class="break-out"><code class="language-javascript">public func completeResolveTaskList(with possibleLists: [INSpeakableString], for listName: INSpeakableString, with completion: @escaping (INTaskListResolutionResult) -> Void) {
  4075.    let taskLists = {
  4076.        return INTaskList(title: $0, tasks: [], groupName: nil, createdDateComponents: nil, modifiedDateComponents: nil, identifier: nil)
  4077.    }
  4079.    switch possibleLists.count {
  4080.    case 0:
  4081.        completion(.unsupported())
  4082.    case 1:
  4083.        if possibleLists[0].spokenPhrase.lowercased() == listName.spokenPhrase.lowercased() {
  4084.            completion(.success(with: taskLists[0]))
  4085.        } else {
  4086.            completion(.confirmationRequired(with: taskLists[0]))
  4087.        }
  4088.    default:
  4089.        completion(.disambiguation(with: taskLists))
  4090.    }
  4091. }
  4092. </code></pre>
  4094. <p>It has the same disambiguation logic and behaves in exactly the same way. Saying “Store” needs to be disambiguated, and saying “Grocery Store” would be an exact match.</p>
  4096. <p>We’ll leave <code>confirm</code> unimplemented and accept the default. For <code>handle</code>, we need to add an item to the list and save it.</p>
  4098. <pre class="break-out"><code class="language-javascript">func handle(intent: INAddTasksIntent, completion: @escaping (INAddTasksIntentResponse) -> Void) {
  4099.    var lists = loadLists()
  4100.    guard
  4101.        let taskList = intent.targetTaskList,
  4102.        let listIndex = lists.index(where: { $ == taskList.title.spokenPhrase.lowercased() }),
  4103.        let itemNames = intent.taskTitles, itemNames.count > 0
  4104.    else {
  4105.            completion(INAddTasksIntentResponse(code: .failure, userActivity: nil))
  4106.            return
  4107.    }
  4109.    // Get the list
  4110.    var list = lists[listIndex]
  4112.    // Add the items
  4113.    var addedTasks = [INTask]()
  4114.    for item in itemNames {
  4115.        list.addItem(name: item.spokenPhrase, at: list.items.count)
  4116.        addedTasks.append(INTask(title: item, status: .notCompleted, taskType: .notCompletable, spatialEventTrigger: nil, temporalEventTrigger: nil, createdDateComponents: nil, modifiedDateComponents: nil, identifier: nil))
  4117.    }
  4119.    // Save the new list
  4120.    lists[listIndex] = list
  4121.    save(lists: lists)
  4123.    // Respond with the added items
  4124.    let response = INAddTasksIntentResponse(code: .success, userActivity: nil)
  4125.    response.addedTasks = addedTasks
  4126.    completion(response)
  4127. }
  4128. </code></pre>
  4130. <p>We get a list of items and a target list. We look up the list and add the items. We also need to prepare a response for Siri to show with the added items and send it to the completion function.</p>
  4132. <p>This function can handle a phrase like, “In ListOMat, add apples to the grocery list.” It can also handle a list of items like, “rice, onions and olives.”</p>
  4134. <figure><a href=""><img src="" width="559" height="981" alt="A screenshot of the simulator showing Siri adding items to the grocery store list" /></a><figcaption>Siri adds a few items to the grocery store list</figcaption></figure>
  4136. <h3 id="almost-done-just-a-few-more-settings">Almost Done, Just A Few More Settings</h3>
  4138. <p>All of this will work in your simulator or local device, but if you want to submit this, you’ll need to add a <code>NSSiriUsageDescription</code> key to your app’s <code>plist</code>, with a string that describes what you are using Siri for. Something like “Your requests about lists will be sent to Siri” is fine.</p>
  4140. <p>You should also add a call to:</p>
  4142. <pre><code class="language-javascript">INPreferences.requestSiriAuthorization { (status) in }
  4143. </code></pre>
  4145. <p>Put this in your main view controller’s <code>viewDidLoad</code> to ask the user for Siri access. This will show the message you configured above and also let the user know that they could be using Siri for this app.</p>
  4147. <figure><a href=""><img src="" width="277" height="234" alt="A screenshot of the dialog that a device pops up when you ask for Siri permission" /></a><figcaption>The device will ask for permission if you try to use Siri in the app.</figcaption></figure>
  4149. <p>Finally, you’ll need to tell Siri what to tell the user if the user asks what your app can do, by providing some <a href="">sample phrases</a>:</p>
  4151. <ol>
  4152. <li>Create a <code>plist</code> file in your app (not the extension), named <code>AppIntentVocabulary.plist</code>.</li>
  4153. <li>Fill out the intents and phrases that you support.</li>
  4154. </ol>
  4156. <figure class="break-out"><a href=""><img src="" width="717" height="244" alt="A screenshot of the AppIntentVocabulary.plist showing sample phrases" /></a><figcaption>Add an <code>AppIntentVocabulary.plist</code> to list the sample phrases that will invoke the intent you handle. (<a href="">Large preview</a>)</figcaption></figure>
  4158. <p>There is no way to really know all of the phrases that Siri will use for an intent, but Apple does provide a few samples for each intent in its documentation. The <a href="">sample phrases for task-list searching</a> show us that Siri can understand “Show me all my notes on &lt;appName&gt;,” but I found other phrases by trial and error (for example, Siri understands what “lists” are too, not just notes).</p>
  4160. <h3 id="summary">Summary</h3>
  4162. <p>As you can see, adding Siri support to an app has a lot of steps, with a lot of configuration. But the code needed to handle the requests was fairly simple.</p>
  4164. <p>There are a lot of steps, but each one is small, and you might be familiar with a few of them if you have used extensions before.</p>
  4166. <p>Here is what you’ll need to prepare for a new extension on Apple’s developer website:</p>
  4168. <ol>
  4169. <li>Make an app ID for an Intents extension.</li>
  4170. <li>Make an app group if you don’t already have one.</li>
  4171. <li>Use the app group in the app ID for the app and extension.</li>
  4172. <li>Add Siri support to the app’s ID.</li>
  4173. <li>Regenerate the profiles and download them.</li>
  4174. </ol>
  4176. <p>And here are the steps in Xcode for creating Siri’s Intents extension:</p>
  4178. <ol>
  4179. <li>Add an Intents extension using the Xcode template.</li>
  4180. <li>Update the entitlements of the app and extension to match the profiles (groups and Siri support).</li>
  4181. <li>Add your intents to the extension’s <code>plist</code>.</li>
  4182. </ol>
  4184. <p>And you’ll need to add code to do the following things:</p>
  4186. <ol>
  4187. <li>Use the app group sandbox to communicate between the app and extension.</li>
  4188. <li>Add classes to support each intent with resolve, confirm and handle functions.</li>
  4189. <li>Update the generated <code>IntentHandler</code> to use those classes.</li>
  4190. <li>Ask for Siri access somewhere in your app.</li>
  4191. </ol>
  4193. <p>Finally, there are some Siri-specific configuration settings:</p>
  4195. <ol>
  4196. <li>Add the Siri support security string to your app’s <code>plist</code>.</li>
  4197. <li>Add sample phrases to an <code>AppIntentVocabulary.plist</code> file in your app.</li>
  4198. <li>Run the intent target to test; edit the scheme to provide the phrase.</li>
  4199. </ol>
  4201. <p>OK, that is a lot, but if your app fits one of Siri’s domains, then users will expect that they can interact with it via voice. And because the competition for voice assistants is so good, we can only expect that WWDC 2018 will bring a bunch more domains and, hopefully, much better Siri.</p>
  4203. <h4 id="further-reading">Further Reading</h4>
  4205. <ul>
  4206. <li>“<a href="">SiriKit</a>,” Apple<br />
  4207. The technical documentation contains the full list of domains and intents.</li>
  4208. <li>“<a href="">Guides and Sample Code</a>,” Apple<br />
  4209. Includes code for many domains.</li>
  4210. <li>“<a href="">Introducing SiriKit</a>” (video, Safari only), WWDC 2016 Apple</li>
  4211. <li>“<a href="">What’s New in SiriKit</a>” (video, Safari only), WWDC 2017, Apple<br />
  4212. Apple introduces lists and notes</li>
  4213. <li>“<a href="">Lists and Notes</a>,” Apple<br />
  4214. The full list of lists and notes intents.</li>
  4215. </ul>
  4220. <div class="signature">
  4221.  <img src="" alt="Smashing Editorial">
  4222.  <span>(da, ra, al, il)</span>
  4223. </div>
  4226. </div>
  4230.              </article>
  4231.            </body>
  4232.          </html>
  4233.        ]]></content:encoded>
  4234.      </item>
  4236.      <item>
  4239.          <author>Christopher Murphy</author>
  4241.        <title>Becoming A UX Leader</title>
  4242.        <link></link>
  4243.        <pubDate>Wed, 11 Apr 2018 12:50:15 +0200</pubDate>
  4244.        <guid></guid>
  4245.        <description>(This is a sponsored article.) In my previous article on Building UX Teams, I explored the rapidly growing need for UX teams as a result of the emergence of design as a wider business driver. As teams grow, so too does a need for leaders to nurture and guide them.
  4246. In my final article in this series on user experience design, I’ll explore the different characteristics of an effective UX leader, and provide some practical advice about growing into a leadership role.</description>
  4247.        <content:encoded><![CDATA[
  4248.          <html>
  4249.            <head>
  4250.              <meta charset="utf-8">
  4251.              <link rel="canonical" href="" />
  4252.              <title>Becoming A UX Leader</title>
  4253.            </head>
  4254.            <body>
  4255.              <article>
  4256.                <header>
  4257.                  <h1>Becoming A UX Leader</h1>
  4260.                    <address>Christopher Murphy</address>
  4262.                  <time datetime="2018-04-11T12:50:15&#43;02:00" class="op-published">2018-04-11T12:50:15+02:00</time>
  4263.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  4264.                </header>
  4267. <p>(<em>This is a sponsored article</em>.) In my previous article on <a href="">Building UX Teams</a>, I explored the rapidly growing need for UX teams as a result of the emergence of design as a wider business driver. As teams grow, so too does a need for leaders to nurture and guide them.</p>
  4269. <p>In my final article in this series on user experience design, I’ll explore the different characteristics of an effective UX leader, and provide some practical advice about growing into a leadership role.</p>
  4271. <p>I’ve worked in many organizations &mdash; both large and small, and in both the private and public sectors &mdash; and, from experience, <strong>leadership is a rare quality that is far from commonplace</strong>. Truly inspiring leaders are few and far between; if you’re fortunate to work with one, make every effort to learn from them.</p>
  4273. <p>Managers that have risen up the ranks don’t automatically become great leaders, and perhaps one of the biggest lessons I’ve learned is that truly inspirational leaders &mdash; those that inspire passion and commitment &mdash; aren’t as commonplace as you’d think.</p>
  4275. <p>A UX leader is truly a hybrid, perhaps more so than in many other &mdash; more traditional &mdash; businesses. A UX leader needs to encompass a wide range of skills:</p>
  4277. <ul>
  4278. <li>Establishing, driving and articulating a vision;</li>
  4279. <li>Communicating across different teams, including design, research, writing, engineering, and business (no small undertaking!);</li>
  4280. <li>Acting as a champion for user-focused design;</li>
  4281. <li>Mapping design decisions to key performance indicators (KPIs), and vice-versa, so that success can be measured; and</li>
  4282. <li>Managing a team, ensuring all the team’s members are challenged and motivated.</li>
  4283. </ul>
  4285. <p>UX leadership is not unlike being bi-lingual &mdash; or, more accurately, multi-lingual &mdash; and it’s a skill that requires dexterity so that nothing gets lost in translation.</p>
  4287. <p>This hybrid skill set can seem daunting, but &mdash; like anything &mdash; <strong>the attributes of leadership can be learned and developed</strong>. In my final article in this series of ten, I’ll explore what defines a leader and focus on the qualities and attributes needed to step up to this important role.</p>
  4290. <div class="c-garfield-the-cat">
  4293. <h3 id="undertaking-a-skills-audit">Undertaking A Skills Audit</h3>
  4295. <p>Every leader is different, and every leader will be informed by the different experiences they have accumulated to date. There are, however, certain qualities and attributes that leaders tend to share in common.</p>
  4297. <p><strong>Great leaders demonstrate self-awareness</strong>. They tend to have the maturity to have looked themselves in the mirror and identified aspects of their character that they may need to develop if they are to grow as leaders.</p>
  4299. <p>Having identified their strengths and weaknesses and pinpointing areas for improvement, they will have an idea of what they know and — equally important — what they don’t know. As Donald Rumsfeld famously put it:</p>
  4301. <blockquote>“There are known knowns: there are things we know we know. We also know there are known unknowns: That is to say, we know there are some things we do not know. But there are also unknown unknowns: the things we don't know we don't know.”</blockquote>
  4303. <p>Rumsfeld might have been talking about unknown unknowns in a conflict scenario, but his insight applies equally to the world of leadership. To grow as a leader, it’s important to widen your knowledge so that it addresses both:</p>
  4305. <ul>
  4306. <li><strong>The Known Unknowns</strong><br />
  4307. Skills you know that you don’t know, which you can identify through a self-critical skills audit; and</li>
  4308. <li><strong>The Unknown Unknowns</strong><br />
  4309. Skills you don’t know you don’t know, which you can identify through inviting your peers to review your strengths and weaknesses.</li>
  4310. </ul>
  4312. <p>In short, a skills audit will equip you with a roadmap that you can use as a map to plot a path from where you are now to where you want to be.</p>
  4324. <figure >
  4325. <a href="">
  4326. <img
  4327. srcset=",q_auto/w_400/ 400w,
  4328.,q_auto/w_800/ 800w,
  4329.,q_auto/w_1200/ 1200w,
  4330.,q_auto/w_1600/ 1600w,
  4331.,q_auto/w_2000/ 2000w"
  4332. src=",q_auto/w_400/"
  4333. sizes="100vw"
  4334. alt="a map that you can use to plot a path from where you are now to where you want to be"
  4335. />
  4336. </a>
  4338. <figcaption class="op-vertical-bottom">
  4339. Undertaking a skills audit will enable you to develop a map that you can use to plot a path from where you are now to where you want to be. (<a href=''>Large preview</a>)
  4340. </figcaption>
  4341. </figure>
  4344. <p>To become an effective leader is to embark upon a journey, identifying the gaps in your knowledge and &mdash; step by step &mdash; addressing these gaps so that you’re prepared for the leadership role ahead.</p>
  4346. <h4 id="identifying-the-gaps-in-your-knowledge">Identifying The Gaps In Your Knowledge</h4>
  4348. <p>One way to identify the gaps in your knowledge is to undertake an honest and self-reflective &lsquo;skills audit&rsquo; while <strong>making an effort to both learn about yourself and learn about the environment</strong> you are working within.</p>
  4350. <p>To become a UX leader, it’s critical to develop this self-awareness, identifying the knowledge you need to acquire by undertaking both self-assessments and peer assessments. With your gaps in knowledge identified, it’s possible to build a learning pathway to address these gaps.</p>
  4352. <p>In the introduction, I touched on a brief list of skills that an effective and well-equipped leader needs to develop. That list is just the tip of a very large iceberg. At the very least, a hybrid UX leader needs to equip themselves by:</p>
  4354. <ul>
  4355. <li>Developing an awareness of context, expanding beyond the realms of design to encompass a broader business context;</li>
  4356. <li>Understanding and building relationships with a cross-section of team members;</li>
  4357. <li>Identifying outcomes and goals, establishing KPIs that will help to deliver these successfully;</li>
  4358. <li>Managing budgets, both soft and hard; and</li>
  4359. <li>Planning and mapping time, often across a diversified team.</li>
  4360. </ul>
  4362. <p>These are just a handful of <strong>skills that an effective UX leader needs to develop</strong>. If you&rsquo;re anything like me, hardly any of this was taught at art school, so you’ll need to learn these skills yourself<strong>.</strong> This article will help to point you in the right direction. I’ve also provided a list of required reading for reference to ensure you’re well covered.</p>
  4364. <h4 id="a-360º-assessment">A 360º Assessment</h4>
  4366. <p>A 360º degree leadership assessment is a form of <a href="">feedback for leaders</a>. Drawn from the world of business, but equally applicable to the world of user experience, it is an excellent way to measure your effectiveness and influence as a leader.</p>
  4368. <p>Unlike a top-down appraisal, where a leader or manager appraises an employee underneath them in the hierarchy, a 360º assessment involves inviting your colleagues &mdash; at your peer level &mdash; to appraise you, highlighting your strengths and weaknesses.</p>
  4370. <p>This isn’t easy &mdash; and can lead to some uncomfortable home truths &mdash; but it can prove a critical tool in helping you to identify the qualities you need to work on. You might, for example, consider yourself an excellent listener only to discover that your colleagues feel like this is something you need to work on.</p>
  4372. <p>This willingness to put yourself under the spotlight, identify your weaknesses, address these, and develop yourself is one of the defining characteristics of leaders. <strong>Great leaders are always learning</strong> and they aren’t afraid to admit that fact.</p>
  4374. <p>A 360º assessment is a great way to uncover your ‘unknown unknowns’, i.e. the gaps in your knowledge that you aren’t aware of. With these discoveries in hand, it’s possible to build ‘a learning road-map’ that will allow you to develop the skills you need.</p>
  4376. <h4 id="build-a-roadmap">Build A Roadmap</h4>
  4378. <p>With the gaps in your knowledge identified, it’s important to adopt some strategies to address these gaps. Great leaders understand that learning is a lifelong process and to transition into a leadership role will require — inevitably — the acquisition of new skills.</p>
  4380. <p>To develop as a leader, it’s important to address your knowledge gaps in a considered and systematic manner. By working back from your skills audit, <strong>identify what you need to work on</strong> and build a learning programme accordingly.</p>
  4382. <p>This will inevitably involve developing an understanding of different domains of knowledge, but that’s the leader’s path. The important thing is to take it step by step and, of course, to take that first step.</p>
  4384. <p>We are fortunate now to be working in an age in which we have an abundance of learning materials at our fingertips. We no longer need to enroll in a course at a university to learn; we can put together our own bespoke learning programmes.</p>
  4386. <p>We now have so many tools we can use, from paid resources like <a href="">Skillshare</a> which offers &ldquo;access to a learning platform for personalized, on-demand learning,&rdquo; to free resources like <a href="">FutureLearn</a> which offers the ability to “learn new skills, pursue your interests and advance your career.”</p>
  4388. <p>In short, <strong>you have everything you need to enhance your career</strong> just a click away.</p>
  4390. <h3 id="it-s-not-just-you">It’s Not Just You</h3>
  4392. <p>Great leaders understand that it’s not about the effort of individuals, working alone. It’s about the effort of individuals — working collectively. Looking back through the history of innovation, we can see that most (if not all) of the greatest breakthroughs were driven by teams that were motivated by inspirational leaders.</p>
  4394. <p>Thomas Edison didn’t invent the lightbulb alone; he had an ‘<a href="">invention factory</a>’ housed in a series of research laboratories. Similarly, when we consider the development of contemporary graphical user interfaces (GUIs), these emerged from the teamwork of <a href="">Xerox PARC</a>. The <a href="">iPod</a> was similarly conceived.</p>
  4396. <p>Great leaders understand that it’s not about them as individuals, but <strong>it’s about the teams they put together</strong>, which they motivate and orchestrate. They have the humility to build and lead teams that deliver towards the greater good.</p>
  4398. <p>This &mdash; above all &mdash; is one of the defining characteristics of a great leader: they prioritize and celebrate the team’s success over and above their own success.</p>
  4400. <h4 id="it-s-all-about-teamwork">It’s All About Teamwork</h4>
  4402. <p>Truly great leaders understand the importance that teams play in delivering outcomes and goals. One of the most important roles a leader needs to undertake is to act as a lynchpin that sits at the heart of a team, identifying new and existing team members, nurturing them, and <strong>building them into a team that works effectively together</strong>.</p>
  4404. <p>A forward-thinking leader won’t just focus on the present, but will proactively develop a vision and long-term goals for future success. To deliver upon this vision of future success will involve both identifying potential new team members, but &mdash; just as importantly &mdash; developing existing team members. This involves opening your eyes to the different aspects of the business environment you occupy, getting to know your team, and identifying team members’ strengths and weaknesses.</p>
  4406. <p>As a UX leader, an important role you’ll play is helping others by mentoring and coaching them, ensuring they are equipped with the skills they need to grow. Again, this is where a truly selfless leader will put others first, in the knowledge that <strong>the stronger the team, the stronger the outcomes will be</strong>.</p>
  4408. <p>As a UX leader, you’ll also act as a champion for design within the wider business context. You’ll act as a bridge &mdash; and occasionally, a buffer &mdash; between the interface of business requirements and design requirements. Your role will be to champion the power of design and sell its benefits, always singing your team’s praises and &mdash; occasionally &mdash; fighting on their behalf (often without their awareness).</p>
  4410. <h4 id="the-art-of-delegation">The Art Of Delegation</h4>
  4412. <p>It’s possible to build a great UX team from the inside by developing existing team members, and an effective leader will use delegation as an effective development tool to enhance their team members’ capabilities.</p>
  4414. <p>Delegation isn&rsquo;t just passing off the tasks you don&rsquo;t want to do, it&rsquo;s about <strong>empowering the different individuals in a team</strong>. A true leader understands this and spends the time required to learn how to delegate effectively.</p>
  4416. <p>Delegation is about education and expanding others’ skill sets, and it’s a powerful tool when used correctly. Effective delegation is a skill, one that you’ll need to acquire to step up into a UX leadership role.</p>
  4418. <p>When delegating a task to a team member, it’s important to explain to them why you’re delegating the task. As a leader, your role is to <strong>provide clear guidance</strong> and this involves explaining why you’ve chosen a team member for a task and how they will be supported, developed and rewarded for taking the task on.</p>
  4420. <p>This latter point is critical: All too often managers who lack leadership skills use delegation as a means to offload tasks and responsibility, unaware of the power of delegation. This is poor delegation and it’s ineffective leadership, though I imagine, sadly, we have all experienced it! An effective leader understands and strives to delegate effectively by:</p>
  4422. <ul>
  4423. <li>defining the task, establishing the outcomes and goals;</li>
  4424. <li>identifying the appropriate individual or team to take the task on;</li>
  4425. <li>assessing the team member(s) ability and ascertaining any training needs;</li>
  4426. <li>explaining their reasoning, clearly outlining why they chose the individual or team;</li>
  4427. <li>stating the required results;</li>
  4428. <li>agreeing on realistic deadlines; and</li>
  4429. <li>providing feedback on completion of the task.</li>
  4430. </ul>
  4432. <p>When outlined like this, it becomes clear that <strong>effective delegation is more than simply passing on a task you’re unwilling to undertake</strong>. Instead, it’s a powerful tool that an effective UX leader uses to enable their team members to take ownership of opportunities, whilst growing their skills and experience.</p>
  4434. <h4 id="give-success-and-accept-failure">Give Success And Accept Failure</h4>
  4436. <p>A great leader is selfless: they give credit for any successes to the team; and accept the responsibility for any failures alone.</p>
  4438. <p>A true leader gives success to the team, ensuring that &mdash; when there&rsquo;s a win &mdash; the team is celebrated for its success. A true leader takes pleasure in celebrating the team&rsquo;s win. When it comes to failure, however, a true leader steps up and takes responsibility. A mark of a truly great leader is this selflessness.</p>
  4440. <p>As a leader, <strong>you set the direction and nurture the team</strong>, so it stands to reason that, if things go wrong &mdash; which they often do &mdash; you’re willing to shoulder the responsibility. This understanding &mdash; that you need to give success and accept failure &mdash; is what separates great leaders from mediocre managers.</p>
  4442. <p>Poor managers will seek to ‘deflect the blame,’ looking for anyone but themselves to apportion responsibility to. Inspiring leaders are aware that, at the end of the day, they are responsible for the decisions made and outcomes reached; when things go wrong they accept responsibility.</p>
  4444. <p>If you’re to truly inspire others and lead them to achieve great things, it’s important to remember this distinction between managers and leaders. By giving success and accepting failure, you’ll breed intense loyalty in your team.</p>
  4446. <h3 id="lead-by-example">Lead By Example</h3>
  4448. <p>Great leaders understand the importance of leading by example, acting as a beacon for others. To truly inspire a team, it helps to connect yourself with that team, and not isolate yourself. Rolling up your sleeves and pitching in, especially when deadlines are pressing, is a great way to demonstrate that you haven’t lost touch with the ‘front line.’</p>
  4450. <p>A great leader understands that success is &mdash; always &mdash; a team effort and that a motivated team will deliver far more than the sum of its parts.</p>
  4452. <p>As I’ve noted in my previous articles: If you&rsquo;re ever the smartest person in a room, find another room. An effective leader has the confidence to surround themselves with other, smarter people.</p>
  4454. <p>Leadership isn&rsquo;t about individual status or being seen to be the most talented. It&rsquo;s about teamwork and getting the most out of a well-oiled machine of individuals working effectively together.</p>
  4456. <h4 id="get-out-of-your-silo">Get Out Of Your Silo</h4>
  4458. <p>To lead effectively, it’s important to get out of your silo and to see the world as others do. This means getting to know all of the team, throughout the organization and at every level.</p>
  4460. <p>Leaders that isolate themselves &mdash; in their often luxurious corner offices &mdash; are, in my experience, poor leaders (if, indeed, they can be called leaders at all!). By distancing themselves from the individuals that make up an organization they run the very real risk of losing touch.</p>
  4462. <p>To lead, get out of your silo and acquaint yourself with the totality of your team and, if you’re considering a move into leadership, make it your primary task to explore all the facets of the business.</p>
  4464. <h4 id="the-pieces-of-the-jigsaw">The Pieces Of The Jigsaw</h4>
  4466. <p>To lead effectively, you need to have an understanding of others and their different skills. In my last article, <a href="">Building a UX Team</a>, I wrote about the idea of ‘T-shaped’ people &mdash; those that have a depth of skill in their field, along with the willingness and ability to collaborate across disciplines. Great leaders tend to be T-shaped, flourishing by seeing things from others’ perspectives.</p>
  4468. <p>Every organization &mdash; no matter how large or small &mdash; is like an elaborate jigsaw that is made up of many different interlocking parts. An effective leader is informed by an understanding of this context, they will have made the effort to see all of the pieces of the jigsaw. As a UX leader, you’ll need to <strong>familiarize yourself with a wide range of different teams</strong>, including design, research, writing, engineering, and business.</p>
  4470. <p>To lead effectively, it’s important to push outside of your comfort zone and learn about these different specialisms. Do so and you will ensure that you can communicate to these different stakeholders. At the risk of mixing metaphors, you will be the glue that holds the jigsaw together.</p>
  4472. <h4 id="sweat-the-details">Sweat The Details</h4>
  4474. <p>As Charles and Ray Eames put it:</p>
  4476. <blockquote>“The details aren’t the details, they make the product.”</blockquote>
  4478. <p>Great leaders understand this: they set the bar high and they encourage and motivate the teams they lead to deliver on the details. To lead a team, it’s important to <strong>appreciate the need to strive for excellence</strong>. Great leaders aren’t happy to accept the status quo, especially if the status quo can be improved upon.</p>
  4480. <p>Of course, these qualities can be learned, but many of us &mdash; thankfully &mdash; have them, innately. Few (if any) of us are happy with second best and, in a field driven by a desire to create delightful and memorable user experiences, we appreciate the importance of details and their place in the grand scheme of things. This is a great foundation on which to build leadership skills.</p>
  4482. <p>To thrive as a leader, it’s important to share this focus on the details with others, ensuring they understand and appreciate the role that the details play in the whole. Act as a beacon of excellence: <strong>lead by example</strong>; never settle for second best; give success and accept failure&hellip; and your team will follow you.</p>
  4484. <h3 id="in-closing">In Closing</h3>
  4486. <p>As user experience design matures as a discipline, and the number of different specializations multiplies, so too does the discipline’s need for leaders, to nurture and grow teams. As a relatively new field of expertise, the opportunities to develop as a UX leader are tremendous.</p>
  4488. <p>Leadership is a skill and &mdash; like any skill &mdash; it can be learned. As I&rsquo;ve noted throughout this series of articles, one of the best places to learn is to look to other disciplines for guidance, widening the frame of reference. When we consider leadership, this is certainly true.</p>
  4490. <p>There is a great deal we can learn from the world of business, and websites like <a href="">Harvard Business Review</a> (HBR), <a href="">McKinsey Quarterly</a>, and <a href="">Fast Company</a> &mdash; amongst many, many others &mdash; offer us a wealth of insight.</p>
  4492. <p>There’s never been a more exciting time to work in User Experience design. UX has the potential to impact on so many facets of life, and the world is crying out for leaders to step up and lead the charge. I’d encourage anyone eager to learn and to grow to undertake a skills audit, take the first step, and embark on the journey into leadership. Leadership is a privilege, rich with rewards, and is something I’d strongly encourage exploring.</p>
  4494. <h4 id="suggested-reading">Suggested Reading</h4>
  4496. <p>There are many great publications, offline and online, that will help you on your adventure. I’ve included a few below to start you on your journey.</p>
  4498. <ul>
  4499. <li>The Harvard Business Review website is an excellent starting point and its guide, <a href="">HBR’s 10 Must Reads on Leadership</a>, provides an excellent overview on developing leadership qualities.</li>
  4500. <li>Peter Drucker’s writing on leadership is also well worth reading. Drucker has written many books, one I would strongly recommend is <a href="">Managing Oneself</a>. It’s a short (but very powerful) read, and I read it at least two or three times a year.</li>
  4501. <li>If you’re serious about enhancing your leadership credentials, Michael D. Watkins’s <a href="">The First 90 Days: Proven Strategies for Getting Up to Speed Faster and Smarter</a>, provides a comprehensive insight into transitioning into leadership roles.</li>
  4502. <li>Finally, HBR’s website &mdash; mentioned above &mdash; is definitely worth bookmarking. Its business-focused flavor offers designers a different perspective on leadership, which is well worth becoming acquainted with.</li>
  4503. </ul>
  4505. <p><em>This article is part of the UX design series sponsored by Adobe. <a href="">Adobe XD is made for a fast and fluid UX design process</a>, as it lets you go from idea to prototype faster. Design, prototype, and share &mdash; all in one app. You can check out more inspiring projects created with <a href="">Adobe XD on Behance</a>, and also <a href="">sign up for the Adobe experience design newsletter</a> to stay updated and informed on the latest trends and insights for UX/UI design.</em></p>
  4507. <div class="signature">
  4508.  <img src="" alt="Smashing Editorial">
  4509.  <span>(ra, il)</span>
  4510. </div>
  4513. </div>
  4517.              </article>
  4518.            </body>
  4519.          </html>
  4520.        ]]></content:encoded>
  4521.      </item>
  4523.      <item>
  4526.          <author>Alice Кotlyarenko</author>
  4528.        <title>How To Design Emotional Interfaces For Boring Apps</title>
  4529.        <link></link>
  4530.        <pubDate>Tue, 10 Apr 2018 13:20:05 +0200</pubDate>
  4531.        <guid></guid>
  4532.        <description>There’s a trickling line of ones and zeros that disappears behind a large yellow tube. A bear pops out of the tube as a clawed paw starts pointing at my browser’s toolbar, and a headline appears, saying: “Start your bear-owsing!”
  4533. Between my awwing and oohing I forget what I wanted to browse.
  4534. Products like a VPN service rarely evoke endearment — or any other emotion, for that matter. It’s not their job, not what they were built to do.</description>
  4535.        <content:encoded><![CDATA[
  4536.          <html>
  4537.            <head>
  4538.              <meta charset="utf-8">
  4539.              <link rel="canonical" href="" />
  4540.              <title>How To Design Emotional Interfaces For Boring Apps</title>
  4541.            </head>
  4542.            <body>
  4543.              <article>
  4544.                <header>
  4545.                  <h1>How To Design Emotional Interfaces For Boring Apps</h1>
  4548.                    <address>Alice Кotlyarenko</address>
  4550.                  <time datetime="2018-04-10T13:20:05&#43;02:00" class="op-published">2018-04-10T13:20:05+02:00</time>
  4551.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  4552.                </header>
  4555. <p>There’s a trickling line of ones and zeros that disappears behind a large yellow tube. A bear pops out of the tube as a clawed paw starts pointing at my browser’s toolbar, and a headline appears, saying: “Start your bear-owsing!”</p>
  4557. <p>Between my awwing and oohing I forget what I wanted to browse.</p>
  4559. <p>Products like a VPN service rarely evoke endearment — or any other emotion, for that matter. It’s not their job, not what they were built to do. But because <a href="">TunnelBear</a> does, I choose it over any other VPN and recommend it to my friends, so they can have some laughs while caught up in routine.</p>
  4561. <figure><a href=""><img src="" width="800" alt="tunnelbear" /></a></figure>
  4563. <p>Humans can’t endure boredom for a long time, which is why products that are built for non-exciting, repetitive tasks so often get abandoned and gather dust on computers and phones. But boredom, according to psychologists, is merely lack of stimulation, <a href="">the unfulfilled desire for satisfying activity</a>. So what if we use the interface to give them that stimulation?</p>
  4565. <p>I sat with product designers here at MacPaw, who spend their waking hours designing not-so-sexy things like duplicate finders and encryption apps, and they shared five secrets to more emotional UIs: gamification, humor, animation, illustration, and mascots.</p>
  4569. <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  4570.    <div class="container product-panel--book__container">
  4571.      <div class="panel__description panel__description--book">
  4572.    <p>Nope, we can't do any magic tricks, but we have articles, <a href="">books</a> and <a href="">webinars</a> featuring techniques we all can use to improve our work. <a href="">Smashing Members</a> get a seasoned selection of magic front-end tricks — e.g. <strong>live designing sessions</strong> and perf audits, too. <em>Just sayin'</em>! ;-)</p>
  4574.      <a href="" class="btn btn--green btn--large">
  4575.        Explore Smashing Wizardry&nbsp;→
  4576.      </a>
  4577.      </div>
  4578.      <div class="panel__image panel__image--book">
  4579.        <a href="" class="books__book__image">
  4580.        <div class="books__book__img">
  4581.          <img src="" alt="Smashing Cat, just preparing to do some magic stuff." width="310" height="400">
  4582.        </div>
  4583.      </a>
  4584.      </div>
  4585.    </div>
  4586.  </aside>
  4592. <div class="c-garfield-the-cat">
  4595. <h3 id="games-people-play">Games People Play</h3>
  4597. <p>There’s some debate going on around the use of gamification in UIs: <a href="">24 empirical studies</a>, for example, arrived at varying conclusions as to how effective it was. But then again, effectiveness depends on what you were trying to accomplish by designing those shiny achievement badges.</p>
  4599. <p>For many product creators, including <a href="">Akar Sumset here</a>, the point of gamification is not letting users have fun per se — it’s gently pushing them towards certain behaviors via said fun. Achievements, ranks, leaderboards tap into the basic human need of esteem, trigger competitiveness, and supposedly urge users to do what you want them to, like make progress, keep coming back to the app, or share it on social media.</p>
  4601. <p>Gamification can succeed or fail at that, but what it sure achieves is an emotional response. Our brain is packed full of cells that control the levels of dopamine, one of the major <a href="">neurochemicals of happiness</a>. When something enjoyable happens, these neurons light up and trigger a release of dopamine into the blood, but what’s even better, if this pleasant event is regular and can be predicted, they’ll light up and release dopamine before it even happens. What does that mean for your interface? That expecting an enjoyable thing such as the next achievement will give the users little shots of happiness throughout their experience with the product.</p>
  4603. <h4 id="gamification-in-ui-gemini-2-and-duolingo">Gamification in UI: Gemini 2 And Duolingo</h4>
  4605. <p>When designing <a href="">Gemini 2</a>, the new version of our duplicate finder for Mac, we had a serious problem at hand. Reviewing gigabytes of files was soul-crushingly boring, and some users complained they quit before they were done. So what we tried to achieve with the achievements system is intensify the feeling of a crossed-out item on a to-do list, which is the only upside of tedious tasks. The space theme, unwittingly set with the app’s name and exploited in the interface, was perfect for gamification. Our audience grew up on Star Wars and Star Trek, so sci-fi inspired ranks would hit home with them.</p>
  4607. <p>Within days of the release, we started getting tweets from users asking for clues on the Easter Egg that would unlock the final achievement. A year after the release, Gemini 2 got <a href=";y=2017&amp;c=256&amp;a=0">the Red Dot Award</a> for a design that exhibits “clarity and emotion.” So while it’s hard to measure how motivating our achievement system has been, it sure didn’t leave people cold.</p>
  4619. <figure >
  4620. <a href="">
  4621. <img
  4622. srcset=",q_auto/w_400/ 400w,
  4623.,q_auto/w_800/ 800w,
  4624.,q_auto/w_1200/ 1200w,
  4625.,q_auto/w_1600/ 1600w,
  4626.,q_auto/w_2000/ 2000w"
  4627. src=",q_auto/w_400/"
  4628. sizes="100vw"
  4629. alt="Gamification in UI: Gemini 2"
  4630. />
  4631. </a>
  4633. </figure>
  4636. <p>Another product that got it right &mdash; and has by far the most gamified interface I’ve seen &mdash; is <a href="">Duolingo</a>, an online service and mobile app for learning languages. Trying to master a foreign tongue from scratch is daunting, especially if it’s just you and your laptop, without the reassurance that comes with having a teacher. Given how quickly people lose interest in their language endeavors (speaking from experience here), Duolingo would have to go out of its way to keep you hooked. And it does.</p>
  4638. <p>Whenever you complete a quick 5-minute lesson, you earn 10 points. Take lessons 30 days in a row? Get an achievement. Complete 20 lessons without a single typo? Unlock another. For every baby step you take, your senses are rewarded with triumphant sounds and colorful graphics that trigger the release of that sweet, sweet dopamine. Eventually, you start associating Duolingo with the feeling of accomplishment and pride — the kind of feeling you want to come back to.</p>
  4650. <figure >
  4651. <a href="">
  4652. <img
  4653. srcset=",q_auto/w_400/ 400w,
  4654.,q_auto/w_800/ 800w,
  4655.,q_auto/w_1200/ 1200w,
  4656.,q_auto/w_1600/ 1600w,
  4657.,q_auto/w_2000/ 2000w"
  4658. src=",q_auto/w_400/"
  4659. sizes="100vw"
  4660. alt="Gamification in UI: Duolingo"
  4661. />
  4662. </a>
  4664. </figure>
  4667. <p>If you&rsquo;d like to dive deeper into gamification, Gabe Zichermann&rsquo;s book &ldquo;<a href="">Gamification by Design: Implementing Game Mechanics in Web and Mobile Apps</a>&rdquo; is a great way to start.</p>
  4669. <h3 id="you-ve-got-to-be-joking">You’ve Got To Be Joking</h3>
  4671. <p>Victor Yocco has made a solid case for <a href="">using humor in web design</a> as a tool to create memorable experiences, connect with users, and make your work stand out. But the biggest power of jokes is that they’re emotional. While we still don’t fully understand the nature of humor, one thing is clear: it makes humans happy. According to <a href="">brain imaging research</a>, funny cartoons activate the reward network in the limbic system — the same network that responds to eating, music, sex, and mood-altering drugs. In other words, a good joke gives people a kind of emotional high.</p>
  4674.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  4678. <p>Would you want that kind of reaction to your interface? Of course. But the tricky part is that not only is humor subjective, but the way we respond to it depends a lot on the context. One thing is throwing in a pun on the launch screen; a completely different is goofing around in an error message. And while all humans enjoy humor in this or that form, it’s vital to know your audience: what they find hilarious and what might seem inappropriate, crude, or poorly timed. Not that different from cracking jokes in real life.</p>
  4680. <h4 id="humor-in-ui-authentic-weather-and-slack">Humor in UI: Authentic Weather and Slack</h4>
  4682. <p>One app that nails the use of humor — and not just as a complementary comic relief, but as a unique selling proposition — is <a href="">Authentic Weather</a>. Weather apps are a prime example of utilitarian products: they are something people use to get information, period. But with Authentic Weather, you get a lot more than that. No matter the weather, it’s going to crack you up with a snarky comment like “It’s ducking freezing,” “Go home winter,” and my personal favorite “It’s just okay. Look outside for more information.”</p>
  4684. <p>What happens when you use Authentic Weather is you don’t just open it for the forecast — you want to see what it comes up with next, and a routine task like checking the weather becomes a thing to look forward to in the morning. Now, the app’s moody commentary, packed full of f-words and scorn, would probably seem less entertaining to my mom. But being the grumpy millennial that I am, I find it hilarious, which proves humor works if you know your audience.</p>
  4696. <figure >
  4697. <a href="">
  4698. <img
  4699. srcset=",q_auto/w_400/ 400w,
  4700.,q_auto/w_800/ 800w,
  4701.,q_auto/w_1200/ 1200w,
  4702.,q_auto/w_1600/ 1600w,
  4703.,q_auto/w_2000/ 2000w"
  4704. src=",q_auto/w_400/"
  4705. sizes="100vw"
  4706. alt="Humor in UI: Authentic Weather"
  4707. />
  4708. </a>
  4710. </figure>
  4713. <p>Another interface that puts fun to good use is Slack’s. For an app people associate with work emergencies, Slack does a solid job creating <a href="">a more humane experience</a>, not least because of its one-liners. From loading screens to the moments when you’re finally caught up with all your chats, it cracks a joke when you don’t see it coming.</p>
  4715. <p>With such a diverse demographic, humor is a hit and miss, so Slack plays safe with goofy puns and good-natured banter — the kind of jokes that don’t exactly send you rolling on the floor but don’t annoy or offend either. In the best case scenario, the user will chuckle and share the screenshot in one of their channels; in the worst case scenario, they’ll just roll their eyes.</p>
  4727. <figure >
  4728. <a href="">
  4729. <img
  4730. srcset=",q_auto/w_400/ 400w,
  4731.,q_auto/w_800/ 800w,
  4732.,q_auto/w_1200/ 1200w,
  4733.,q_auto/w_1600/ 1600w,
  4734.,q_auto/w_2000/ 2000w"
  4735. src=",q_auto/w_400/"
  4736. sizes="100vw"
  4737. alt="Humor in UI: Slack"
  4738. />
  4739. </a>
  4741. </figure>
  4744. <p>More on Humor: &ldquo;<a href="">Just Kidding: Using Humor Effectively</a>&rdquo; by Louis R. Franzini.</p>
  4746. <h3 id="get-the-world-moving">Get The World Moving</h3>
  4748. <p>Nearly every interface uses a form of animation. It’s the natural way to transition from one state to another. But animations in UI can serve a lot more purposes than signifying a change of state — they can help you direct attention and communicate what’s going on better than static visuals or copy ever could. The movement stimulates both <a href="">visual and kinesthetic learning</a>, which means users are more likely to stay focused and figure out how to use the thing.</p>
  4750. <p>These are all good reasons to incorporate animation into your design, but why does it elicit emotion, exactly? Simon Grozyan, who worked on our apps Encrypto and Gemini Photos, believes it’s because in the physical world we interpret animated things as alive:</p>
  4752. <blockquote>“We are used to seeing things in movement. Everything around us is either moving or changing appearance because of the light. Static equals dead.”</blockquote>
  4754. <p>In addition to the relatable, lifelike quality of a moving object, animation has the power of a delightful and unexpected thing that brings us <a href="">a lot more pleasure</a> than a thing equally delightful but expected. Therefore, by using it in spots less habitual than transitions you can achieve that coveted stimulation that makes your product fun to use.</p>
  4756. <h4 id="animation-in-ui-encrypto-and-shazam">Animation in UI: Encrypto and Shazam</h4>
  4758. <p><a href="">Encrypto</a> is a tiny Mac app that encrypts and decrypts your files so that you can send them to someone securely. It’s an indispensable tool for those who care about data security and privacy, but not the kind of tool you would feel attached to. Nevertheless, Encrypto is by far my favorite MacPaw app as far as design is concerned, thanks to the Matrix-style animated bar that slides over your file and transforms it into a new secured entity. Encryption comes to life; it’s no longer a dull process on your computer — it’s mesmerizing digital magic.</p>
  4760. <figure><a href=""><img src="" width="800" alt="encrypto" /></a></figure>
  4762. <p>Animation is at the heart of another great UI: that of <a href="">Shazam</a>, an app you probably have on your phone. When you use Shazam to find out what’s playing, the button you tap starts sending concentric circles outward and inward. This similarity to a throbbing audio speaker makes the interface almost tangible, physical — as if you’re blasting your favorite album on a powerful sound system.</p>
  4764. <figure><a href=""><img src="" width="800" alt="shazam" /></a></figure>
  4766. <p>More on Animation: &ldquo;<a href="">How Functional Animation Helps Improve User Experience</a>&rdquo;.</p></p>
  4768. <h3 id="art-is-everywhere">Art Is Everywhere</h3>
  4770. <p>As <a href="">Blair Culbreth argues</a>, polished is no longer enough for interfaces. Sleek, professional design is expected, but it’s the personalized, humane details that users smile at and forward to their friends. Custom art can be this detail.</p>
  4772. <p>Unlike generic imagery, illustration is emotional, because it communicates more than meaning. It carries positive associations with cartoons every person used to watch as a child, shows things in a more playful, imaginative way, and, most importantly, contains a touch of the artist’s personality.</p>
  4774. <p>“I think when an artist creates an illustration they always infuse some of their personal experience, their context, their story into it,” says Max Kukurudziak, one of our product designers. The theory rings true — a human touch is more likely to stir feelings.</p>
  4776. <h4 id="illustration-in-ui-gemini-photos-and-google-calendar">Illustration in UI: Gemini Photos and Google Calendar</h4>
  4778. <p>One of our newest products <a href="">Gemini Photos</a> is an iPhone app that helps you clear unneeded photos. Much like Gemini 2 for desktop, it involves some tedious reviewing for the user, so even with a handy and handsome UI, we’d have a hard time holding their attention and generally making them feel good.</p>
  4780. <p>Like in many of our previous apps, we used animations and sounds to enliven the interface, but custom art has become the highlight of the experience. As said above, it’s scientifically proven that surprising pleasurable things cause an influx of that happiness chemical into our blood, so by using quirky illustrations in unexpected spots we didn’t just fill up an empty screen — we added a tad of enjoyment to an otherwise monotonous activity.</p>
  4792. <figure >
  4793. <a href="">
  4794. <img
  4795. srcset=",q_auto/w_400/ 400w,
  4796.,q_auto/w_800/ 800w,
  4797.,q_auto/w_1200/ 1200w,
  4798.,q_auto/w_1600/ 1600w,
  4799.,q_auto/w_2000/ 2000w"
  4800. src=",q_auto/w_400/"
  4801. sizes="100vw"
  4802. alt="Illustration in UI: Gemini Photos"
  4803. />
  4804. </a>
  4806. </figure>
  4809. <p>One more example of how illustration can make a product more lovable is <a href="">Google Calendar</a>. Until recently there was a striking difference between the web version and the iOS app. While the former had the appeal of a spreadsheet, the latter instantly won my heart with one killer detail. For many types of events, Google Calendar slips in art that illustrates them, based on the keywords it picks up from event titles. That way, your plans for the week look a lot more exciting, even if all you’ve got going on is the gym and a dentist appointment.</p>
  4811. <p>But that’s not even the best thing. I realized that whenever I create a new event, I secretly hope Google Calendar will have art for it and feel genuinely pleased when it does. Just like that, using a calendar stopped being a necessity and became a source of positive emotion. And, apparently, the illustration experiment didn’t work for me alone, because Google recently rolled out the web version of their calendar with the same art.</p>
  4823. <figure >
  4824. <a href="">
  4825. <img
  4826. srcset=",q_auto/w_400/ 400w,
  4827.,q_auto/w_800/ 800w,
  4828.,q_auto/w_1200/ 1200w,
  4829.,q_auto/w_1600/ 1600w,
  4830.,q_auto/w_2000/ 2000w"
  4831. src=",q_auto/w_400/"
  4832. sizes="100vw"
  4833. alt="Illustration in UI: Google Calendar"
  4834. />
  4835. </a>
  4837. </figure>
  4840. <p>More on Illustration: &ldquo;<a href="">Illustration That Works: Professional Techniques For Artistic And Commercial Success</a>&rdquo; by Greg Houston.</p>
  4842. <h3 id="what-a-character">What A Character</h3>
  4844. <p>Cute characters that impersonate products have been used in <a href="">web design</a> and marketing for years (think Ronald McDonald and the Michelin Man). In interfaces — not quite as much. Mascots in UI can be perceived as intrusive and annoying, especially if they distract the user from an important action or obstruct the view. A notorious example of a mascot gone wrong is Microsoft’s Clippy: it <a href="">evoked nothing but fear and loathing</a> (which, of course, are emotions, but not the kind you’re looking for).</p>
  4846. <p>At the same time, <a href="">studies show</a> that people easily personify things, even if they are merely geometric figures. Lifelike creatures are easier to relate to, understand the behavior of, and generally feel some way about. Moreover, an animated character is easier to attribute a personality to, so you can broadcast the characteristics of your product through that character — make it playful and goofy, eager and helpful, or whatever you need it to be. With that much-untapped potential, mascots are perfect for non-emotional products.</p>
  4848. <p>The trick is timing.</p>
  4850. <p>Clippy was so obnoxious because he appeared uninvited, interrupted completely unrelated tasks, and was generally in the way. But if the mascot shows up in a relatively idle moment — for example, the user has just completed a task — it will do its endearing job.</p>
  4852. <h4 id="mascots-in-ui-remembear-and-yelp">Mascots in UI: RememBear and Yelp</h4>
  4854. <p>TunnelBear Inc. has recently beta launched another utility that’s cute as a button (no pun intended). <a href="">RememBear</a> is a password manager, and passwords are supposed to be no joke. But the brilliance of bear cartoons in RememBear is that they are nowhere in sight when you do serious, important things like creating a new entry. Instead, you get a bear hug when you’re done with stage one of signing up for the app and haven’t yet proceeded to stage two — saving your first password. By placing the mascot in this spot, RememBear avoided being in the way but made me smile when I least expected it.</p>
  4866. <figure >
  4867. <a href="">
  4868. <img
  4869. srcset=",q_auto/w_400/ 400w,
  4870.,q_auto/w_800/ 800w,
  4871.,q_auto/w_1200/ 1200w,
  4872.,q_auto/w_1600/ 1600w,
  4873.,q_auto/w_2000/ 2000w"
  4874. src=",q_auto/w_400/"
  4875. sizes="100vw"
  4876. alt="Mascots in UI: RememBear"
  4877. />
  4878. </a>
  4880. </figure>
  4883. <p>Just like RememBear, <a href="">Yelp</a> — a widely known app for restaurant reviews — has perfect timing for their mascot. The funny hamster first appeared at the bottom of the iOS app’s settings so that the user would discover it like an Easter egg.</p>
  4885. <p>“At Yelp we&rsquo;re always striving to make our product and brand feel fun and delightful,” <a href="">says Yoni De Beule</a>, Yelp’s Product Design manager. “We reflect Yelp&rsquo;s personality in everything from our fun poster designs and funny release notes to internal hackathon projects and Yelp Elite parties. When we found our iPhone settings page to be seriously lacking in the fun department, we decided to roll up our sleeves and fix it.”</p>
  4887. <p>The hamster in the iOS app later got company, as the team designed a velociraptor for the Android version and a dog for the web. So whenever — and wherever — you use Yelp, you almost want to run out of recommendations, so that you can see another version of the delightful character.</p>
  4899. <figure >
  4900. <a href="">
  4901. <img
  4902. srcset=",q_auto/w_400/ 400w,
  4903.,q_auto/w_800/ 800w,
  4904.,q_auto/w_1200/ 1200w,
  4905.,q_auto/w_1600/ 1600w,
  4906.,q_auto/w_2000/ 2000w"
  4907. src=",q_auto/w_400/"
  4908. sizes="100vw"
  4909. alt="Mascots in UI: Yelp"
  4910. />
  4911. </a>
  4913. </figure>
  4916. <p>If you&rsquo;d like to learn how to create your own mascot, there&rsquo;s a nice <a href="">tutorial</a> by Sirine (aka &lsquo;Miss ChatZ&rsquo;) on Envato Tuts+.</p>
  4918. <h3 id="to-wrap-it-up">To Wrap It Up&hellip;</h3>
  4920. <p>Not all products are inherently fun the way games, or social media apps are, but even utilities don’t have to be merely utilitarian. Apps that deal with repetitive tasks often struggle with retaining users: people abandon them because they feel bored, and boredom is simply lack of stimulation. By using positive stimuli like humor, movement, unique art, elements of game, and relatable characters we can make users feel a different way — more excited, less distracted, and ultimately happier.</p>
  4922. <h4 id="further-reading">Further Reading</h4>
  4924. <ul>
  4925. <li>&ldquo;<a href="">Emotional Design: Why We Love (Or Hate) Everyday Things</a>,&rdquo; Don Norman</li>
  4926. <li>&ldquo;<a href="">Seductive Interaction Design: Creating Playful, Fun, and Effective User Experiences (Voices That Matter)</a>,&rdquo; Stephen P. Anderson</li>
  4927. </ul>
  4932. <div class="signature">
  4933.  <img src="" alt="Smashing Editorial">
  4934.  <span>(cc, ra, il)</span>
  4935. </div>
  4938. </div>
  4942.              </article>
  4943.            </body>
  4944.          </html>
  4945.        ]]></content:encoded>
  4946.      </item>
  4948.      <item>
  4951.          <author>Steven Lambert</author>
  4953.        <title>Designing For Accessibility And Inclusion</title>
  4954.        <link></link>
  4955.        <pubDate>Mon, 09 Apr 2018 14:45:39 +0200</pubDate>
  4956.        <guid></guid>
  4957.        <description>“Accessibility is solved at the design stage.” This is a phrase that Daniel Na and his team heard over and over again while attending a conference. To design for accessibility means to be inclusive to the needs of your users. This includes your target users, users outside of your target demographic, users with disabilities, and even users from different cultures and countries. Understanding those needs is the key to crafting better and more accessible experiences for them.</description>
  4958.        <content:encoded><![CDATA[
  4959.          <html>
  4960.            <head>
  4961.              <meta charset="utf-8">
  4962.              <link rel="canonical" href="" />
  4963.              <title>Designing For Accessibility And Inclusion</title>
  4964.            </head>
  4965.            <body>
  4966.              <article>
  4967.                <header>
  4968.                  <h1>Designing For Accessibility And Inclusion</h1>
  4971.                    <address>Steven Lambert</address>
  4973.                  <time datetime="2018-04-09T14:45:39&#43;02:00" class="op-published">2018-04-09T14:45:39+02:00</time>
  4974.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  4975.                </header>
  4978. <p>“Accessibility is solved at the design stage.” This is a phrase that <a href="">Daniel Na</a> and his team heard over and over again while attending a conference. To design for accessibility means to <strong>be inclusive to the needs of your users</strong>. This includes your target users, users outside of your target demographic, users with disabilities, and even users from different cultures and countries. Understanding those needs is the key to crafting better and more accessible experiences for them.</p>
  4980. <p>One of the most common problems when designing for accessibility is knowing what needs you should design for. It’s not that we intentionally design to exclude users, it’s just that “<a href="">we don’t know what we don’t know</a>.” So, when it comes to accessibility, there’s a lot to know.</p>
  4982. <p>How do we go about understanding the myriad of users and their needs? How can we ensure that their needs are met in our design? To answer these questions, I have found that it is helpful to apply a critical analysis technique of viewing a design through different lenses.</p>
  4984. <blockquote>“Good [accessible] design happens when you view your [design] from many different perspectives, or lenses.”<br /><br />&mdash; <a href="">The Art of Game Design: A Book of Lenses</a></blockquote>
  4986. <p>A <a href="">lens</a> is “a narrowed filter through which a topic can be considered or examined.” Often used to examine works of art, literature, or film, lenses ask us to leave behind our worldview and instead view the world through a different context.</p>
  4988. <p>For example, <a href="">viewing art through a lens of history</a> asks us to understand the “social, political, economic, cultural, and/or intellectual climate of the time.” This allows us to better understand what world influences affected the artist and how that shaped the artwork and its message.</p>
  4992. <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  4993.    <div class="container product-panel--book__container">
  4994.      <div class="panel__description panel__description--book">
  4995.    <p>Nope, we can't do any magic tricks, but we have articles, <a href="">books</a> and <a href="">webinars</a> featuring techniques we all can use to improve our work. <a href="">Smashing Members</a> get a seasoned selection of magic front-end tricks — e.g. <strong>live designing sessions</strong> and perf audits, too. <em>Just sayin'</em>! ;-)</p>
  4997.      <a href="" class="btn btn--green btn--large">
  4998.        Explore Smashing Wizardry&nbsp;→
  4999.      </a>
  5000.      </div>
  5001.      <div class="panel__image panel__image--book">
  5002.        <a href="" class="books__book__image">
  5003.        <div class="books__book__img">
  5004.          <img src="" alt="Smashing Cat, just preparing to do some magic stuff." width="310" height="400">
  5005.        </div>
  5006.      </a>
  5007.      </div>
  5008.    </div>
  5009.  </aside>
  5015. <div class="c-garfield-the-cat">
  5018. <p>Accessibility lenses are a filter that we can use to understand how different aspects of the design affect the needs of the users. Each lens presents a set of questions to ask yourself throughout the design process. By using these lenses, you will become more inclusive to the needs of your users, allowing you to design a more accessible user experience for all.</p>
  5020. <p>The <em>Lenses of Accessibility</em> are:</p>
  5022. <ul>
  5023.    <li><a href="#lens-animation-effects">Lens of Animation and Effects</a></li>
  5024.    <li><a href="#lens-audio-video">Lens of Audio and Video</a></li>
  5025.    <li><a href="#lens-color">Lens of Color</a></li>
  5026.    <li><a href="#lens-controls">Lens of Controls</a></li>
  5027.    <li><a href="#lens-font">Lens of Font</a></li>
  5028.    <li><a href="#lens-images-icons">Lens of Images and Icons</a></li>
  5029.    <li><a href="#lens-keyboard">Lens of Keyboard</a></li>
  5030.    <li><a href="#lens-layout">Lens of Layout</a></li>
  5031.    <li><a href="#lens-material-honesty">Lens of Material Honesty</a></li>
  5032.    <li><a href="#lens-readability">Lens of Readability</a></li>
  5033.    <li><a href="#lens-structure">Lens of Structure</a></li>
  5034.    <li><a href="#lens-time">Lens of Time</a></li>
  5035. </ul>
  5037. <p>You should know that not every lens will apply to every design. While some can apply to every design, others are more situational. What works best in one design may not work for another.</p>
  5039. <p>The questions provided by each lens are merely a tool to help you understand what problems may arise. As always, you should test your design with users to ensure it’s usable and accessible to them.</p>
  5041. <h3 id="lens-animation-effects">Lens Of Animation And Effects</h3>
  5043. <p>Effective animations can help bring a page and brand to life, guide the users focus, and help orient a user. But animations are a double-edged sword. Not only can misusing animations cause confusion or be distracting, but they can also be potentially deadly for some users.</p>
  5045. <p>Fast flashing effects (defined as flashing more than three times a second) or high-intensity effects and patterns can cause seizures, known as ‘<a href="">photosensitive epilepsy</a>.’ Photosensitivity can also cause headaches, nausea, and dizziness. Users with photosensitive epilepsy have to be very careful when using the web as they <a href="">never know when something might cause a seizure</a>.</p>
  5047. <p>Other effects, such as parallax or motion effects, can cause some users to feel dizzy or experience vertigo due to <a href="">vestibular sensitivity</a>. The vestibular system controls a person’s balance and sense of motion. When this system doesn’t function as it should, <a href="">it causes dizziness and nausea</a>.</p>
  5049. <blockquote>“Imagine a world where your internal gyroscope is not working properly. Very similar to being intoxicated, things seem to move of their own accord, your feet never quite seem to be stable underneath you, and your senses are moving faster or slower than your body.”<br /><br />&mdash; <a href="">A Primer To Vestibular Disorders</a></blockquote>
  5051. <p>Constant animations or motion can also be distracting to users, especially to users who have difficulty concentrating. GIFs are notably problematic as our eyes are drawn towards movement, making it easy to be distracted by anything that updates or moves constantly.</p>
  5053. <p>This isn’t to say that animation is bad and you shouldn’t use it. Instead you should understand why you&rsquo;re using the animation and <a href="">how to design safer animations</a>. Generally speaking, you should try to design animations that cover small distances, match direction and speed of other moving objects (including scroll), and are relatively small to the screen size.</p>
  5055. <p>You should also provide controls or options to cater the experience for the user. For example, <a href="">Slack lets you hide animated images or emojis</a> as both a global setting and on a per image basis.</p>
  5057. <p>To use the <em>Lens of Animation and Effects</em>, ask yourself these questions:</p>
  5059. <ul>
  5060. <li>Are there any effects that could cause a seizure?</li>
  5061. <li>Are there any animations or effects that could cause dizziness or vertigo through use of motion?</li>
  5062. <li>Are there any animations that could be distracting by constantly moving, blinking, or auto-updating?</li>
  5063. <li>Is it possible to provide controls or options to stop, pause, hide, or change the frequency of any animations or effects?</li>
  5064. </ul>
  5066. <h3 id="lens-audio-video">Lens Of Audio And Video</h3>
  5068. <p>Autoplaying videos and audio can be pretty annoying. Not only do they break a users concentration, but they also force the user to hunt down the offending media and mute or stop it. As a general rule, don’t autoplay media.</p>
  5070. <blockquote>“Use autoplay sparingly. Autoplay can be a powerful engagement tool, but it can also annoy users if undesired sound is played or they perceive unnecessary resource usage (e.g. data, battery) as the result of unwanted video playback.”<br /><br />&mdash; <a href="">Google Autoplay guidelines</a></blockquote>
  5072. <p>You&rsquo;re now probably asking, “But what if I autoplay the video in the background but keep it muted?” While <a href="">using videos as backgrounds</a> may be a growing trend in today’s web design, background videos suffer from the same problems as GIFs and constant moving animations: they can be distracting. As such, you should provide controls or options to pause or disable the video.</p>
  5074. <p>Along with controls, videos should have transcripts and/or subtitles so users can consume the content in a way that works best for them. Users who are visually impaired or who would rather read instead of watch the video need a transcript, while users who aren’t able to or don’t want to listen to the video need subtitles.</p>
  5076. <p>To use the <em>Lens of Audio and Video</em>, ask yourself these questions:</p>
  5078. <ul>
  5079. <li>Are there any audio or video that could be annoying by autoplaying?</li>
  5080. <li>Is it possible to provide controls to stop, pause, or hide any audio or videos that autoplay?</li>
  5081. <li>Do videos have transcripts and/or subtitles?</li>
  5082. </ul>
  5084. <h3 id="lens-color">Lens Of Color</h3>
  5086. <p>Color plays an important part in a design. Colors evoke emotions, feelings, and ideas. Colors can also help strengthen a brand’s message and perception. Yet the power of colors is lost when a user can’t see them or perceives them differently.</p>
  5088. <p><a href="">Color blindness affects roughly 1 in 12 men and 1 in 200 women</a>. Deuteranopia (red-green color blindness) is the most common form of color blindness, affecting about 6% of men. Users with red-green color blindness typically perceive reds, greens, and oranges as yellowish.</p>
  5100. <figure >
  5101. <a href="">
  5102. <img
  5103. srcset=",q_auto/w_400/ 400w,
  5104.,q_auto/w_800/ 800w,
  5105.,q_auto/w_1200/ 1200w,
  5106.,q_auto/w_1600/ 1600w,
  5107.,q_auto/w_2000/ 2000w"
  5108. src=",q_auto/w_400/"
  5109. sizes="100vw"
  5110. alt="Color Blindness Reference Chart for Deuternaopia, Protanopia, and Tritanopia"
  5111. />
  5112. </a>
  5114. <figcaption class="op-vertical-bottom">
  5115. Deuteranopia (green color blindness) is common and causes reds to appear brown/yellow and greens to appear beige. Protanopia (red color blindness) is rare and causes reds to appear dark/black and orange/greens to appear yellow. Tritanopia (blue-yellow colorblindness) is very rare and cases blues to appear more green/teal and yellows to appear violet/grey. (<a href=''>Source</a>) (<a href=''>Large preview</a>)
  5116. </figcaption>
  5117. </figure>
  5120. <p>Color meaning is also problematic for international users. <a href="">Colors mean different things in different countries and cultures</a>. In Western cultures, red is typically used to represent negative trends and green positive trends, but <a href="">the opposite is true in Eastern and Asian cultures</a>.</p>
  5122. <p>Because colors and their meanings can be lost either through cultural differences or color blindness, you should always add a non-color identifier. Identifiers such as icons or text descriptions can help bridge cultural differences while patterns work well to distinguish between colors.</p>
  5134. <figure >
  5135. <a href="">
  5136. <img
  5137. srcset=",q_auto/w_400/ 400w,
  5138.,q_auto/w_800/ 800w,
  5139.,q_auto/w_1200/ 1200w,
  5140.,q_auto/w_1600/ 1600w,
  5141.,q_auto/w_2000/ 2000w"
  5142. src=",q_auto/w_400/"
  5143. sizes="100vw"
  5144. alt="Six colored labels. Five use a pattern while the sixth doesn’t"
  5145. />
  5146. </a>
  5148. <figcaption class="op-vertical-bottom">
  5149. Trello’s color blind friendly labels use different patterns to distinguish between the colors. (<a href=''>Large preview</a>)
  5150. </figcaption>
  5151. </figure>
  5154. <p>Oversaturated colors, high contrasting colors, and even just the color yellow can be <a href="">uncomfortable and unsettling for some users</a>, prominently those on the autism spectrum. It’s best to avoid high concentrations of these types of colors to help users remain comfortable.</p>
  5156. <p>Poor contrast between foreground and background colors make it harder to see for users with low vision, using a low-end monitor, or who are just in direct sunlight. All text, icons, and any focus indicators used for users using a keyboard should meet a <a href="">minimum contrast ratio</a> of 4.5:1 to the background color.</p>
  5158. <p>You should also ensure your design and colors work well in different settings of <a href="">Windows High Contrast mode</a>. A common pitfall is that text becomes invisible on certain high contrast mode backgrounds.</p>
  5160. <p>To use the <em>Lens of Color</em>, ask yourself these questions:</p>
  5162. <ul>
  5163. <li>If the color was removed from the design, what meaning would be lost?</li>
  5164. <li>How could I provide meaning without using color?</li>
  5165. <li>Are any colors oversaturated or have high contrast that could cause users to become overstimulated or uncomfortable?</li>
  5166. <li>Does the foreground and background color of all text, icons, and focus indicators meet contrast ratio guidelines of 4.5:1?</li>
  5167. </ul>
  5169. <h3 id="lens-controls">Lens Of Controls</h3>
  5171. <p>Controls, also called ‘<a href="">interactive content</a>,’ are any UI elements that the user can interact with, be they buttons, links, inputs, or any HTML element with an event listener. Controls that are too small or too close together can cause lots of problems for users.</p>
  5173. <p>Small controls are hard to click on for users who are unable to be accurate with a pointer, such as those with tremors, or those who suffer from reduced dexterity due to age. The default size of checkboxes and radio buttons, for example, can pose problems for older users. Even when a label is provided that could be clicked on instead, <a href="">not all users know they can do so</a>.</p>
  5175. <p>Controls that are too close together can cause problems for touch screen users. Fingers are big and difficult to be precise with. Accidentally touching the wrong control can cause frustration, especially if that control navigates you away or makes you lose your context.</p>
  5187. <figure >
  5188. <a href="">
  5189. <img
  5190. srcset=",q_auto/w_400/ 400w,
  5191.,q_auto/w_800/ 800w,
  5192.,q_auto/w_1200/ 1200w,
  5193.,q_auto/w_1600/ 1600w,
  5194.,q_auto/w_2000/ 2000w"
  5195. src=",q_auto/w_400/"
  5196. sizes="100vw"
  5197. alt="Tweet that says Software being Done is like lawn being Mowed. Jim Benson"
  5198. />
  5199. </a>
  5201. <figcaption class="op-vertical-bottom">
  5202. When touching a single line tweet, it’s very easy to accidentally click the person’s name or handle instead of opening the tweet because there’s not enough space between them. (<a href=''>Source</a>) (<a href=''>Large preview</a>)
  5203. </figcaption>
  5204. </figure>
  5207. <p>Controls that are nested inside another control can also contribute to touch errors. <a href="">Not only is it not allowed in the HTML spec</a>, it also makes it easy to accidentally select the parent control instead of the one you wanted.</p>
  5209. <p>To give users enough room to accurately select a control, <a href="">the recommended minimum size</a> for a control is 34 by 34 device independent pixels, but <a href="">Google recommends at least 48 by 48 pixels</a>, while the <a href="">WCAG spec recommends at least 44 by 44 pixels</a>. This size also includes any padding the control has. So a control could visually be 24 by 24 pixels but with an additional 10 pixels of padding on all sides would bring it up to 44 by 44 pixels.</p>
  5211. <p>It’s also recommended that controls be placed far enough apart to reduce touch errors. Microsoft recommends at least 8 pixels of spacing while Google recommends controls be spaced at least 32 pixels apart.</p>
  5213. <p>Controls should also have a visible text label. Not only do screen readers require the text label to know what the control does, but it’s been shown that <a href="">text labels help all users better understand a controls purpose</a>. This is especially important for form inputs and icons.</p>
  5215. <p>To use the <em>Lens of Controls</em>, ask yourself these questions:</p>
  5217. <ul>
  5218. <li>Are any controls not large enough for someone to touch?</li>
  5219. <li>Are any controls too close together that would make it easy to touch the wrong one?</li>
  5220. <li>Are there any controls inside another control or clickable region?</li>
  5221. <li>Do all controls have a visible text label?</li>
  5222. </ul>
  5224. <h3 id="lens-font">Lens Of Font</h3>
  5226. <p>In the early days of the web, we designed web pages with a <a href="">font size between 9 and 14 pixels</a>. This worked out just fine back then as monitors had a relatively known screen size. We designed thinking that <a href="">the browser window was a constant</a>, something that couldn’t be changed.</p>
  5228. <p>Technology today is very different than it was 20 years ago. Today, browsers can be used on any device of any size, from a small watch to a huge 4K screen. We can no longer use fixed font sizes to design our sites. Font sizes must be as responsive as the design itself.</p>
  5230. <p>Not only should the font sizes be responsive, but the design should be flexible enough to allow users to customize the font size, line height, or letter spacing to a comfortable reading level. Many users make use of <a href="">custom CSS that helps them have a better reading experience</a>.</p>
  5232. <p>The font itself should be easy to read. You may be wondering if one font is more readable than another. The truth of the matter is that the font doesn’t really make a difference to readability. Instead it’s the font style that plays an important role in a fonts readability.</p>
  5234. <p><a href="">Decorative or cursive font styles</a> are harder to read for many users, but especially problematic for users with dyslexia. <a href="">Small font sizes, italicized text</a>, and all uppercase text are also difficult for users. Overall, larger text, shorter line lengths, taller line heights, and increased letter spacing can help all users have a better reading experience.</p>
  5236. <p>To use the <em>Lens of Font</em>, ask yourself these questions:</p>
  5238. <ul>
  5239. <li>Is the design flexible enough that the font could be modified to a comfortable reading level by the user?</li>
  5240. <li>Is the font style easy to read?</li>
  5241. </ul>
  5243. <h3 id="lens-images-icons">Lens Of Images and Icons</h3>
  5245. <p>They say, “A picture is worth a thousand words.” Still, a picture you can’t see is speechless, right?</p>
  5247. <p>Images can be used in a design to convey a specific meaning or feeling. Other times they can be used to simplify complex ideas. Whichever the case for the image, a user who uses a screen reader needs to be told what the meaning of the image is.</p>
  5249. <p>As the designer, you understand best the meaning or information the image conveys. As such, you should annotate the design with this information so it’s not left out or misinterpreted later. This will be used to create the alt text for the image.</p>
  5251. <p><a href="">How you describe an image depends entirely on context</a>, or how much textual information is already available that describes the information. It also depends on if the image is just for decoration, conveys meaning, or contains text.</p>
  5253. <blockquote>“You almost never describe what the picture looks like, instead you explain the information the picture contains.”<br /><br />&mdash; <a href="">Five Golden Rules for Compliant Alt Text</a></blockquote>
  5255. <p>Since knowing how to describe an image can be difficult, there’s a <a href="">handy decision tree</a> to help when deciding. Generally speaking, if the image is decorational or there’s surrounding text that already describes the image’s information, no further information is needed. Otherwise you should describe the information of the image. If the image contains text, repeat the text in the description as well.</p>
  5257. <p>Descriptions should be succinct. It’s recommended to use no more than two sentences, but aim for one concise sentence when possible. This allows users to quickly understand the image without having to listen to a lengthy description.</p>
  5259. <p>As an example, if you were to describe this image for a screen reader, what would you say?</p>
  5271. <figure >
  5272. <a href="">
  5273. <img
  5274. srcset=",q_auto/w_400/ 400w,
  5275.,q_auto/w_800/ 800w,
  5276.,q_auto/w_1200/ 1200w,
  5277.,q_auto/w_1600/ 1600w,
  5278.,q_auto/w_2000/ 2000w"
  5279. src=",q_auto/w_400/"
  5280. sizes="100vw"
  5281. alt="Vincent van Gogh’s The Starry Night"
  5282. />
  5283. </a>
  5285. <figcaption class="op-vertical-bottom">
  5286. <a href=''>Source</a> (<a href=''>Large preview</a>)
  5287. </figcaption>
  5288. </figure>
  5291. <p>Since we describe the information of the image and not the image itself, the description could be Vincent van Gogh’s <em>The Starry Night</em> since there is no other surrounding context that describes it. What you shouldn’t put is a description of the style of the painting or what the picture looks like.</p>
  5293. <p>If the information of the image would require a lengthy description, such as a complex chart, you shouldn’t put that description in the alt text. Instead, you should still use a short description for the alt text and then provide the <a href="">long description as either a caption or link to a different page</a>.</p>
  5295. <p>This way, users can still get the most important information quickly but have the ability to dig in further if they wish. If the image is of a chart, you should repeat the data of the chart just like you would for text in the image.</p>
  5297. <p>If the platform you are designing for allows users to upload images, you should provide a way for the user to enter the alt text along with the image. For example, <a href="">Twitter allows its users to write alt text</a> when they upload an image to a tweet.</p>
  5299. <p>To use the <em>Lens of Images and Icons</em>, ask yourself these questions:</p>
  5301. <ul>
  5302. <li>Does any image contain information that would be lost if it was not viewable?</li>
  5303. <li>How could I provide the information in a non-visual way?</li>
  5304. <li>If the image is controlled by the user, is it possible to provide a way for them to enter the alt text description?</li>
  5305. </ul>
  5307. <h3 id="lens-keyboard">Lens Of Keyboard</h3>
  5309. <p>Keyboard accessibility is among the most important aspects of an accessible design, yet it is also among the most overlooked.</p>
  5311. <p>There are many reasons why a user would use a keyboard instead of a mouse. Users who use a screen reader use the keyboard to read the page. A user with tremors may use a keyboard because it provides better accuracy than a mouse. Even power users will use a keyboard because it’s faster and more efficient.</p>
  5313. <p>A user using a keyboard typically uses the tab key to navigate to each control in sequence. A logical order for the tab order greatly helps users know where the next key press will take them. In western cultures, this usually means from left to right, top to bottom. Unexpected tab orders results in users becoming lost and having to scan frantically for where the focus went.</p>
  5315. <p>Sequential tab order also means that they must tab through all controls that are before the one that they want. If that control is tens or hundreds of keystrokes away, it can be a real pain point for the user.</p>
  5317. <p>By making the most important user flows nearer to the top of the tab order, we can help enable our users to be more efficient and effective. However, this isn’t always possible nor practical to do. In these cases, providing a way to quickly jump to a particular flow or content can still allow them to be efficient. This is why &ldquo;skip to content&rdquo; links are helpful.</p>
  5319. <p>A good example of this is Facebook which <a href="">provides a keyboard navigation menu</a> that allows users to jump to specific sections of the site. This greatly speeds up the ability for a user to interact with the page and the content they want.</p>
  5331. <figure >
  5332. <a href="">
  5333. <img
  5334. srcset=",q_auto/w_400/ 400w,
  5335.,q_auto/w_800/ 800w,
  5336.,q_auto/w_1200/ 1200w,
  5337.,q_auto/w_1600/ 1600w,
  5338.,q_auto/w_2000/ 2000w"
  5339. src=",q_auto/w_400/"
  5340. sizes="100vw"
  5341. alt="facebook"
  5342. />
  5343. </a>
  5345. <figcaption class="op-vertical-bottom">
  5346. Facebook provides a way for all keyboard users to jump to specific sections of the page, or other pages within Facebook, as well as an Accessibility Help menu. (<a href=''>Large preview</a>)
  5347. </figcaption>
  5348. </figure>
  5351. <p>When tabbing through a design, focus styles should always be visible or a user can easily become lost. Just like an unexpected tab order, not having good focus indicators results in users not knowing what is currently focused and having to scan the page.</p>
  5353. <p>Changing the look of the default focus indicator can sometimes improve the experience for users. A good focus indicator doesn’t rely on color alone to indicate focus (Lens of Color), and should be distinct enough to easily allow the user to find it. For example, a blue focus ring around a similarly colored blue button may not be visually distinct to discern that it is focused.</p>
  5355. <p>Although this lens focuses on keyboard accessibility, it’s important to note that it applies to any way a user could interact with a website without a mouse. Devices such as mouth sticks, switch access buttons, sip and puff buttons, and eye tracking software all require the page to be keyboard accessible.</p>
  5357. <p>By improving keyboard accessibility, you allow a wide range of users better access to your site.</p>
  5359. <p>To use the <em>Lens of Keyboard</em>, ask yourself these questions:</p>
  5361. <ul>
  5362. <li>What keyboard navigation order makes the most sense for the design?</li>
  5363. <li>How could a keyboard user get to what they want in the quickest way possible?</li>
  5364. <li>Is the focus indicator always visible and visually distinct?</li>
  5365. </ul>
  5367. <h3 id="lens-layout">Lens Of Layout</h3>
  5369. <p>Layout contributes a great deal to the usability of a site. Having a layout that is easy to follow with easy to find content makes all the difference to your users. A layout should have a meaningful and logical sequence for the user.</p>
  5371. <p>With the advent of CSS Grid, being able to change the layout to be more meaningful based on the available space is easier than ever. However, <a href="">changing the visual layout creates problems</a> for users who rely on the structural layout of the page.</p>
  5373. <p>The structural layout is what is used by screen readers and users using a keyboard. When the visual layout changes but not the underlying structural layout, these users can become confused as their tab order is no longer logical. If you must change the visual layout, you should do so by changing the structural layout so users using a keyboard maintain a sequential and logical tab order.</p>
  5375. <p>The layout should be resizable and flexible to a minimum of 320 pixels with no horizontal scroll bars so that it can be viewed comfortably on a phone. The layout should also be flexible enough to be zoomed in to 400% (also with no horizontal scroll bars) for users who need to increase the font size for a better reading experience.</p>
  5377. <p>Users using a screen magnifier <a href="">benefit when related content is in close proximity to one another</a>. A screen magnifier only provides the user with a small view of the entire layout, so content that is related but far away, or changes far away from where the interaction occurred is hard to find and can go unnoticed.</p>
  5379. <figure><a href=""><img src="" width="800" height="" alt="GIF of CodePen showing that clicking on a button does not update the interface" /></a><figcaption>When performing a search on CodePen, the search button is in the top right corner of the page. Clicking the button reveals a large search input on the opposite side of the screen. A user using a screen magnifier would be hard pressed to notice the change and would think the button doesn’t work. (<a href="">Large preview</a>)</figcaption></figure>
  5381. <p>To use the <em>Lens of Layout</em>, ask yourself these questions:</p>
  5383. <ul>
  5384. <li>Does the layout have a meaningful and logical sequence?</li>
  5385. <li>What should happen to the layout when it’s viewed on a small screen or zoomed in to 400%?</li>
  5386. <li>Is content that is related or changes due to user interaction in close proximity to one another?</li>
  5387. </ul>
  5389. <h3 id="lens-material-honesty">Lens Of Material Honesty</h3>
  5391. <p><a href=",_functional_and_material_honesty_design_value">Material honesty is an architectural design value</a> that states that a material should be honest to itself and not be used as a substitute for another material. It means that concrete should look like concrete and not be painted or sculpted to look like bricks.</p>
  5393. <p>Material honesty values and celebrates the unique properties and characteristics of each material. An architect who follows material honesty knows when each material should be used and how to use it without tarnishing itself.</p>
  5395. <p>Material honesty is not a hard and fast rule though. <a href="">It lies on a continuum</a>. Like all values, you are allowed to break them when you understand them. As the saying goes, they are &ldquo;more what you&rsquo;d call &ldquo;guidelines&rdquo; than actual rules.&rdquo;</p>
  5397. <p><a href="">When applied to web design</a>, material honesty means that one element or component shouldn’t look, behave, or function as if it were another element or component. Doing so would cheat the user and could lead to confusion. A common example of this are <a href="">buttons that look like links or links that look like buttons</a>.</p>
  5399. <p><a href="">Links and buttons have different behaviors and affordances</a>. A link is activated with the enter key, typically takes you to a different page, and has a special context menu on right click. Buttons are activated with the space key, used primarily to trigger interactions on the current page, and have no such context menu.</p>
  5401. <p>When a link is styled to look like a button or vise versa, a user could become confused as it does not behave and function as it looks. If the “button” navigates the user away unexpectedly, they might become frustrated if they lost data in the process.</p>
  5403. <blockquote>“At first glance everything looks fine, but it won’t stand up to scrutiny. As soon as such a website is stress‐tested by actual usage across a range of browsers, the façade crumbles.”<br /><br />&mdash; <a href="">Resilient Web Design</a></blockquote>
  5405. <p>Where this becomes the most problematic is when a link and button are styled the same and are placed next to one another. As there is nothing to differentiate between the two, a user can accidentally navigate when they thought they wouldn’t.</p>
  5417. <figure >
  5418. <a href="">
  5419. <img
  5420. srcset=",q_auto/w_400/ 400w,
  5421.,q_auto/w_800/ 800w,
  5422.,q_auto/w_1200/ 1200w,
  5423.,q_auto/w_1600/ 1600w,
  5424.,q_auto/w_2000/ 2000w"
  5425. src=",q_auto/w_400/"
  5426. sizes="100vw"
  5427. alt="Three links and/or buttons shown inline with text"
  5428. />
  5429. </a>
  5431. <figcaption class="op-vertical-bottom">
  5432. Can you tell which one of these will navigate you away from the page and which won’t? (<a href=''>Large preview</a>)
  5433. </figcaption>
  5434. </figure>
  5437. <p>When a component behaves differently than expected, it can easily lead to problems for users using a keyboard or screen reader. <a href="">An autocomplete menu that is more than an autocomplete menu</a> is one such example.</p>
  5439. <p>Autocomplete is used to suggest or predict the rest of a word a user is typing. An autocomplete menu allows a user to select from a large list of options when not all options can be shown.</p>
  5441. <p>An autocomplete menu is typically attached to an input field and <a href="">is navigated with the up and down arrow keys</a>, keeping the focus inside the input field. When a user selects an option from the list, that option will override the text in the input field. Autocomplete menus are meant to be lists of just text.</p>
  5443. <p>The problem arises when an autocomplete menu starts to gain more behaviors. Not only can you select an option from the list, but you can edit it, delete it, or even expand or collapse sections. The autocomplete menu is no longer just a simple list of selectable text.</p>
  5455. <figure >
  5456. <a href="">
  5457. <img
  5458. srcset=",q_auto/w_400/ 400w,
  5459.,q_auto/w_800/ 800w,
  5460.,q_auto/w_1200/ 1200w,
  5461.,q_auto/w_1600/ 1600w,
  5462.,q_auto/w_2000/ 2000w"
  5463. src=",q_auto/w_400/"
  5464. sizes="100vw"
  5465. alt=""
  5466. />
  5467. </a>
  5469. <figcaption class="op-vertical-bottom">
  5470. With the addition of edit, delete, and profile buttons, this autocomplete menu is materially dishonest. (<a href=''>Large preview</a>)
  5471. </figcaption>
  5472. </figure>
  5475. <p>The added behaviors no longer mean you can just use the up and down arrows to select an option. Each option now has more than one action, so a user needs to be able to traverse two dimensions instead of just one. This means that a user using a keyboard could become confused on how to operate the component.</p>
  5477. <p>Screen readers suffer the most from this change of behavior as there is no easy way to help them understand it. A lot of work will be required to ensure the menu is accessible to a screen reader by using non-standard means. As such, it will might result in a sub-par or inaccessible experience for them.</p>
  5479. <p>To avoid these issues, it’s best to be honest to the user and the design. Instead of combining two distinct behaviors (an autocomplete menu and edit and delete functionality), leave them as two separate behaviors. Use an autocomplete menu to just autocomplete the name of a user, and have a different component or page to edit and delete users.</p>
  5481. <p>To use the <em>Lens of Material Honesty</em>, ask yourself these questions:</p>
  5483. <ul>
  5484. <li>Is the design being honest to the user?</li>
  5485. <li>Are there any elements that behave, look, or function as another element?</li>
  5486. <li>Are there any components that combine distinct behaviors into a single component? Does doing so make the component materially dishonest?</li>
  5487. </ul>
  5489. <h3 id="lens-readability">Lens Of Readability</h3>
  5491. <p>Have you ever picked up a book only to get a few paragraphs or pages in and want to give up because the text was too hard to read? Hard to read content is mentally taxing and tiring.</p>
  5493. <p>Sentence length, paragraph length, and complexity of language all contribute to how readable the text is. Complex language can pose problems for users, especially those with cognitive disabilities or who aren’t fluent in the language.</p>
  5495. <p>Along with using plain and simple language, you should ensure each paragraph focuses on a single idea. A paragraph with a single idea is easier to remember and digest. The same is true of a sentence with fewer words.</p>
  5497. <p>Another contributor to the readability of content is the length of a line. The ideal line length is often quoted to be between 45 and 75 characters. A line that is too long causes users to lose focus and makes it harder to move to the next line correctly, while a line that is too short causes users to jump too often, causing fatigue on the eyes.</p>
  5499. <blockquote>“The subconscious mind is energized when jumping to the next line. At the beginning of every new line the reader is focused, but this focus gradually wears off over the duration of the line”<br /><br />&mdash; Typographie: A Manual of Design</blockquote>
  5501. <p>You should also break up the content with headings, lists, or images to give mental breaks to the reader and support different learning styles. Use headings to logically group and summarize the information. Headings, links, controls, and labels should be clear and descriptive to enhance the users ability to comprehend.</p>
  5503. <p>To use the <em>Lens of Readability</em>, ask yourself these questions:</p>
  5505. <ul>
  5506. <li>Is the language plain and simple?</li>
  5507. <li>Does each paragraph focus on a single idea?</li>
  5508. <li>Are there any long paragraphs or long blocks of unbroken text?</li>
  5509. <li>Are all headings, links, controls, and labels clear and descriptive?</li>
  5510. </ul>
  5512. <h3 id="lens-structure">Lens Of Structure</h3>
  5514. <p>As mentioned in the Lens of Layout, the structural layout is what is used by screen readers and users using a keyboard. While the Lens of Layout focused on the visual layout, the Lens of Structure focuses on the structural layout, or the underlying HTML and semantics of the design.</p>
  5517.  <div id="sponsors-article" data-impression="true" class="c-promo-box c-promo-box--ad sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  5521. <p>As a designer, you may not write the structural layout of your designs. This shouldn’t stop you from thinking about how your design will ultimately be structured though. Otherwise, your design may result in an inaccessible experience for a screen reader.</p>
  5523. <p>Take for example a design for a single elimination tournament bracket.</p>
  5535. <figure >
  5536. <a href="">
  5537. <img
  5538. srcset=",q_auto/w_400/ 400w,
  5539.,q_auto/w_800/ 800w,
  5540.,q_auto/w_1200/ 1200w,
  5541.,q_auto/w_1600/ 1600w,
  5542.,q_auto/w_2000/ 2000w"
  5543. src=",q_auto/w_400/"
  5544. sizes="100vw"
  5545. alt="Eight person tournament bracket featuring George, Fred, Linus, Lucy, Jack, Jill, Fred, and Ginger. Ginger ultimately wins against George."
  5546. />
  5547. </a>
  5549. <figcaption class="op-vertical-bottom">
  5550. <a href=''>Large preview</a>
  5551. </figcaption>
  5552. </figure>
  5555. <p>How would you know if this design was accessible to a user using a screen reader? Without understanding structure and semantics, you may not. As it stands, the design would probably result in an inaccessible experience for a user using a screen reader.</p>
  5557. <p>To understand why that is, we first must understand that a screen reader reads a page and its content in sequential order. This means that every name in the first column of the tournament would be read, followed by all the names in the second column, then third, then the last.</p>
  5559. <blockquote>“George, Fred, Linus, Lucy, Jack, Jill, Fred, Ginger, George, Lucy, Jack, Ginger, George, Ginger, Ginger.”</blockquote>
  5561. <p>If all you had was a list of seemingly random names, how would you interpret the results of the tournament? Could you say who won the tournament? Or who won game 6?</p>
  5563. <p>With nothing more to work with, a user using a screen reader would probably be a bit confused about the results. To be able to understand the visual design, we must provide the user with more information in the structural design.</p>
  5565. <p>This means that as a designer you need to know how a screen reader interacts with the HTML elements on a page so you know how to enhance their experience.</p>
  5567. <ul>
  5568. <li><strong>Landmark Elements</strong> (header, nav, main, and footer)<br />
  5569. Allow a screen reader to jump to important sections in the design.</li>
  5570. <li><strong>Headings</strong> (<code>h1</code> &rarr; <code>h6</code>)<br />
  5571. Allow a screen reader to scan the page and get a high level overview. Screen readers can also jump to any heading.</li>
  5572. <li><strong>Lists</strong> (<code>ul</code> and <code>ol</code>)<br />
  5573. Group related items together, and allow a screen reader to easily jump from one item to another.</li>
  5574. <li><strong>Buttons</strong><br />
  5575. Trigger interactions on the current page.</li>
  5576. <li><strong>Links</strong><br />
  5577. Navigate or retrieve information.</li>
  5578. <li><strong>Form labels</strong><br />
  5579. Tell screen readers what each form input is.</li>
  5580. </ul>
  5582. <p>Knowing this, how might we provide more meaning to a user using a screen reader?</p>
  5584. <p>To start, we could group each column of the tournament into rounds and use headings to label each round. This way, a screen reader would understand when a new round takes place.</p>
  5586. <p>Next, we could help the user understand which players are playing against each other each game. We can again use headings to label each game, allowing them to find any game they might be interested in.</p>
  5588. <p>By just adding headings, the content would read as follows:</p>
  5590. <blockquote>“__Round 1, Game 1__, George, Fred, __Game 2__, Linus, Lucy, __Game 3__, Jack, Jill, __Game 4__, Fred, Ginger, __Round 2, Game 5__, George, Lucy, __Game 6__, Jack, Ginger, __Round 3__, __Game 7__, George, Ginger, __Winner__, Ginger.”</blockquote>
  5592. <p>This is already a lot more understandable than before.</p>
  5594. <p>The information still doesn’t answer who won a game though. To know that, you&rsquo;d have to understand which game a winner plays next to see who won the previous game. For example, you&rsquo;d have to know that the winner of game four plays in game six to know who advanced from game four.</p>
  5596. <p>We can further enhance the experience by informing the user who won each game so they don’t have to go hunting for it. Putting the text &ldquo;(winner)&rdquo; after the person who won the round would suffice.</p>
  5598. <p>We should also further group the games and rounds together using lists. Lists provide the structural semantics of the design, essentially informing the user of the connected nodes from the visual design.</p>
  5600. <p>If we translate this back into a visual design, the result could look as follows:</p>
  5612. <figure >
  5613. <a href="">
  5614. <img
  5615. srcset=",q_auto/w_400/ 400w,
  5616.,q_auto/w_800/ 800w,
  5617.,q_auto/w_1200/ 1200w,
  5618.,q_auto/w_1600/ 1600w,
  5619.,q_auto/w_2000/ 2000w"
  5620. src=",q_auto/w_400/"
  5621. sizes="100vw"
  5622. alt="The tournament bracket"
  5623. />
  5624. </a>
  5626. <figcaption class="op-vertical-bottom">
  5627. The tournament with descriptive headings and winner information (shown here with grey background). (<a href=''>Large preview</a>)
  5628. </figcaption>
  5629. </figure>
  5632. <p>Since the headings and winner text are redundant in the visual design, <a href="">you could hide them just from visual users</a> so the end visual result looks just like the first design.</p>
  5634. <p>&ldquo;If the end result is visually the same as where we started, why did we go through all this?&rdquo; You may ask.</p>
  5636. <p>The reason is that you should always annotate your design with all the necessary structural design requirements needed for a better screen reader experience. This way, the person who implements the design knows to add them. If you had just handed the first design to the implementer, it would more than likely end up inaccessible.</p>
  5638. <p>To use the <em>Lens of Structure</em>, ask yourself these questions:</p>
  5640. <ul>
  5641. <li>Can I outline a rough HTML structure of my design?</li>
  5642. <li>How can I structure the design to better help a screen reader understand the content or find the content they want?</li>
  5643. <li>How can I help the person who will implement the design understand the intended structure?</li>
  5644. </ul>
  5646. <h3 id="lens-time">Lens Of Time</h3>
  5648. <p>Periodically in a design you may need to limit the amount of time a user can spend on a task. Sometimes it may be for security reasons, such as a session timeout. Other times it could be due to a non-functional requirement, such as a time constrained test.</p>
  5650. <p>Whatever the reason, you should understand that some users may need more time in order finish the task. Some users might need more time to understand the content, others might not be able to perform the task quickly, and a lot of the time they could just have been interrupted.</p>
  5652. <blockquote>“The designer should assume that people will be interrupted during their activities”<br /><br />&mdash; The Design of Everyday Things</blockquote>
  5654. <p>Users who need more time to perform an action should be able to adjust or remove a time limit when possible. For example, with a session timeout you could alert the user when their session is about to expire and allow them to extend it.</p>
  5656. <p>To use the <em>Lens of Time</em>, ask yourself this question:</p>
  5658. <ul>
  5659. <li>Is it possible to provide controls to adjust or remove time limits?</li>
  5660. </ul>
  5662. <h3 id="bringing-it-all-together">Bringing It All Together</h3>
  5664. <p>So now that you’ve learned about the different lenses of accessibility through which you can view your design, what do you do with them?</p>
  5666. <p>The lenses can be used at any point in the design process, even after the design has been shipped to your users. Just start with a few of them at hand, and one at a time carefully analyze the design through a lens.</p>
  5668. <p>Ask yourself the questions and see if anything should be adjusted to better meet the needs of a user. As you slowly make changes, bring in other lenses and repeat the process.</p>
  5670. <p>By looking through your design one lens at a time, you&rsquo;ll be able to refine the experience to better meet users&rsquo; needs. As you are more inclusive to the needs of your users, you will create a more accessible design for all your users.</p>
  5672. <p><em>Using lenses and insightful questions to examine principles of accessibility was heavily influenced by <a href="">Jesse Schell</a> and his book “The Art of Game Design: A Book of Lenses.”</em></p>
  5674. <div class="signature">
  5675.  <img src="" alt="Smashing Editorial">
  5676.  <span>(il, ra, yk)</span>
  5677. </div>
  5681.  <div id="sponsors-article-end" data-impression="true" class="c-promo-box c-promo-box--ad c-promo-box--wide sponsors hidden" data-audience="non-subscriber" data-remove="true"></div>
  5685. </div>
  5689.              </article>
  5690.            </body>
  5691.          </html>
  5692.        ]]></content:encoded>
  5693.      </item>
  5695.      <item>
  5698.          <author>Andrew Clarke</author>
  5700.        <title>Art Directing For The Web With CSS Grid Template Areas</title>
  5701.        <link></link>
  5702.        <pubDate>Mon, 09 Apr 2018 11:00:23 +0200</pubDate>
  5703.        <guid></guid>
  5704.        <description>(This article is kindly sponsored by CoffeeCup Software.) Alright, I’m going to get straight to the point. CSS Grid is important, really important, too important to be one of those &#34;I’ll use it when all browsers support it&#34; properties. That’s because, with CSS Grid, we can now be as creative with layout on the web as we can in print, without compromising accessibility, responsiveness, or usability.
  5705. If you’re at all serious about web design or development, you need to be serious about learning and using CSS Grid too.</description>
  5706.        <content:encoded><![CDATA[
  5707.          <html>
  5708.            <head>
  5709.              <meta charset="utf-8">
  5710.              <link rel="canonical" href="" />
  5711.              <title>Art Directing For The Web With CSS Grid Template Areas</title>
  5712.            </head>
  5713.            <body>
  5714.              <article>
  5715.                <header>
  5716.                  <h1>Art Directing For The Web With CSS Grid Template Areas</h1>
  5719.                    <address>Andrew Clarke</address>
  5721.                  <time datetime="2018-04-09T11:00:23&#43;02:00" class="op-published">2018-04-09T11:00:23+02:00</time>
  5722.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  5723.                </header>
  5724.                <p>(<em>This article is kindly sponsored by CoffeeCup Software</em>.) Alright, I’m going to get straight to the point. CSS Grid is important, really important, too important to be one of those "I’ll use it when all browsers support it" properties. That’s because, with CSS Grid, we can now be as creative with layout on the web as we can in print, without compromising accessibility, responsiveness, or usability.</p>
  5726. <p>If you’re at all serious about web design or development, you need to be serious about learning and using CSS Grid too. In this article I’m going to explain how to use one aspect, <strong>grid-template areas</strong>, a way of arranging elements that even a big, dumb mug like me can understand, and one that doesn’t get enough attention.</p>
  5728. <p>Now, you want to see some action and some code, I know that, but hold on one Goddam minute. Before you learn "how," I want to teach you "why" it’s important to make the kind of layouts we’ve seen in other media for decades, but have mostly been absent from the web.</p>
  5730. <h3>Feeling Frustrated</h3>
  5732. <p>I guess you’ve seen those "which one of these two layouts are you designing today?" tweets, lamenting the current state of design on the web. Even I’ve spoken about how web design’s lost its "soul." I bet you’ve also seen people use CSS Grid to recreate posters or pages from magazines. These technical demonstrations are cool, and they show how easy implementing complex layouts with CSS Grid can be when compared to other methods, but they don’t get to the bottom of why doing this stuff matters.</p>
  5734. <p>So what’s the reason? Why’s layout such an important part of design? Well, it all boils down to one thing, and that’s communication.</p>
  5737. <div class="c-garfield-the-cat">
  5740. <p>For what seems like forever, web designers have created templates, then filled them, with little consideration of the relationship between content and layout. I suppose that’s inevitable, given considerations for content management systems, our need to make designs responsive, and the limitations of the CSS properties we’ve used until now. Sure, we’ve made designs that are flexible, usable, but we’ve been missing a key piece of the puzzle, the role that layout plays in delivering a message.</p>
  5742. <p>If you’ve been around the block a few times, you’ll know the role color plays in setting the right tone for a design. I don’t need to tell you that type plays its part too. Pick the wrong typeface, and you run the risk of communicating ineffectively and leaving people feeling differently to how you intended.</p>
  5744. <p>Layout &mdash; closely linked to aspects of typography like the ’measure’ &mdash; plays an equally important role. Symmetry and asymmetry, harmony and tension. These principles draw people to your content, guide them, and help them understand it more easily. That’s why crafting the right layout is as important as choosing the most appropriate typeface. Print designers have known this for years.</p>
  5746. <h3>Telling Stories Through Art Direction</h3>
  5748. <p>Art direction matters as much on the web as it does in other media, including print, and what I’m going to cover applies as much to promoting digital products as it does to telling stories.</p>
  5750. <p>What do you think of when you hear the term ’art direction?’ Do you think about responsive images, presenting alternative crops, sizes or orientations to several screen sizes using the &lt;picture&gt; element or ’sizes’ in HTML? They’ve become useful responsive design and art direction tools, but there’s more to web design than tools.</p>
  5752. <p>Do you think of those designers like <a href="">Jason Santa Maria</a> and <a href="">Trent Walton</a> who sometimes art direct their writing by giving an entry its own, distinctive image, layout and typography. This gets us closer to understanding art direction, but images, layout, and typography are only the result of art direction, not the meaning of it.</p>
  5754. <p>So if art direction isn’t exactly those things, what exactly is it? In a sentence, it’s the art of distilling an essential, precise meaning or purpose from a piece of content &mdash; be that magazine article or a list of reasons why to use the coolest app from the hottest start-up &mdash; and conveying that meaning or purpose better by using design. We don’t hear much about art direction on the web, but it’s well established in another medium, perhaps the most memorable being magazines and to some extent newspapers.</p>
  5756. <p>I’m not old enough to remember first hand <a href="">Alexey Brodovitch</a>’s work on Harpers Bazaar magazine from 1934 to 1958.</p>
  5768. <figure class="article__image break-out">
  5769. <a href="">
  5770. <img
  5771. srcset=",q_auto/w_400/ 400w,
  5772.,q_auto/w_800/ 800w,
  5773.,q_auto/w_1200/ 1200w,
  5774.,q_auto/w_1600/ 1600w,
  5775.,q_auto/w_2000/ 2000w"
  5776. src=",q_auto/w_400/"
  5777. sizes="100vw"
  5778. alt="designs by Brodovitch"
  5779. />
  5780. </a>
  5782. <figcaption class="op-vertical-bottom">
  5783. Fig.1. What I love about these designs &mdash; particularly his pencil sketches &mdash; is how Brodovitch placed his content to perfectly reflect the image that accompanies it.
  5784. </figcaption>
  5785. </figure>
  5788. <p>I do remember <a href="">Neville Brody</a>’s artistic art direction for the Face magazine and I’m still inspired by it every day.</p>
  5800. <figure class="article__image break-out">
  5801. <a href="">
  5802. <img
  5803. srcset=",q_auto/w_400/ 400w,
  5804.,q_auto/w_800/ 800w,
  5805.,q_auto/w_1200/ 1200w,
  5806.,q_auto/w_1600/ 1600w,
  5807.,q_auto/w_2000/ 2000w"
  5808. src=",q_auto/w_400/"
  5809. sizes="100vw"
  5810. alt="Brody’s pages from The Face magazine"
  5811. />
  5812. </a>
  5814. <figcaption class="op-vertical-bottom">
  5815. Fig.2. Even twenty five years after he created them, Brody’s pages from The Face magazine are still remarkable designs.
  5816. </figcaption>
  5817. </figure>
  5820. <p>Art direction is so rarely discussed in relation to the web that you could be forgiven for thinking that it’s not relevant. Perhaps you see art direction as an activity that’s more suited to the print world than it is to the web? Some people might think of art direction as elitist in some way.</p>
  5822. <p>I don’t think that any of that’s true. Stories are stories, no matter where they’re told or through what medium. They may be thought-provoking like the ones published on <a href="">ProPublica</a>, or they might be the story of your company and why people should do business with you. There’s the story of how your charity supports a good cause and why people should donate to it. Then there’s the story of your start-up’s new app and why someone should download it. With all of these stories, there’s a deeper message beyond just telling the facts about what you do or sell.</p>
  5824. <p>Art direction is about understanding those messages and deciding how best to communicate them through the organization and presentation of words and visuals. Is art direction relevant for the web? Of course. Art directors use design to help people better understand the significance of a piece of content, and that’s as important on the web as it is in print. In fact, the basic principles of art direction haven’t changed between print and digital.</p>
  5826. <p>I’d go further, by saying that art direction is essential to creating cohesive experiences across multiple channels, so that the meaning of a story isn’t lost in the gaps between devices and screen sizes.</p>
  5828. <p>David Hillman, formerly of The Guardian and New Statesman and designer of many other publications said:</p>
  5830. <blockquote>"In its best form, (art direction) involves the art director having a full and in-depth understanding of what the magazine says, and through design, influencing how it is said."</blockquote>
  5832. <p>My friend <a href="">Mark Porter</a>, coincidentally the former Creative Director at The Guardian also said:</p>
  5834. <blockquote>"Design is being in charge of the distribution of elements in space."</blockquote>
  5836. <p>CSS Grid makes being in charge of the distribution of elements more possible than ever before.</p>
  5838. <h3>Art Directing A Hardboiled Story</h3>
  5840. <p>I guess now is the time to get down to it, so I’m going to tell you how to put some of this to work in a series of <em>Hardboiled</em> examples. I’ll shine a flashlight on layout and how it helps storytelling and then give you the low down on how to develop one of these designs using CSS Grid.</p>
  5852. <figure class="article__image break-out">
  5853. <a href="">
  5854. <img
  5855. srcset=",q_auto/w_400/ 400w,
  5856.,q_auto/w_800/ 800w,
  5857.,q_auto/w_1200/ 1200w,
  5858.,q_auto/w_1600/ 1600w,
  5859.,q_auto/w_2000/ 2000w"
  5860. src=",q_auto/w_400/"
  5861. sizes="100vw"
  5862. alt="several ’shots’ of a story in a Hardboiled book"
  5863. />
  5864. </a>
  5866. <figcaption class="op-vertical-bottom">
  5867. Fig.3. When I conceived the covers for my Hardboiled books, I wanted the story to continue across several ’shots.’ (Left: Cover illustrations by <a href=''>Kevin Cornell</a>. Right: Cover illustrations by <a href=''>Natalie Smith</a>.) (Copyright: <a href=''>Stuff & Nonsense</a>)
  5868. </figcaption>
  5869. </figure>
  5872. <p>First, the backstory. On the cover of my 2010 edition of <em>Hardboiled Web Design</em> (1), a mystery woman in a red dress (there’s always a woman in a red dress) is pointing a gun at our private dick. (Sheesh, I know that feeling.) By the <a href="">Fifth Anniversary Edition</a> in 2015 (2), the story’s moved on and a shadow moves ominously across the door of our detective’s office. The door flies open, two villains burst in (3), and a fist fight ensues (4). Our mystery woman sure knows how to throw a punch and before you can say "kiss me, deadly" one villain’s tied to a chair and ready to spill the beans (5).</p>
  5874. <h4>Chapter Three</h4>
  5876. <p>I’ll start telling that story at the explosive moment when those two villains bust open the door. Now, if you’ve read Scott McCloud’s book ‘<a href="">Understanding Comics</a>’ you’ll know that panel size affects how long people spend looking at an area, so I want to make the image of our bad guys as large as possible to maximise its impact (1). What the hoods don’t know is that our woman is waiting for them. I use layout to add tension by connecting their eye lines, (2) at the same time drawing a reader’s eyes to where the content starts.</p>
  5888. <figure class="article__image break-out">
  5889. <a href="">
  5890. <img
  5891. srcset=",q_auto/w_400/ 400w,
  5892.,q_auto/w_800/ 800w,
  5893.,q_auto/w_1200/ 1200w,
  5894.,q_auto/w_1600/ 1600w,
  5895.,q_auto/w_2000/ 2000w"
  5896. src=",q_auto/w_400/"
  5897. sizes="100vw"
  5898. alt="Adding tension by connecting eye lines and maximise impact through large images."
  5899. />
  5900. </a>
  5902. <figcaption class="op-vertical-bottom">
  5903. Fig.4. Add tension by connecting eye lines and maximise impact through large images. (View <a href=''>project files on CodePen</a>) (Copyright: <a href=''>Stuff & Nonsense</a>)
  5904. </figcaption>
  5905. </figure>
  5908. <h4>Chapter Four</h4>
  5910. <p>As the first villain bursts onto the scene, I use the left edge of the page, without margins, to represent the open door (1). As most of the action takes place on the right, I create a large spacial zone using the majority of the height and width of the page (2).</p>
  5912. <p>Now, when fists fly in all directions, our layout needs to do the same, so my content comes from the top &mdash; where whitespace draws the eye down to the bold paragraph (3) &mdash; and from the left with the enormous headline (4). You might be wondering why I haven’t mentioned that smaller image in the top-right, but I’ll get to that in a minute.</p>
  5924. <figure class="article__image break-out">
  5925. <a href="">
  5926. <img
  5927. srcset=",q_auto/w_400/ 400w,
  5928.,q_auto/w_800/ 800w,
  5929.,q_auto/w_1200/ 1200w,
  5930.,q_auto/w_1600/ 1600w,
  5931.,q_auto/w_2000/ 2000w"
  5932. src=",q_auto/w_400/"
  5933. sizes="100vw"
  5934. alt="When fists fly, a layout needs to do the same."
  5935. />
  5936. </a>
  5938. <figcaption class="op-vertical-bottom">
  5939. Fig.5. When fists fly, a layout needs to do the same. (View <a href=''>project files on CodePen</a>) (Copyright: <a href=''>Stuff & Nonsense</a>)
  5940. </figcaption>
  5941. </figure>
  5944. <h4>Chapter Five</h4>
  5946. <p>The fight’s over, and our detective is back in control, so on this final page I use a more structured layout to reflect the order that’s returned. Solid columns of justified text (1) with plenty of whitespace around them add to the feeling of calm. At the same time, the right aligned caption (2) feels edgy and uncomfortable, like the gunpoint interrogation that’s taking place.</p>
  5958. <figure class="article__image break-out">
  5959. <a href="">
  5960. <img
  5961. srcset=",q_auto/w_400/ 400w,
  5962.,q_auto/w_800/ 800w,
  5963.,q_auto/w_1200/ 1200w,
  5964.,q_auto/w_1600/ 1600w,
  5965.,q_auto/w_2000/ 2000w"
  5966. src=",q_auto/w_400/"
  5967. sizes="100vw"
  5968. alt="using layout to create order as well as disorder"
  5969. />
  5970. </a>
  5972. <figcaption class="op-vertical-bottom">
  5973. Fig.6. We can use layout to create order as well as disorder. (View <a href=''>project files on CodePen</a>) (Copyright: <a href=''>Stuff & Nonsense</a>)
  5974. </figcaption>
  5975. </figure>
  5978. <h3>Getting My Dands Dirty</h3>
  5980. <p>It’s time for a confession. I’m not going to teach you everything you need to know about developing layouts using CSS Grid as there are plenty of smarter people who’ve done that before:</p>
  5982. <ul>
  5983. <li><a href="">Grid by Example</a> by Rachel Andrew</li>
  5984. <li>Learn <a href="">CSS Grid</a> with Wes Bos</li>
  5985. <li><a href="">A Complete Guide to Grid</a> by Chris House on CSS Tricks</li>
  5986. </ul>
  5988. <p>Instead, I’ll show you the inspiration for one grid, how I translated it into a (large screen) layout using columns and rows in CSS Grid, and then placed elements into the spacial zones created using the <strong>grid-template areas</strong> property. Finally, I’ll deconstruct and alter the design for smaller screen sizes.</p>
  5990. <h3>The Perfect Beat</h3>
  5992. <p>My inspiration for the layout I use came from this 1983 design by Neville Brody for <em>The Face Magazine</em>. I was drawn to how Brody cleverly created both horizontal and vertical axis and the large space occupied by the main image.</p>
  6004. <figure class="article__image break-out">
  6005. <a href="">
  6006. <img
  6007. srcset=",q_auto/w_400/ 400w,
  6008.,q_auto/w_800/ 800w,
  6009.,q_auto/w_1200/ 1200w,
  6010.,q_auto/w_1600/ 1600w,
  6011.,q_auto/w_2000/ 2000w"
  6012. src=",q_auto/w_400/"
  6013. sizes="100vw"
  6014. alt="layout by Neville Brody for The Face Magazine"
  6015. />
  6016. </a>
  6018. <figcaption class="op-vertical-bottom">
  6019. Fig.7. This layout by Neville Brody for The Face Magazine felt like the perfect starting point for my design. Look closely at Brody’s grid, and you should spot that he used five columns of equal width.
  6020. </figcaption>
  6021. </figure>
  6024. <p>I did the same by applying the following CSS Grid properties to the margin-less &lt;body&gt; element of my page, where columns one fraction unit wide repeat five times with a 2vw gap between them:</p>
  6026. <pre><code class="language-css">body {
  6027. margin: 0;
  6028. padding : 0;
  6029. display: grid;
  6030. grid-column-gap : 2vw;
  6031. grid-template-columns: repeat(5, 1fr); }
  6032. </code></pre>
  6044. <figure class="article__image break-out">
  6045. <a href="">
  6046. <img
  6047. srcset=",q_auto/w_400/ 400w,
  6048.,q_auto/w_800/ 800w,
  6049.,q_auto/w_1200/ 1200w,
  6050.,q_auto/w_1600/ 1600w,
  6051.,q_auto/w_2000/ 2000w"
  6052. src=",q_auto/w_400/"
  6053. sizes="100vw"
  6054. alt="combining five equal width columns"
  6055. />
  6056. </a>
  6058. <figcaption class="op-vertical-bottom">
  6059. Fig.8. I combine five equal width columns in different ways to create spacial zones.
  6060. </figcaption>
  6061. </figure>
  6064. <p>In CSS Grid we define a grid module by giving it a name, then we place an element into either a single module or multiple adjacent modules &mdash; known as spacial zones &mdash; with the <strong>grid-template-areas</strong> property. Sounds complicated huh? No, not really. It’s one of the easiest and most obvious ways of using CSS Grid, so let’s get to work.</p>
  6066. <p>First things, first. I have five elements to position, and they are my "Kiss Me, Deadly" title, the largest ’banner’ image, main content, aside paragraph and two images, fig-1 and fig-2. My HTML looks like this:</p>
  6068. <pre><code class="language-html">&lt;body&gt;
  6069. &lt;picture role="banner"&gt;&#8230;&lt;/picture&gt;
  6070. &lt;h1 class="title">&#8230;&lt;/h1&gt;
  6071. &lt;main>&#8230;&lt;/main&gt;
  6072. &lt;aside>&#8230;&lt;/aside&gt;
  6073. &lt;img class="fig-1"&gt;
  6074. &lt;img class="fig-2"&gt;
  6075. &lt;/body&gt;
  6076. </code></pre>
  6078. <p>I wrote that markup in the order that makes most sense, just as I would when constructing a narrative. It reads like a dream on small screens and even without styles. I give each element a <strong>grid-area</strong> value that in a moment I’ll use to place it on my grid:</p>
  6080. <pre><code class="language-css">[role="banner"] { grid-area: banner; }
  6081. .title { grid-area: title; }
  6082. main { grid-area: main; }
  6083. aside { grid-area: aside; }
  6084. .fig-1 { grid-area: fig-1; }
  6085. .fig-2 { grid-area: fig-2; }
  6086. </code></pre>
  6088. <p>Your grid area values don’t necessarily need to reflect your element types. In fact, you can use any values, even single letters like a, b, c, or d.</p>
  6090. <p>Back with the grid, I add three rows to the columns I created earlier. The height of each row is automatically defined by the height of the content inside it:</p>
  6092. <pre><code class="language-css">body {
  6093. grid-template-rows: repeat(3, auto); }
  6094. </code></pre>
  6096. <p>Here’s where the magic happens. I literally draw the grid in CSS using the grid-template-areas property, where each period (.) represents one empty module:</p>
  6098. <pre><code class="language-css">body {
  6099. grid-template-areas:
  6100. ".  .  .  .  ."
  6101. ".  .  .  .  ."
  6102. ".  .  .  .  ."; }
  6103. </code></pre>
  6105. <p>Now it’s time to position elements on that grid using the grid-area values I created earlier. I place each elements’ value into a module on the grid and if I repeat that value across multiple adjacent modules &mdash; either across columns or row, that element will expand across them to create a spacial zone. Leaving a period (.) will create an empty space:</p>
  6107. <pre><code class="language-css">body {
  6108. grid-template-areas:
  6109. ".  aside  .  fig-2  fig-2"
  6110. "title  title  banner  banner  banner"
  6111. "fig-2  main  banner  banner  banner"; }
  6112. </code></pre>
  6114. <p>One more small detail before I finish the layout CSS. I want the content of the aside element to sit at the bottom &mdash; close to the title and leaving ample white space above it to draw someone’s eye down &mdash; so I use an align-self property that might be familiar from learning Flexbox, but with a new value of ’end.‘</p>
  6116. <pre><code class="language-css">aside {
  6117. align-self: end; }
  6118. </code></pre>
  6130. <figure class="article__image break-out">
  6131. <a href="">
  6132. <img
  6133. srcset=",q_auto/w_400/ 400w,
  6134.,q_auto/w_800/ 800w,
  6135.,q_auto/w_1200/ 1200w,
  6136.,q_auto/w_1600/ 1600w,
  6137.,q_auto/w_2000/ 2000w"
  6138. src=",q_auto/w_400/"
  6139. sizes="100vw"
  6140. alt="CSS Grid layout for larger screens"
  6141. />
  6142. </a>
  6144. <figcaption class="op-vertical-bottom">
  6145. Fig.9. That’s it, my CSS Grid layout for larger screens is done. (Copyright: <a href=''>Stuff & Nonsense</a>)
  6146. </figcaption>
  6147. </figure>
  6150. <p>All that remains is to add a few other styles to bring the design to life, including a striking inverse color scheme and a bright, red accent that ties the word "Deadly" in the title to the color of our woman’s dress:</p>
  6152. <pre><code class="language-css">&lt;h1 class="title"&gt;Kiss Me, &lt;em&gt;Deadly&lt;/em&gt;&lt;/h1&gt;
  6154. .title em {
  6155. font-style: normal;
  6156. color : #fe3d6b; }
  6157. </code></pre>
  6159. <h3>Going Up In Smoke</h3>
  6161. <p>Now, I know you’ve been wondering about that smaller fight image, and I need to admit something. <a href="">Natalie Smith</a> made only one finished fists flying illustration for my <em>Hardboiled Shot</em> covers, but her sketches were too good to waste. I used CSS Grid to position an inverted version of one pencil sketch above the gun and rotated it with a CSS transform to form a cloud of smoke.</p>
  6173. <figure >
  6174. <a href="">
  6175. <img
  6176. srcset=",q_auto/w_400/ 400w,
  6177.,q_auto/w_800/ 800w,
  6178.,q_auto/w_1200/ 1200w,
  6179.,q_auto/w_1600/ 1600w,
  6180.,q_auto/w_2000/ 2000w"
  6181. src=",q_auto/w_400/"
  6182. sizes="100vw"
  6183. alt="CSS Grid and transforms turn this sketch into a cloud of smoke."
  6184. />
  6185. </a>
  6187. <figcaption class="op-vertical-bottom">
  6188. Fig.10. CSS Grid and transforms turn this sketch into a cloud of smoke. (Copyright: <a href=''>Stuff & Nonsense</a>)
  6189. </figcaption>
  6190. </figure>
  6193. <h3>Breaking It Down</h3>
  6195. <p>In this article, I’ve shown how to create a layout for large screens, but in reality, I start with a small one and then work up, using breakpoints to add or change styles. With CSS Grid, adapting a layout to various screen sizes is as easy as positioning elements into different grid-template areas. There are two ways that I can do this, first by changing the grid itself:</p>
  6197. <pre><code class="language-css">body {
  6198. grid-template-columns: 50px repeat(2, 1fr); }
  6200. @media screen and (min-width : 48em) {
  6201. body {
  6202. grid-template-columns: repeat(5, 1fr); }
  6203. }
  6204. </code></pre>
  6206. <p>The second, by positioning elements into different grid-template areas on the same grid:</p>
  6208. <pre><code class="language-css">body {
  6209. grid-template-areas:
  6210. "fig-1  aside  aside  aside  aside"
  6211. "fig-1  title  title  title  title"
  6212. "banner  banner  banner  banner  banner"
  6213. "....  main  main  main  main"; }
  6215. @media screen and (min-width : 64em) {
  6216. body {
  6217. grid-template-areas:
  6218. "....  aside  ....  fig-2  fig-2"
  6219. "title  title  banner  banner  banner"
  6220. "fig-1  main  banner  banner  banner"; }
  6221. }
  6222. </code></pre>
  6234. <figure class="article__image break-out">
  6235. <a href="">
  6236. <img
  6237. srcset=",q_auto/w_400/ 400w,
  6238.,q_auto/w_800/ 800w,
  6239.,q_auto/w_1200/ 1200w,
  6240.,q_auto/w_1600/ 1600w,
  6241.,q_auto/w_2000/ 2000w"
  6242. src=",q_auto/w_400/"
  6243. sizes="100vw"
  6244. alt="adapting layout to various screen sizes"
  6245. />
  6246. </a>
  6248. <figcaption class="op-vertical-bottom">
  6249. Fig.11. Adapting my layout to various screen sizes is as easy as positioning elements into different grid-template areas. Small screen (left) Medium screen (right). (Copyright: <a href=''>Stuff & Nonsense</a>)
  6250. </figcaption>
  6251. </figure>
  6254. <h3>Using CSS Grid Builder</h3>
  6256. <p>Grid template areas make developing art directed layouts so easy that even a flat-foot like me can do it, but if you’re the type that likes tools to do the dirty work, <a href="">CSS Grid Builder</a> from CoffeeCup Software might be just the thing for you. You may have used WYSIWYG editors before, so you might be remembering how lousy the code they spat out was. Let me stop you there. CSS Grid Builder outputs clean CSS and accessible markup. Maybe not as clean as you write yourself, but pretty damn close, and the small team who developed it plan to make it even better. My handwritten HTML looks like this:</p>
  6258. <pre><code class="language-css">&lt;picture role="banner"&gt;
  6259.    &lt;source srcset="banner.png" media="(min-width: 64em)"&gt;
  6260.    &lt;img src="banner-small.png" alt="Kiss Me, Deadly"&gt;
  6261. &lt;/picture&gt;
  6262. </code></pre>
  6264. <p>The CSS Grid Builder &lt;picture&gt; element comes wrapped in an extra division, with a few other elements thrown in for good measure:</p>
  6266. <pre><code class="language-css">&lt;div class="responsive-picture banner" role="banner"&gt;
  6267.    &lt;picture&gt;
  6268.    &lt;!--[if IE 9]&gt;&lt;video style="display: none;"&gt;&lt;![endif]--&gt;
  6269.    &lt;source srcset="banner.png" media="(min-width: 64em)"&gt;
  6270.    &lt;!--[if IE 9]&gt;&lt;/video&gt;&lt;![endif]--&gt;
  6271.    &lt;img alt="Kiss Me, Deadly" src="banner-small.png"&gt;
  6272.    &lt;/picture&gt;
  6273. &lt;/div&gt;
  6274. </code></pre>
  6276. <p>Like I said, close enough, and if you don’t believe me, <a href="">download a set of exported files</a> from my <em>Hardboiled</em> example. Maybe that’ll convince you.</p>
  6278. <p>Browsers’ developer tools are getting better at inspecting grids, but CSS Grid Builder helps you build them. Obviously. At its core, CSS Grid Builder is a Chromium-based browser wrapped in a user-interface, and it runs on macOS and Windows. That means that if the browser can render it, the UI tools can write it, with one or two notable exceptions including CSS Shapes.</p>
  6280. <p>In fact, CSS Grid Builder builds more than grids, and you can use it to create styles for backgrounds &mdash; including <strong>gradients</strong>, which is very handy &mdash; borders, and <strong>typography</strong>. It even handles <strong>Flexbox and multi-column layouts</strong>, but you’re here because you want to learn about CSS Grid.</p>
  6282. <h3>Looking Around The Interface</h3>
  6284. <p>The interface in CSS Grid Builder, is pretty much as you’d expect it, with a wide area for the design you’re making on the left and controls over on the right. Those controls include common elements; text, images, interactive buttons and form controls, and layout containers. If you need one of those elements, drag and drop it into your work area.</p>
  6296. <figure class="article__image break-out">
  6297. <a href="">
  6298. <img
  6299. srcset=",q_auto/w_400/ 400w,
  6300.,q_auto/w_800/ 800w,
  6301.,q_auto/w_1200/ 1200w,
  6302.,q_auto/w_1600/ 1600w,
  6303.,q_auto/w_2000/ 2000w"
  6304. src=",q_auto/w_400/"
  6305. sizes="100vw"
  6306. alt="Drag and drop common elements including text, images, and layout containers."
  6307. />
  6308. </a>
  6310. <figcaption class="op-vertical-bottom">
  6311. Drag and drop common elements including text, images, and layout containers.
  6312. </figcaption>
  6313. </figure>
  6316. <p>Press to reveal the Styles tab, and you’ll find controls for naming class and ID attributes, applying styles at specific breakpoints and in particular states. All very useful, but it’s the layout section &mdash; somewhat inconveniently tucked away at the bottom of the pane &mdash; that’s the most interesting.</p>
  6328. <figure class="article__image break-out">
  6329. <a href="">
  6330. <img
  6331. srcset=",q_auto/w_400/ 400w,
  6332.,q_auto/w_800/ 800w,
  6333.,q_auto/w_1200/ 1200w,
  6334.,q_auto/w_1600/ 1600w,
  6335.,q_auto/w_2000/ 2000w"
  6336. src=",q_auto/w_400/"
  6337. sizes="100vw"
  6338. alt="Styles layout section contains grid controls."
  6339. />
  6340. </a>
  6342. <figcaption class="op-vertical-bottom">
  6343. Styles layout section contains grid controls.
  6344. </figcaption>
  6345. </figure>
  6348. <p>In this section you can design a grid. Setting up columns and rows to form a layout without visual representation can be one of the hardest parts of learning how ‘grid’ works. The app’s ability to visually define the grid structure is a handy feature, especially when you’re new to CSS Grid. This is the section I’m going to explain.</p>
  6360. <figure class="article__image break-out">
  6361. <a href="">
  6362. <img
  6363. srcset=",q_auto/w_400/ 400w,
  6364.,q_auto/w_800/ 800w,
  6365.,q_auto/w_1200/ 1200w,
  6366.,q_auto/w_1600/ 1600w,
  6367.,q_auto/w_2000/ 2000w"
  6368. src=",q_auto/w_400/"
  6369. sizes="100vw"
  6370. alt="The Grid Editor contains tools for building a grid visually."
  6371. />
  6372. </a>
  6374. <figcaption class="op-vertical-bottom">
  6375. The Grid Editor contains tools for building a grid visually.
  6376. </figcaption>
  6377. </figure>
  6380. <p>Using CSS Grid Builder I added a container division. When selecting that in the work area, I get access to the Grid Editor. Activate that, and all the tools needed to visually build a grid are there:</p>
  6383. <ul>
  6384. <li>Add columns and rows</li>
  6385. <li>Align and justify content and items within each module</li>
  6386. <li>Size columns and rows using every type of unit including fr and minmax</li>
  6387. <li>Specify gaps</li>
  6388. <li>Name grid-template-areas</li>
  6389. <li>Specify breakpoints</li>
  6390. </ul>
  6392. <p>When I’m happy with those settings, "OK" the changes and they’re applied to the design in the work area. Back there, use sliders to preview the results at various breakpoints, and if you’re one of those people who’s worried about the shrinking percentage of people using incapable browsers, CSS Grid Builder also offers settings where you can figure fallbacks. Then just copy and paste CSS styles to somewhere else in your project or export the whole kit and caboodle.</p>
  6404. <figure class="article__image break-out">
  6405. <a href="">
  6406. <img
  6407. srcset=",q_auto/w_400/ 400w,
  6408.,q_auto/w_800/ 800w,
  6409.,q_auto/w_1200/ 1200w,
  6410.,q_auto/w_1600/ 1600w,
  6411.,q_auto/w_2000/ 2000w"
  6412. src=",q_auto/w_400/"
  6413. sizes="100vw"
  6414. alt="preview results at various breakpoints"
  6415. />
  6416. </a>
  6418. <figcaption class="op-vertical-bottom">
  6419. Preview results at various breakpoints, save the project to edit later or export the files.
  6420. </figcaption>
  6421. </figure>
  6424. <p><a href="">CSS Grid Builder</a> is currently <strong>free</strong> while CoffeeCup develops it and if you like what they’re doing, you can throw a few dollars their way to help fund its development.</p>
  6426. <h3>Cleaning Up</h3>
  6428. <p>I’m finding it hard to contain my excitement about CSS Grid. Yes, I know I should get out more, but I really do think that it offers us the best chance yet of learning lessons from other media to make the websites we create better at communicating what we aim to convey to our audiences. Whether we make websites for businesses who want to sell more, charities who need to raise more money through donations to good causes, or news outlets who want to tell stories more effectively, CSS Grid plus thoughtful, art directed content makes that all possible.</p>
  6430. <p>Now that’s <em>Hardboiled</em>.</p>
  6432. <p><em>I hope you enjoyed this article, now view the <a href="">project files on CodePen</a> or <a href="">download the example files</a>.</em></p>
  6434. <p><img style="float: right; padding: 1em;" src="" alt="Art Direction for the Web" /><em>‘Art Direction for the Web’ by Andy Clarke, the first Hardboiled Web Design ‘shot.’ Shots are a series of short books on ‘Art Directing for the web, ’ ‘Designing with a Browser,’ and ‘Selling Creative Ideas’ to be published throughout 2018.</em></p>
  6436. <div class="signature">
  6437.  <img src="" alt="Smashing Editorial">
  6438.  <span>(ms, ra, il)</span>
  6439. </div>
  6442. </div>
  6446.              </article>
  6447.            </body>
  6448.          </html>
  6449.        ]]></content:encoded>
  6450.      </item>
  6452.      <item>
  6455.          <author>Lukas van Driel</author>
  6457.        <title>Hit The Ground Running With Vue.js And Firestore</title>
  6458.        <link></link>
  6459.        <pubDate>Fri, 06 Apr 2018 13:30:33 +0200</pubDate>
  6460.        <guid></guid>
  6461.        <description>Google Firebase has a new data storage possibility called ‘Firestore’ (currently in beta stage) which builds on the success of the Firebase Realtime Database but adds some nifty features. In this article, we’ll set up the basics of a web app using Vue.js and Firestore.
  6462. Let&amp;rsquo;s say you have this great idea for a new product (e.g. the next Twitter, Facebook, or Instagram, because we can never have too much social, right?</description>
  6463.        <content:encoded><![CDATA[
  6464.          <html>
  6465.            <head>
  6466.              <meta charset="utf-8">
  6467.              <link rel="canonical" href="" />
  6468.              <title>Hit The Ground Running With Vue.js And Firestore</title>
  6469.            </head>
  6470.            <body>
  6471.              <article>
  6472.                <header>
  6473.                  <h1>Hit The Ground Running With Vue.js And Firestore</h1>
  6476.                    <address>Lukas van Driel</address>
  6478.                  <time datetime="2018-04-06T13:30:33&#43;02:00" class="op-published">2018-04-06T13:30:33+02:00</time>
  6479.                  <time datetime="2018-04-20T15:32:23&#43;00:00" class="op-modified">2018-04-20T15:32:23+00:00</time>
  6480.                </header>
  6483. <p>Google Firebase has a new data storage possibility called ‘Firestore’ (currently in beta stage) which builds on the success of the <em>Firebase Realtime Database</em> but adds some nifty features. In this article, we’ll set up the basics of a web app using Vue.js and Firestore.</p>
  6485. <p>Let&rsquo;s say you have this great idea for a new product (e.g. the next Twitter, Facebook, or Instagram, because we can never have too much social, right?). To start off, you want to make a prototype or <strong>M</strong>inimum <strong>V</strong>iable <strong>P</strong>roduct (MVP) of this product. The goal is to build the core of the app as fast as possible so you can show it to users and get feedback and analyze usage. The emphasis is heavily on development speed and quick iterating.</p>
  6487. <p>But before we start building, our amazing product needs a name. Let&rsquo;s call it “Amazeballs.” It’s going to be <em>legen</em> &mdash; wait for it &mdash; <em>dary</em>!</p>
  6489. <p>Here’s a shot of how I envision it:</p>
  6501. <figure >
  6502. <a href="">
  6503. <img
  6504. srcset=",q_auto/w_400/ 400w,
  6505.,q_auto/w_800/ 800w,
  6506.,q_auto/w_1200/ 1200w,
  6507.,q_auto/w_1600/ 1600w,
  6508.,q_auto/w_2000/ 2000w"
  6509. src=",q_auto/w_400/"
  6510. sizes="100vw"
  6511. alt="Screenshot of Amazeballs app"
  6512. />
  6513. </a>
  6515. <figcaption class="op-vertical-bottom">
  6516. The legendary Amazeballs app
  6517. </figcaption>
  6518. </figure>
  6521. <p>Our Amazeballs app is &mdash; of course &mdash; all about sharing cheesy tidbits of your personal life with friends, in so-called Balls. At the top is a form for posting Balls, below that are your friends’ Balls.</p>
  6523. <p>When building an MVP, you&rsquo;ll need tooling that gives you the power to quickly implement the key features as well as the flexibility to quickly add and change features later on. My choice falls on Vue.js as it&rsquo;s a Javascript-rendering framework, backed by the Firebase suite (by Google) and its new real-time database called Firestore.</p>
  6527.  <aside class="product-panel product-panel__tilted product-panel--book" data-audience="non-subscriber">
  6528.    <div class="container product-panel--book__container">
  6529.      <div class="panel__description panel__description--book">
  6530.    <p><em>“You must unlearn what you have learned!”</em> Meet the <strong>brand new episode</strong> of <a href="">SmashingConf San Francisco</a> with smart front-end tricks and UX techniques. Featuring Yiying Lu, Aarron Draplin, Smashing Yoda, and many others. Tickets now on sale. April <span class="small-caps">17-18</span>.</p>
  6531.      <a href="" class="btn btn--green btn--large">
  6532.        Check the speakers&nbsp;→
  6533.      </a>
  6534.      </div>
  6535.      <div class="panel__image panel__image--book">
  6536.        <a href="" class="books__book__image">
  6537.        <div class="books__book__img">
  6538.          <img src="" alt="SmashingConf San Francisco, with Yiying Lu, Josh Clark and many others." width="310" height="400">
  6539.        </div>
  6540.      </a>
  6541.      </div>
  6542.    </div>
  6543.  </aside>
  6549. <div class="c-garfield-the-cat">
  6552. <p>Firestore can directly be accessed using normal HTTP methods which makes it a full backend-as-a-service solution in which you don’t have to manage any of your own servers but still store data online.</p>
  6554. <p>Sounds powerful and daunting, but no sweat, I&rsquo;ll guide you through the steps of creating and hosting this new web app. Notice how big the scrollbar is on this page; there’s not