<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Weston Thayer’s Blog</title>
        <link>http://westonthayer.com/writing/</link>
        <description>Writing a few times a year about design, development, and everything in between</description>
        <lastBuildDate>Tue, 06 Apr 2021 20:25:42 GMT</lastBuildDate>
        <docs>http://blogs.law.harvard.edu/tech/rss</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Weston Thayer’s Blog</title>
            <url>http://westonthayer.com/assets/default-meta-img.jpg</url>
            <link>http://westonthayer.com/writing/</link>
        </image>
        <copyright>All rights reserved, 2019, Weston Thayer</copyright>
        <atom:link href="http://westonthayer.com/writing/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Intro to Font Metrics]]></title>
            <link>http://westonthayer.com/writing/intro-to-font-metrics/</link>
            <guid>http://westonthayer.com/writing/intro-to-font-metrics/</guid>
            <pubDate>Mon, 11 Feb 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Font files contain a wealth of information about a typeface. Whether you're a designer or a developer, learning more about how fonts work can open new doors in how you work and what you create.]]></description>
            <content:encoded><![CDATA[<p><em>Font files contain a wealth of information about a typeface. Whether you’re a designer or a developer, learning more about how fonts work can open new doors in how you work and what you create.</em></p>
<h2 id="what-are-font-metrics">What are font metrics?</h2>
<p>We’ll start with a font. A font is a digital representation of a typeface that consists of a series of glyphs (commonly called letters or characters). Computers read a font file in order to render glyphs on your screen as pixels. To describe how all those individual glyphs should be assembled together into words, sentences, and paragraphs, typeface designers encode the font with <em>metrics</em>.</p>
<p>Font metrics help the computer determine things like the default spacing between lines, how high or low sub and super scripts should go, and how to align two differently sized pieces of text next to each other.</p>
<p>Visualizing a font’s metrics, it looks a lot like guidelines in Sketch or Photoshop.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="font-metrics.png" alt="Screenshot of OpenType.js font inspector" >
        <figcaption class="post-figure__caption"><p>The metrics for lato.ttf, viewed with <a href="https://opentype.js.org/font-inspector.html">https://opentype.js.org/font-inspector.html</a>, then visualized.</p>
</figcaption>
</figure>

<p>Your computer is constantly using font metrics, but as a designer or developer, you probably don’t think about them in your day to day. Maybe this is the first time you’ve heard of font metrics.</p>
<p>Similarly, while design and development tools use font metrics under the hood, they don’t often expose them to their users. But they could—and it could change the way you design. To understand how, we first need to talk about the anatomy of type.</p>
<h2 id="a-look-inside-type">A look inside type</h2>
<p>There’s an anatomy behind the letters that makes up this sentence. As the example below shows, the curve of an “s” is called the spine—or the white space inside an “a” or “o” is the counter. Then there’s that imaginary line that all letters “sit” on (baseline), the tops of capital letters (cap height), and the tops of lowercase letters (x-height).</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="anatomy.png" alt="The word &#x27;Glossary&#x27; annotated with different anatomical features" >
        <figcaption class="post-figure__caption"><p>Anatomy of a typeface. Credit: <a href="https://www.fontshop.com/glossary">https://www.fontshop.com/glossary</a>.</p>
</figcaption>
</figure>

<p>When we practice typography by arranging type on a page or screen, we’re often leveraging different bits of anatomy to create readability and beauty. For example, the search suggestions in Google Maps contain both a place’s name and address.</p>
<p>To help you focus on the most important information (a place’s name), the typographer has set the address in a smaller type size and a lighter color. But to help with readability, both the place’s name and address share a <strong>baseline</strong>.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="baseline-google-maps.png" alt="Screenshot of Google Maps search dropdown, showing results for Dough Zone Dumpling House" >
</figure>

<p>The baseline is also helpful for creating vertical rhythm, which may make it <a href="https://www.smashingmagazine.com/2012/12/css-baseline-the-good-the-bad-and-the-ugly/">easier</a> for readers to jump from line to line, paragraph to paragraph, and section to section.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="baseline-vertical-rhythm.png" alt="Paragraphs with their baselines snapped to a repeating vertical grid" >
</figure>

<p>Another bit of frequently used anatomy is <strong>cap height</strong>, the top of capital letters. It often helps align your type with the top edge of pictures.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="cap-height-airbnb.png" alt="An Airbnb notification with a circular image on the left and the title on the right, its cap height aligned to the top of the image" >
        <figcaption class="post-figure__caption"><p>Notification from Airbnb.</p>
</figcaption>
</figure>

<p>Or baseline and cap height can be combined to create a playful container for smaller type.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="cap-height-helms-workshop.png" alt="A large title to the left of a smaller descriptive paragraph, where the paragraph fits within the vertical bounds of the title&#x27;s baseline and cap height" >
        <figcaption class="post-figure__caption"><p>Title / description from <a href="https://helmsworkshop.com/clients">https://helmsworkshop.com/clients</a>.</p>
</figcaption>
</figure>

<p>When we vertically center icons with type, we’re usually centering based on the cap height (if the first letter is uppercase) or the x-height (if the first letter is lowercase).</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="cap-height-google-contacts.png" alt="Screenshot of Google Contacts showing that next to each contact’s avatar, their name is vertically centered according to the first uppercase letter" >
</figure>

<p>Typographic anatomy plays a big part in our designs. Pieces of that anatomy are encoded in font metrics, which open the door for our tools to help in new ways.</p>
<h2 id="how-do-our-tools-use-font-metrics-today">How do our tools use font metrics today?</h2>
<p>Font metrics metadata is used by tools like Sketch to power features like <a href="https://www.sketchapp.com/docs/canvas/measuring/">smart guides</a>, which can help you snap the baseline to a layout grid.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="sketch-smart-guides.gif" alt="GIF showing a headline being snapped by baseline to a grid in Sketch" >
</figure>

<p>Similarly, CSS’s <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align">vertical-align</a> relies entirely on font metrics.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="css-vertical-align.gif" alt="GIF showing CSS vertical-align toggling from top to baseline to align two pieces of text" >
</figure>

<p>Unfortunately, most of the time, our tools obscure type’s anatomy behind the <strong>bounding box</strong>.</p>
<p>In Sketch, the bounding box is represented by selection handles. In CSS, you can see it by setting a <code>background-color</code>. All type positioning is in relation to the bounding box, so if you wanted 100px from the top of the screen to a paragraph, our tools yield 100px to the top of the box, not to the top of an “L” (cap height) or the bottom (baseline).</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="type-bounding-box.png" alt="Left, Sketch&#x27;s resize handles on a paragraph. Right, the same paragraph with CSS background-color: pink. Both are the same size" >
</figure>

<p>While our tools are generally pretty good at helping with baseline alignment, that’s not always true. Multi-column layouts in Sketch can be tricky. If two differently sized headlines are aligned to the bottom of the bounding box, the smaller inevitably looks too low. Care must be taken to create a layout grid for smart guides to snap to or they must be aligned by hand.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="sketch-align-bottom.gif" alt="GIF showing the effect of Sketch&#x27;s bottom alignment on a big headline and a small headline" >
</figure>

<p>Similarly, top aligning text to an icon doesn’t always work out either. On the left, Sketch’s align top tool. On the right, I aligned with the top of the “L” with the icon by hand. There isn’t any help from smart guides this time.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="sketch-align-top.png" alt="Left, a square icon next to a paragraph that has been aligned-top with Sketch. Right, the same icon and paragraph, but aligned by hand" >
</figure>

<p>Finally, vertically centering text to an icon is a pain. Using Sketch’s align tool, the text always looks too low. The same is true with CSS flexbox’s <code>align-items: center</code>.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="sketch-align-center.gif" alt="GIF showing the effect of Sketch&#x27;s center alignment on a square icon (left) and text (right)" >
</figure>

<p>This is because even though the space above and below the text’s bounding box is equal, the space above and below the “M” is not.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="sketch-align-center-annotated.png" alt="Left, the icon with text centered, annotated to show 13px above and below the text&#x27;s bounding box. Right, the icon with text centered, annotated to show 21px above the cap height and 19px below the baseline" >
        <figcaption class="post-figure__caption"><p>Depending on your font and font size, the alignment can often be off by much more than 1px.</p>
</figcaption>
</figure>

<p>In all of these examples, you could “eyeball” it, squinting your eyes or zooming in until things look <em>right</em>. Eyeballing comes with some notable downsides however:</p>
<ul>
<li><strong>Translation</strong> - eyeballing leads to a lot of seemingly random values for spacing/margins. Say, <code>margin: 27px 0 18px</code>. If you’re not building the designs yourself, it’s easy for a developer to make a mistake when copying values from Sketch. And if you work on a team with other designers, sticking to a spacing convention (like an <a href="https://builttoadapt.io/intro-to-the-8-point-grid-system-d2573cde8632">8pt grid</a>) becomes next to impossible.</li>
<li><strong>Maintenance</strong> - even if all the spacing values make it into code successfully, it’s easy to accidentally break them with future code changes.</li>
<li><strong>Flexibility</strong> - if the size, line height, or typeface ever changes, you have to carefully eyeball everything again.</li>
</ul>
<p>With today’s tools, font metrics are usually hidden behind the scenes. But they don’t have to be.</p>
<h2 id="how-could-our-tools-use-font-metrics">How could our tools use font metrics?</h2>
<p>Font metrics enable us to build smarter tools. They are the key to opening the bounding box, exposing the beautiful typographic anatomy inside.</p>
<p>For example, if Lato is the current font, Sketch can read <code>lato.ttf</code>’s font metrics, calculate the distance from the baseline to the cap height, then change the bounding box to snap to that new height. Vertically aligning center now works perfectly.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="sketch-bounding-box-fit.png" alt="A square icon (left) and text (right), annotated to show 20px above the cap height and 20px below the baseline. It looks perfectly centered to the icon" >
</figure>

<p>Once your intent of centering based on cap height is communicated, tools can preserve it. If the icon needs to increase in size or the text decreases in size (like if your users have adjusted the CSS <a href="https://support.mozilla.org/en-US/kb/font-size-and-zoom-increase-size-of-web-pages#w_how-to-only-change-the-size-of-the-text">base font size</a> in their browser), nothing breaks.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="metrics-dynamic-align-center.gif" alt="GIF showing vertical centering being perfectly preserved while the text and icon both change size" >
</figure>

<p>The same benefit applies if the font changes (maybe your web font failed to load, or you’re using a <a href="https://css-tricks.com/snippets/css/system-font-stack/">system fonts strategy</a>).</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="metrics-system-font-align-center.gif" alt="GIF showing vertical centering being perfectly preserved while the text&#x27;s font changes" >
</figure>

<p>Writing code becomes easier too—no more <code>align-self: flex-start; margin-top: 13px;</code> to perfectly center the text. If CSS exposed font metrics via a property, like <a href="https://github.com/w3c/csswg-drafts/issues/3240">leading-trim</a>, flexbox could take care of everything for you.</p>
<pre class="hljs"><code class="lang-css"><span class="hljs-selector-class">.icon-label</span> {
    <span class="hljs-comment">/*
    trim off the bits of the bounding box
    above the cap height and below the
    ideographic baseline
    */</span>
    <span class="hljs-attribute">leading-trim</span>: cap ideographic;
    <span class="hljs-comment">/*
    then center using the trimmed height
    */</span>
    <span class="hljs-attribute">align-self</span>: center;
}</code></pre><p>Our tools could also use font metrics to look at x-height and suggest a <a href="https://blog.prototypr.io/to-choose-the-right-typeface-look-at-its-x-height-instead-d5ef0967d09c">readable typeface for body text</a>, quickly find a suitable fallback font to <a href="https://helenvholmes.com/writing/type-is-your-right">avoid FOUC</a>, or in some distant future <a href="https://jon.gold/2016/05/robot-design-school/">algorithmically suggesting typeface pairings</a>.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="font-style-matcher-demo.gif" alt="GIF showing the Font Style Matcher tool manually matching Georgia to Merriweather" >
        <figcaption class="post-figure__caption"><p>Using <a href="https://twitter.com/notwaldorf">Monica Dinculescu</a>’s fantastic <a href="https://meowni.ca/font-style-matcher/">Font Style Matcher</a> to avoid FOUC. Could font metrics take out some of the guesswork?</p>
</figcaption>
</figure>

<h2 id="conclusion">Conclusion</h2>
<p>Good typography is hard, but it can be easier with good tools. Embracing the raw anatomical features of type could enable us to create designs that are precise, resilient, readable, and maybe even original.</p>
<p>But it can be hard to get excited over Sketch features that don’t exist and CSS properties that aren’t implemented. Luckily, we can build some of this ourselves! In the next article, I’ll explore how exactly to extract and read the font metrics for your fonts. Once you have the raw data, I’ll explain the math behind using them in layout, and how they can be useful in today’s in HTML and CSS.</p>
<h2 id="further-reading">Further reading</h2>
<p>Font metrics are a low-level implementation detail, but they’re far from boring. If you’re interesting in learning more, check out some of these fantastic resources. And if <code>leading-trim</code> sounds like a compelling CSS feature, check out <a href="https://github.com/w3c/csswg-drafts/issues/3240">CSSWG #3240</a>.</p>
<ul>
<li><a href="http://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align">Deep dive CSS: font metrics, line-height and vertical-align</a> by Vincent De Oliveira</li>
<li><a href="https://journal.yummygum.com/get-down-to-the-nitty-gritty-of-text-rendering-in-sketch-cd49f0544e20">Get Down to the Nitty-Gritty of Text Rendering in Sketch</a> by Yakim van Zuijlen</li>
<li><a href="https://indesignsecrets.com/understanding-the-first-baseline-position-of-text.php">Understanding the First Baseline Position of Text</a> by Mike Rankin<ul>
<li>It’s worth noting how our design tools of old (InDesign, Illustrator) expose richer font metrics control than today’s modern tools</li>
</ul>
</li>
</ul>
]]></content:encoded>
            <enclosure url="http://westonthayer.com/writing/intro-to-font-metrics/font-metrics.png">
            </enclosure>
        </item>
        <item>
            <title><![CDATA[How to use VoiceOver in 6 Tips]]></title>
            <link>http://westonthayer.com/writing/how-to-use-voiceover/</link>
            <guid>http://westonthayer.com/writing/how-to-use-voiceover/</guid>
            <pubDate>Thu, 21 Sep 2017 00:00:00 GMT</pubDate>
            <description><![CDATA[Designing for screen readers is essential for a pleasant user experience with low vision users.]]></description>
            <content:encoded><![CDATA[<p><a href="https://www.apple.com/accessibility/mac/vision/">VoiceOver</a> is a screen reader that comes bundled free with OSX. Designing for screen readers is essential for a pleasant user experience with low vision users, and also has the added benefit of <a href="https://moz.com/blog/accessibility-seo-1">helping with SEO</a>. But in order to design for screen readers, it helps to understand how they work.</p>
<p>Here are 6 quick tips to get you started with VoiceOver and Safari.</p>
<h2 id="1-turn-it-on">1. Turn it on</h2>
<p>Head to System Preferences &gt; Accessibility &gt; VoiceOver and check the box. A dialog will show offering an optional tutorial (took me about 20 minutes), but you don’t need that, you have this guide! Click <strong>Use VoiceOver</strong>.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="turn-on-voiceover.gif" alt="GIF showing how to turn on VoiceOver in System Preferences" >
</figure>

<p>As soon as VoiceOver is on, your computer will start talking to you. You’ll also see a floating black bubble containing closed captions with a written version of the VoiceOver text, as well as a black rectangle indicating what UI elements have been focused on.</p>
<p>You can still use your mouse when VoiceOver is on, which is a helpful crutch while you’re still learning the keyboard shortcuts.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="using-voiceover-with-mouse.gif" alt="GIF showing how the mouse cursor can still be used" >
</figure>

<h2 id="2-be-an-explorer">2. Be an explorer</h2>
<p>While you <em>can</em> use your mouse, VoiceOver was designed to be used with your keyboard. You may have used familiar keyboard shortcuts like <code>TAB</code> and <code>SHIFT + TAB</code> to navigate in the past, but some types of UI aren’t tab-able.</p>
<p>To solve this, VoiceOver introduces new keyboard shortcuts. All of these shortcuts ask you to start by holding down <code>CTRL + OPTION</code> (referred to in the documentation as <code>VO</code> for Voice Over).</p>
<p>Start by trying <code>CTRL + OPTION + →</code>.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="voiceover-keyboard-navigation.gif" alt="GIF of System Preferences being navigated using the VO keys" >
</figure>

<p>Try all the arrow keys! Notice how VoiceOver sometimes has tips for interacting with certain UI.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="voiceover-tip.png" alt="Black tooltip showing instructions for using the checkbox with the keyboard" >
</figure>

<h2 id="3-silence">3. Silence!</h2>
<p>As you navigate, all the talking can be repetitive if you aren’t used to it. Simply tap <code>CTRL</code> to instantly stop VoiceOver from reading. If you have music playing, OSX will smoothly lower the volume when VoiceOver is speaking, then ramp it back up when VoiceOver is done.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="https://media1.giphy.com/media/4oMoIbIQrvCjm/giphy.gif" alt="GIF of Bart from the Simpsons jamming out to music" >
</figure>

<h2 id="4-stepping-in-and-out">4. Stepping in and out</h2>
<p>For certain pieces of UI, VoiceOver will focus on the <em>container</em>. To access the UI within the container, use <code>SHIFT + CTRL + OPTION + ↓</code>.</p>
<p>Try it out by switching to Safari, entering a URL in the address bar, and using the shortcut to start navigating.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="voiceover-safari-step-in.gif" alt="GIF of stepping into Safari&#x27;s web container" >
</figure>

<p>Similarly, to get out of the container use the up arrow.</p>
<h2 id="5-click-click-click">5. Click click click</h2>
<p>Previously, I’ve used <code>ENTER</code> as the keyboard equivalent of clicking with the mouse, but a much more reliable option with VoiceOver is <code>CTRL + OPTION + SPACE</code>, which will do exactly what a click would.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="voiceover-click.gif" alt="GIF of opening a dropdown via VO click" >
</figure>

<h2 id="6-navigating">6. Navigating</h2>
<p>Play around with exploring via the arrow keys for long enough and you’ll soon become tired. There’s so much UI! Do we really have to <code>CTRL + OPTION + →</code> hundreds of times to get to the bottom of the page?</p>
<p>Luckily, no. VoiceOver has a cool feature called Rotor that lets you jump between things like sections, headings, links, and more. Activate it while on a webpage with <code>CTRL + OPTION + U</code>.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="voiceover-rotor.gif" alt="GIF of VoiceOver&#x27;s Rotor feature" >
</figure>

<p>That’s all for now. Go ahead and give VoiceOver a try, maybe even try it out on that swanky-new-feature you’ve been working on. Some things to watch out for:</p>
<ul>
<li>Does VoiceOver announce that your clickable areas are clickable?</li>
<li>Do your headings show up in Rotor?</li>
<li>Do images have a description?</li>
<li>Is copy in all caps read as an <a href="https://stackoverflow.com/questions/28549307/apple-voiceover-reading-words-as-acronyms-can-this-be-controlled">acronym</a>?</li>
</ul>
<blockquote>
<p><strong>Bonus tip</strong>: for those of us with touchpads, it is possible to lose your mouse if you accidentally are holding down <code>CTRL + OPTION</code> and rotate 2 fingers clockwise (my palm did this once). To fix it, simply hold down the keys and rotate 2 fingers counter-clockwise.</p>
</blockquote>
]]></content:encoded>
            <enclosure url="http://westonthayer.com/writing/how-to-use-voiceover/voiceover-tip.png">
            </enclosure>
        </item>
        <item>
            <title><![CDATA[Layout Experiments in Adobe Illustrator]]></title>
            <link>http://westonthayer.com/writing/2016/07/27/layout-experiments-in-adobe-illustrator/</link>
            <guid>http://westonthayer.com/writing/2016/07/27/layout-experiments-in-adobe-illustrator/</guid>
            <pubDate>Wed, 27 Jul 2016 00:00:00 GMT</pubDate>
            <description><![CDATA[As designers, we need tools that expose us to layout, that let us test and explore layout variations, and most importantly make the best decisions.]]></description>
            <content:encoded><![CDATA[<p>As designers, we need <a href="https://medium.com/bridge-collection/modern-design-tools-adaptive-layouts-e236070856e3#.7ky86uult">tools that expose us to layout</a>, that let us test and explore layout variations, and most importantly make the best decisions. Today, tools like <a href="http://www.antetype.com/">Antetype</a>, <a href="https://www.figma.com/">Figma</a>, <a href="http://www.adobe.com/products/experience-design.html">Adobe XD</a>, and <a href="https://vimeo.com/169816724">Affinity Designer</a> are leading the way with innovative layout features that can save us from tedious tasks like updating the <a href="https://www.youtube.com/watch?v=42VCB42TKp4">same margin 20 times</a> or the pain of scaling one design to different device sizes.</p>
<p>Unfortunately, these tools are mostly unavailable on Windows. My teammates at Microsoft largely prefer to work in Adobe Illustrator because it’s cross-platform. Not wanting to be left out, I started researching potential solutions. I ended up creating an Illustrator extension called <a href="https://github.com/WestonThayer/Bloks"><strong>Bloks</strong></a> which takes a new approach to layout.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="1.gif" alt="shapes that stick together" >
        <figcaption class="post-figure__caption"><p>Shapes that stick together.</p>
</figcaption>
</figure>

<p>Bloks uses <a href="http://www.michaellucassmith.com/20080525%20User%20Interface%20Layout.html">stack-based layout</a>. When art is placed in a BlokGroup with an orientation (vertical or horizontal), the BlokGroup keeps them stacked in that direction, edge to edge, no matter what you do.</p>
<p>Basic, but combined with a few extra features you can create just about any layout. Perhaps the most powerful feature is the ability to place <a href="https://helpx.adobe.com/illustrator/using/symbols.html">symbols</a> in BlokGroups. Resize a symbol once and all the BlokGroups it’s used in move to make room for it.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="2.gif" alt="updating symbols" >
        <figcaption class="post-figure__caption"><p>0% opacity symbols form the spacing between each list item. An update to the root symbol cascades to every BlokGroup its used in. The result is that the height of a single symbol controls the list’s density.</p>
</figcaption>
</figure>

<p>Access to such a primitive layout mechanism has the benefit of allowing designs that other tools do not.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="3.gif" alt="multi-height list items" >
        <figcaption class="post-figure__caption"><p>You can easily stack variable-height items. Tools like Adobe XD’s <a href="https://www.youtube.com/watch?v=42VCB42TKp4">Repeat Grid</a> require each item to be the same height.</p>
</figcaption>
</figure>

<p>You can also give objects <strong>flexibility</strong>, which allows them to fluidly resize.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="4.gif" alt="fluid layouts" >
        <figcaption class="post-figure__caption"><p>The flexibility property applies to children of a BlokGroup. It can be hard to understand at first. Experiment with values of 1 and 2 to get a feel for how it works.</p>
</figcaption>
</figure>

<p>These features come together to enable powerfully complex layouts, all within Illustrator.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="5.gif" alt="responsive design" >
        <figcaption class="post-figure__caption"><p>The same design can quickly be fit to different sized artboards. Strings expand to fit their new containers.</p>
</figcaption>
</figure>

<p>I’ve been able to try Bloks out with several designers for a few months. It turns out that stack-based layout is extremely easy to learn, easier than the <a href="https://vimeo.com/146967392">constraints</a> Figma uses or the <a href="http://www.antetype.com/tutorial1.html">box model</a> used by Antetype.</p>
<p>Stack-based layout is also extremely powerful. However, certain scenarios (like pinning an object 12px from the artboard’s right edge) are not intuitive (constraints make more sense in that case). Using symbols within stack-based layout is a huge time saver. You can change 20 margins in a few clicks. It would be even better with support for dynamic symbols (similar to <a href="https://www.sketchapp.com/learn/documentation/07-symbols/2-editing-symbols.html">symbol overrides in Sketch</a>) as entire components could be turned into symbols.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I’m convinced that layout is a growing pillar of design, alongside giants like typography, color, and motion. As our industry’s tools evolve, I hope they add options for stack-based layout, maybe in conjunction with constraints so that everyone can explore this space.</p>
<p>You can <a href="https://github.com/WestonThayer/Bloks#installation"><strong>try Bloks</strong></a> if you have Illustrator. Let me know if you have a problem by creating a new <a href="https://github.com/WestonThayer/Bloks/issues">issue</a>. Share your experience, frustration, or delight with me in the comments or <a href="https://twitter.com/WestonThayer5">on Twitter</a>.</p>
<p>Under the hood, it’s all powered by <a href="https://github.com/facebook/css-layout">flexbox</a> (thanks for the <a href="https://medium.com/facebook-design/exploring-dynamic-layout-in-sketch-fdf0e825d1cf#.2jcauvrh3">tip Matej</a>) and lot of long nights.</p>
]]></content:encoded>
            <enclosure url="http://westonthayer.com/writing/2016/07/27/layout-experiments-in-adobe-illustrator/1.gif">
            </enclosure>
        </item>
        <item>
            <title><![CDATA[A Response to Analysis Paralysis]]></title>
            <link>http://westonthayer.com/writing/2016/02/12/a-response-to-analysis-paralysis/</link>
            <guid>http://westonthayer.com/writing/2016/02/12/a-response-to-analysis-paralysis/</guid>
            <pubDate>Fri, 12 Feb 2016 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>The *<a href="https://medium.com/@pistacchio/i-m-a-web-developer-and-i-ve-been-stuck-with-the-simplest-app-for-the-last-10-days-fb5c50917df#.embpeepov">I’m a web developer and I’ve been stuck with the simplest app for the last 10 days</a>* Medium post gained a lot of attention on HN and <a href="https://www.reddit.com/r/programming/comments/458udn/im_a_web_developer_and_ive_been_stuck_with_the/">/r/programming</a> yesterday. The article is in no way unwarrented or off-base, I can sympathize. However, I want to address the two reoccuring themes from the comments:</p>
<ul>
<li>“Well you should try <strong>X</strong> framework!”</li>
<li>“Bah, all these libraries are to save you 20 keystrokes. Just use raw JS!”</li>
</ul>
<p>While neither of those comments are completely disagreeable, they forget the big picture. Using raw JS may end your paralysis, but is it <em>always</em> the best choice?</p>
<p>Most sucessful frameworks and tools exist and prosper not because they saved you keystrokes or they just wanted to do something different for the hell of it. They exist because the vanilla technologies used for webdev (HTML/CSS/JS) make it hard to follow some very important principals:</p>
<ol>
<li><a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a></li>
<li><a href="http://c2.com/cgi/wiki?GlobalVariablesAreBad">Avoid globals</a></li>
<li><a href="http://stackoverflow.com/questions/18300953/why-encapsulation-is-an-important-feature-of-oop-languages">Encapsulate</a></li>
</ol>
<p><a href="http://stackoverflow.com/questions/7696955/how-to-create-dry-html">HTML</a> and <a href="http://alistapart.com/article/why-sass">CSS</a> sometimes can’t accomplish being DRY. <a href="https://medium.com/seek-ui-engineering/the-end-of-global-css-90d2a4a06284#.igsnzzjbz">CSS</a> and <a href="http://requirejs.org/docs/why.html">JS</a> are both bad at avoiding globals. CSS is <a href="https://github.com/Wolfr/css-encapsulation-today">particularly horrid</a> at encapsulation.</p>
<p>Ignoring these principals is fool hearted. They’re hard learned lessons from decades of programming experience. For example, encapsulation eliminates an <em>entire class of bugs</em>! Those bugs will bite you regardless of your project’s size, and they’ll only become more aggressive as it grows.</p>
<p>Successful frameworks and tools often got there by making it easier to follow your principals. To name a few: Sass and Handlebars keep it DRY, Webpack and Browserify keep it non-global, React and Web Components help encapsulate.</p>
<p>To conclude, I encourage you to make an honest list of the principals that <em>you</em> value. Ask yourself how important each is and what’s the easiest way to adhere? Sometimes the easiest answer might be to use a tool. Other times, it might just be to learn how prototypical inheritance works in Javascript. The important thing is to put your principals first, tools second.</p>
<blockquote>
<p>Great minds discuss principals. Average minds discuss technologies. Small minds discuss tools. – <a href="http://bradfrost.com/blog/post/i-have-no-idea-what-the-hell-i-am-doing/">Brad Frost</a></p>
</blockquote>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hosting Framer Prototypes on Azure]]></title>
            <link>http://westonthayer.com/writing/2015/10/23/hosting-framer-on-azure/</link>
            <guid>http://westonthayer.com/writing/2015/10/23/hosting-framer-on-azure/</guid>
            <pubDate>Fri, 23 Oct 2015 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>While Framer Studio makes it <a href="http://framerjs.tumblr.com/post/108550864712/sharing-projects">extremely easy</a> to get a sharable link to your prototype, your company might not be too happy to find their work on a public (although obscure) URL. Here’s how you can use Azure to lock things down.</p>
<ol>
<li>Create an Azure <a href="https://azure.microsoft.com/en-us/services/app-service/web/">Web App</a>. It’s free, but you have to hand over your credit card number</li>
<li>Follow the <a href="https://github.com/WestonThayer/FramerAzureBoilerplate#usage">FramerAzureBoilerplate instructions</a> to enable simple username/password authentication, as shown below:</li>
</ol>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="login.png" alt="Logging in" >
</figure>

<p>Of course there are obvious security issues with sharing the username and password to everyone you want to share the prototype with, so keep that in mind. It’s also possible that your company has an internal Azure instance, which is even more secure.</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Framer on Windows with framer-cli]]></title>
            <link>http://westonthayer.com/writing/2015/10/09/framer-on-windows-with-framer-cli/</link>
            <guid>http://westonthayer.com/writing/2015/10/09/framer-on-windows-with-framer-cli/</guid>
            <pubDate>Fri, 09 Oct 2015 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p><a href="https://github.com/koenbok/Framer">Framer</a>, the fantastically fast JavaScript prototyping library, is primarily used through <a href="http://framerjs.com/">Framer Studio</a>, a paid (but well worth it) IDE for OSX. While it’s been possible to use Framer on Windows for quite a while (it is just JavaScript after all), that required a lot of <a href="http://www.prototypingwithframer.com/framer-on-windows-with-atom/">setup</a> (If you do follow this article, beware that the Getting Started link is out of date). I recently discovered a much easier way, courtesy of Pete Schaffner’s <a href="https://github.com/peteschaffner/framer-cli">framer-cli</a>.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="workspace.png" alt="My workspace" >
</figure>

<ol>
<li><a href="https://nodejs.org/">Download Node.js</a> and install</li>
<li>From Start, open the <strong>Node.js command prompt</strong> and enter <code>npm install -g framer-cli</code></li>
<li><code>cd C:\Users\yourname\Desktop\</code>, or to some other folder</li>
<li><code>framer new MyProto.framer</code></li>
<li><code>framer preview MyProto.framer</code></li>
</ol>
<p>If you now take your browser to <code>http://localhost:3000/</code>, you’ll see your work! To make changes:</p>
<ol>
<li>Navigate to <code>C:\Users\yourname\Desktop\MyProto.framer\</code></li>
<li>Rename <code>index.js</code> to <code>index.coffee</code></li>
<li>Open <code>index.coffee</code> and make changes</li>
</ol>
<p>If you make edits while <code>framer preview</code> is still running, you’ll see your browser automatically perform a live refresh whenever you save. Step 2 is optional (<a href="https://github.com/peteschaffner/framer-cli/issues/16">working on it</a>), you could write in JavaScript if you wanted. That’s the basics, but here are a few more tips:</p>
<ul>
<li>Emulate Framer Studio’s <strong>Mirror</strong> feature by typing <code>ipconfig</code> in the command prompt. You should see an <code>IPV4 Address</code> line with a set of four digits separated by periods. For example: <code>192.168.0.214</code>. This is your IP address. If you have a device or phone on the same local network, type that number, plus :3000 into your browser. For example <code>192.168.0.214:3000</code>. Now you can test your work on a phone or tablet. We’re working <a href="https://github.com/peteschaffner/framer-cli/issues/14">to make this easier</a>.</li>
<li>You can change the mouse cursor to a touch point by integrating this outstanding <a href="https://github.com/peteschaffner/framer-cli/pull/12">pull request</a>.</li>
<li>If you’re including code from a Framer Studio project and it doesn’t immediately work, you may want to integrate <a href="https://github.com/peteschaffner/framer-cli/pull/13">this pull request</a>.</li>
<li>If the preview isn’t showing anymore, check the command window where you ran <code>framer preview</code>. Compilation errors are displayed here.</li>
</ul>
<p>The two major features that I miss most from Framer Studio are PSD and Sketch import as well as the editor’s intelligent autocomplete. You can play around with plugins for editors like Sublime Text to get better autocompletion (framer-cli is working on support for <a href="http://ternjs.net/">Tern</a>), but it still won’t be great. And of course designs can be manually imported, but that’s fairly painful.</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My Performance Pitfall]]></title>
            <link>http://westonthayer.com/writing/2015/04/20/my-performance-pitfall/</link>
            <guid>http://westonthayer.com/writing/2015/04/20/my-performance-pitfall/</guid>
            <pubDate>Mon, 20 Apr 2015 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>The landscape of software performance, especially for UI, is complex, mysterious, and poorly understood by many. This is the story of a dark hole that I found myself in.</p>
<blockquote>
<p>Today, the developer created a list UI component.</p>
</blockquote>
<p>She sought to consolidate and unify lists in her many apps, while removing duplicate code. Her users would rejoice at the level of polish and consistency she’d achieved.</p>
<p>Being a responsible developer, she wants to ensure that lists display just as fast as ever. Unfortunately, she only has high-end devices to test on. Everything <em>seems</em> to be fine with her changes. But, she suspects that may not be the case on low-end devices. So she writes some code to measure how long it takes for the list to render and runs some tests, effectively <a href="https://en.wikipedia.org/wiki/Benchmark_%28computing%29">benchmarking</a>. Here are some of her results:</p>
<table>
<thead>
<tr>
<th>Test Run</th>
<th>Pre-Change</th>
<th>Post-Change</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>80ms</td>
<td>94ms</td>
</tr>
<tr>
<td>2</td>
<td>74ms</td>
<td>81ms</td>
</tr>
<tr>
<td>3</td>
<td>81ms</td>
<td>79ms</td>
</tr>
</tbody></table>
<p>Unfortunately, it appears that on average, she made things a bit slower. Sure, it’s only a few ms, but what will a few ms become on a low-end device? Worse still, the 94ms result appears to be an outlier. Hmm. Maybe another process got some extra CPU time on that run. As she runs more tests, the level of variance is frustrating. ±10ms, sometimes worse!</p>
<p>Discouraged, she thought for a bit and came up with an idea. What if she wrote a stress test? Perhaps it tries to render 1,000 list items instead of the usual 40-50. That should take whole <strong>seconds</strong> to run and the mere ±10ms variance will be insignificant. Here’s her next round of results:</p>
<table>
<thead>
<tr>
<th>Test Run</th>
<th>Pre-Change</th>
<th>Post-Change</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>1.92s</td>
<td>2.22s</td>
</tr>
<tr>
<td>2</td>
<td>1.88s</td>
<td>2.10s</td>
</tr>
<tr>
<td>3</td>
<td>1.72s</td>
<td>2.15s</td>
</tr>
</tbody></table>
<p>Oh dear. Not only did that attempt fail to clamp down on the variance, her changes seem to have made things even worse!</p>
<blockquote>
<p>This is a dismal hole.</p>
</blockquote>
<p>You can stay in it. Run more tests. Sometimes the variance will be less and you’ll think you have concrete results. But you’ll run more tests the next day and things are thrown back into chaos. To get yourself out, you must learn three things:</p>
<ul>
<li>Test real-world scenarios</li>
<li>Test on slow, cheap devices</li>
<li>Use a <a href="https://en.wikipedia.org/wiki/Profiling_%28computer_programming%29">performance analyzer</a></li>
</ul>
<h2 id="test-real-world-scenarios">Test real-world scenarios</h2>
<p>Measuring performance is frustrating because each time you measure, you might get a different result. This is at odds with the repeatable nature of computing. While it’s tempting to write a stress test to minimize variance, unless you need to perform at the scale you’re testing there’s simply no value in optimizing for it. Test real-world scenarios.</p>
<h2 id="test-on-slow-cheap-devices">Test on slow, cheap devices</h2>
<p>This one sucks, because you have to buy something. Good thing it’s cheap, right? Alternatively, there are more than a <a href="http://developer.samsung.com/remotetestlab/rtlDeviceList.action">few</a> <a href="http://aws.amazon.com/device-farm/">services</a> out there that let you virtually “rent” a device for testing. While it’s tempting to try and slow your machine down or use an emulator, use a real device that you want to support.</p>
<h2 id="use-a-performance-analyzer">Use a performance analyzer</h2>
<p>These tools are often hard to use and come with a steep learning curve, but trust me they’re worth it. Instead of guessing at which part of your code is at fault, it will <em>tell</em> you. Even better, it stops you from measuring time from your app code, which may result in <a href="https://en.wikipedia.org/wiki/Heisenbug">Heisenbugs</a>.</p>
<p><em>Having absorbed these learnings, the developer was enlightened. After testing on a low-end device, she found that there wasn’t even a performance issue! Equipped with this newfound wisdom, she set out to prevent others from the same fate.</em></p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Bootstrap Theme for Doxygen]]></title>
            <link>http://westonthayer.com/writing/2014/11/27/bootstrap-theme-for-doxygen/</link>
            <guid>http://westonthayer.com/writing/2014/11/27/bootstrap-theme-for-doxygen/</guid>
            <pubDate>Thu, 27 Nov 2014 00:00:00 GMT</pubDate>
            <description><![CDATA[A practical guide to High Contrast mode in Windows.]]></description>
            <content:encoded><![CDATA[<p>At work, I started a C++/Cx repository in <a href="http://www.visualstudio.com/en-us/products/what-is-visual-studio-online-vs.aspx">Visual Studio Online</a>. I needed an easy way for consumers to read about the public APIs.</p>
<p><a href="http://www.stack.nl/~dimitri/doxygen/">Doxygen</a> turns out to be the de facto solution for this. It was super easy to hook up, I could document both in code and in separate files and I could document in markdown! I’ve found markdown to be the absolutely quickest way to write well structured comments. C# style Document XML is great, but not if you have to type it by hand. I might be swayed back to DocXML if <a href="http://stackoverflow.com/questions/3371205/c-intellisense-with-descriptions">Intellisense supported it for C++</a> and I could get a good comment generator going.</p>
<p>In any case, the website Doxygen creates is wonderful, but ugly:</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="before.png" alt="Screenshot before" >
</figure>

<p>Luckily I found <a href="https://github.com/Velron/doxygen-bootstrapped">doxygen-bootstrapped</a> which applies the goodness of <a href="http://getbootstrap.com/">Bootstrap</a>. The original repo was a bit sparse on documentation, but I managed to figure things out and contributed an <a href="https://github.com/Velron/doxygen-bootstrapped/tree/master/example-site">example site</a> to get your project up and going quickly.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="after.png" alt="Screenshot after" >
</figure>

<p>Very pleased with the result. It’s even fairly responsive to screen width changes!</p>
<h2 id="side-note">Side note</h2>
<p>For anybody else needing to document C++ projects, you might have noticed that VS has a compiler option to generate DocXML. You could plug the XML output into <a href="http://shfb.codeplex.com/">Sandcastle</a> and get a very nice looking site. The problem is that the DocXML compiler for C++ treats links in comments like code. What you’re linking to <em>must be forward declared!</em> This is incredibly impractical for comments where you want to link between different classes in your code base. Doxygen does not have this restriction.</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[High Contrast in XAML]]></title>
            <link>http://westonthayer.com/writing/2014/11/21/high-contrast-in-xaml/</link>
            <guid>http://westonthayer.com/writing/2014/11/21/high-contrast-in-xaml/</guid>
            <pubDate>Fri, 21 Nov 2014 00:00:00 GMT</pubDate>
            <description><![CDATA[A practical guide to High Contrast mode in Windows.]]></description>
            <content:encoded><![CDATA[<p><em>Update: I contributed to the <a href="https://msdn.microsoft.com/windows/uwp/accessibility/high-contrast-themes">official MSDN documentation</a>. It contains everything in this post and more, so go there instead.</em></p>
<p>High contrast is a source of confusion for many. This is a practical guide that extends the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh868165.aspx">MSDN guidance</a> and <a href="https://code.msdn.microsoft.com/windowsapps/XAML-high-contrast-style-c0ce936f/sourcecode?fileId=63896&amp;pathId=354124371">sample</a> for developers who would rather not think about it.</p>
<h2 id="when-do-i-need-to-think-about-it">When do I need to think about it?</h2>
<p>As soon as you need to apply color to any UI (change it from its system default) or need to add images as decoration (ex: image background).</p>
<h2 id="what-do-i-need-to-do">What do I need to do?</h2>
<p>Start by creating the proper plumbing, if it doesn’t already exist.</p>
<ul>
<li>In App.xaml, create a <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.resourcedictionary.themedictionaries.aspx">ThemeDictionaries</a> collection<ul>
<li>Note that App.xaml may not be the most <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh994641.aspx">performant choice</a></li>
<li><code>HighContrast</code> is not the only available key name. There’s also <code>HighContrastBlack</code>, <code>HighContrastWhite</code>, and <code>HighContrastCustom</code><ul>
<li>In almost all cases, <code>HighContrast</code> is all you need. Forget about the others - read on to see why</li>
</ul>
</li>
</ul>
</li>
<li>In <code>Default</code>, create the type of <a href="http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.media.brush.aspx">Brush</a> you need (usually a SolidColorBrush). Give it a Key name specific to what it’s being used for:<ul>
<li><code>&lt;SolidColorBrush x:Key=&quot;BrandedPageBackground&quot; /&gt;</code></li>
</ul>
</li>
<li>Assign the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.color.aspx">Color</a> you want for it<ul>
<li><code>&lt;SolidColorBrush x:Key=&quot;BrandedPageBackground&quot; Color=&quot;Red&quot; /&gt;</code></li>
</ul>
</li>
<li>Copy that Brush into <code>HighContrast</code></li>
<li>Determine what color your Brush should be in <code>HighContrast</code></li>
</ul>
<pre class="hljs"><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Application.Resources</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary.ThemeDictionaries</span>&gt;</span>
            <span class="hljs-comment">&lt;!-- Default is a fallback if a more precise theme isn't called out below --&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"Default"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">SolidColorBrush</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"BrandedPageBackground"</span> <span class="hljs-attr">Color</span>=<span class="hljs-string">"Red"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary</span>&gt;</span>
            <span class="hljs-comment">&lt;!-- HighContrast is used in any high contrast theme --&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"HighContrast"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">SolidColorBrush</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"BrandedPageBackground"</span> <span class="hljs-attr">Color</span>=<span class="hljs-string">"Red"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary.ThemeDictionaries</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Application.Resources</span>&gt;</span></code></pre><h2 id="high-contrast-colors">High Contrast Colors</h2>
<p>Determining a color for high contrast requires a bit of learning. If you don’t have time, stop now. The plumbing you’ve created above will make this a simple bug to fix later.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="controlpanel1.png" alt="Windows 8.1 Control Panel for High Contrast" >
</figure>

<p>The user can switch to high contrast using the above settings page. They have 4 high contrast themes by default. Once they select an option, the page shows a preview of how apps will likely look. Every square on the preview can be clicked to change its value. Every square <em>also</em> directly maps to a <a href="http://msdn.microsoft.com/en-us/library/windows/apps/dn518235.aspx#SystemColor_Color_resources">XAML system resource</a>.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="controlpanel-mapping.png" alt="High Contrast Mapping" >
</figure>

<p>Prefix the names called out above with <em>SystemColor</em> and postfix them with <em>Color</em> (ex: <code>SystemColorWindowTextColor</code>). These will <strong>dynamically update to match what the user specified</strong>! The documentation for this is poor, but we can learn a bit from how they worked in the <a href="http://blogs.msdn.com/b/wpf/archive/2010/11/30/systemcolors-reference.aspx">WPF days</a>.</p>
<p>This frees you from having to pick a specific color for high contrast. Instead, pick a system resource that corresponds to what the color is being used for. In the above example, we named our SolidColorBrush <code>BrandedPageBackground</code>. Since this will be used for a background, we can map this to the <code>SystemColorWindowColor</code> in high contrast:</p>
<pre class="hljs"><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Application.Resources</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary.ThemeDictionaries</span>&gt;</span>
            <span class="hljs-comment">&lt;!-- Default is a fallback if a more precise theme isn't called out below --&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"Default"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">SolidColorBrush</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"BrandedPageBackground"</span> <span class="hljs-attr">Color</span>=<span class="hljs-string">"Red"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary</span>&gt;</span>
            <span class="hljs-comment">&lt;!-- HighContrast is used in any high contrast theme --&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"HighContrast"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">SolidColorBrush</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"BrandedPageBackground"</span> <span class="hljs-attr">Color</span>=<span class="hljs-string">"{ThemeResource SystemColorWindowColor}"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary.ThemeDictionaries</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Application.Resources</span>&gt;</span></code></pre><p>If you stick to this palette of 8 high contrast colors, you don’t have to create any additional high contrast ResourceDictionaries. This limited palette can often present difficult challenges in representing complex visual states. My advice is to look at other areas of Windows (like Start) and see how they solved a similar issue. Often, adding a border to an area <em>only</em> in high contrast can help bail you out of a situation.</p>
<h2 id="dos--donts">DOs &amp; DON’Ts</h2>
<ul>
<li><p><strong>DON’T</strong> put any Brushes that you create outside a <a href="http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.resourcedictionary.themedictionaries.aspx">ThemeDictionaries</a> collection</p>
</li>
<li><p><strong>DON’T</strong> ever use <a href="http://msdn.microsoft.com/en-us/library/windows/apps/hh758287.aspx">StaticResource</a> to reference a resource in a ThemeDictionaries collection. This will appear to work until the user changes themes while your app is running. Use <a href="http://msdn.microsoft.com/en-us/library/windows/apps/dn263118.aspx">ThemeResource</a> instead</p>
</li>
<li><p><strong>DO</strong> put primitives like Color, Brush, and Thickness inside of ThemeDictionaries. <strong>Avoid</strong> putting more complex resources like Styles in them. The following situation works fine:</p>
</li>
</ul>
<pre class="hljs"><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Application.Resources</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary.ThemeDictionaries</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">ResourceDictionary</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"Default"</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">SolidColorBrush</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"BrandedPageBackground"</span> <span class="hljs-attr">Color</span>=<span class="hljs-string">"Red"</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary.ThemeDictionaries</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">Style</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">"MyButtonStyle"</span> <span class="hljs-attr">TargetType</span>=<span class="hljs-string">"Button"</span>&gt;</span><span class="xml">
            <span class="hljs-tag">&lt;<span class="hljs-name">Setter</span> <span class="hljs-attr">Property</span>=<span class="hljs-string">"Foreground"</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">"{ThemeResource BrandedPageBackground"</span> /&gt;</span>
        </span><span class="hljs-tag">&lt;/<span class="hljs-name">Style</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ResourceDictionary</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Application.Resources</span>&gt;</span>

...

<span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">Style</span>=<span class="hljs-string">"{StaticResource MyButtonStyle}"</span> /&gt;</span></code></pre><ul>
<li><strong>DO</strong> test high contrast early and often</li>
</ul>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducting the TextLine]]></title>
            <link>http://westonthayer.com/writing/2014/10/08/introducing-textline/</link>
            <guid>http://westonthayer.com/writing/2014/10/08/introducing-textline/</guid>
            <pubDate>Wed, 08 Oct 2014 00:00:00 GMT</pubDate>
            <description><![CDATA[UI frameworks should stop putting type in a box because it's counter to the design intent and doesn't withstand localization. I've created a prototype implementation of the TextLine paradigm in XAML.]]></description>
            <content:encoded><![CDATA[<p><em>tldr: UI frameworks should stop putting type in a box because it’s counter to the design intent and doesn’t withstand localization. I’ve created a prototype implementation of the TextLine paradigm in XAML.</em></p>
<p>I’ve been thinking a lot about the elements of good typography lately. Specifically, I’ve thought about aligning type to a <a href="http://en.wikipedia.org/wiki/Grid_%28graphic_design%29">grid</a> and how to technically achieve a grid-based design.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="baseline.png" alt="Type baseline" >
</figure>

<p>In the above example, the type’s baseline is snapped to a horizontal grid line. That’s not the only way to align type, but it’s very common. To learn about more, read about <a href="http://en.wikipedia.org/wiki/Typeface#Font_metrics">font metrics</a>. To illustrate the value in aligning type to the grid, see the below example. Which looks better - the top or the bottom image?</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="positioning.png" alt="Positioning" >
</figure>

<p>The top example is aligned by descender (the bottom of the <em>p</em>). While the descenders <em>do</em> form a horizontal line, the baseline is visually stronger in this situation. In most cases, designers choose the bottom option. The intent is that the bottom edge of the rectangle is on the same horizontal grid line as the type’s baseline.</p>
<h2 id="the-problem">The problem</h2>
<p>Once you start building, positioning your type by baseline is <em>hard</em>. Your UI framework doesn’t think like you. It puts type in a box that you position with positive (and sometimes negative) margins. You didn’t want to position type by box, you wanted to position type by baseline!</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="boxed.png" alt="Text in a box" >
</figure>

<p>That 25px can really only be determined by guess work. <a href="http://www.smashingmagazine.com/2012/12/17/css-baseline-the-good-the-bad-and-the-ugly/">Smashing Magazine</a> explains that in CSS:</p>
<blockquote>
<p>…the CSS line-height property doesn’t have an inherent concept of baseline, and each line of text is placed roughly in the middle of the element’s total height.</p>
</blockquote>
<p>“Roughly in the middle.” Yuck.</p>
<p>Some frameworks try to remedy the issue. Android has <a href="http://www.doubleencore.com/2013/10/shifty-baseline-alignment/">baseAligned</a>. CSS has <a href="http://www.w3schools.com/cssref/pr_pos_vertical-align.asp">vertical-align</a>. Both of these cause a good deal of <a href="http://css-tricks.com/what-is-vertical-align/">confusion</a>. Try as you might, you’ll find yourself tediously nudging your type into place using margins. You know what you want, why can’t the UI framework think like you do?!</p>
<h2 id="enter-textline">Enter TextLine</h2>
<p><strong>Let’s stop putting type in a box</strong>! Let’s think of type as curves that grow from a horizontal line that you get to position. Before, there was a box that <em>imprisoned</em> your type. Now, there’s a line that <em>grows</em> your type. Let’s call this paradigm <strong>TextLine</strong>.</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="positionbybaseline.png" alt="Position by baseline" >
</figure>

<p>Now positioning makes sense:</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="nobox.png" alt="No more type in a box" >
</figure>

<p>This paradigm extends to multi-line scenarios as well. The top margin simply applies to the first line, while the bottom margin applies to the last:</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="nobox-multiline.png" alt="Multiline scenario" >
</figure>

<p>The baseline just one font metric. There’s no need to limit yourself to it. Can type grow out of the cap height line? Yes it can! Center of the em-square? Sure!</p>
<p>With greater power comes greater responsibility. It’s up to you to give your type enough room to grow, else it could clip and be unreadable. But don’t worry it’s not that hard. Use <a href="http://en.wikipedia.org/wiki/Pseudolocalization">pseudolocalization</a> to see how much space the riskiest glyphs need, then set a top and bottom margin that is <em>at least</em> that much. I’ve found that I barely have to think about it in most cases.</p>
<h2 id="further-benefits-of-textline">Further benefits of TextLine</h2>
<p>This approach has added benefits when it comes time to localize your app. Localization can sometimes make things really ugly. Why? There aren’t very many font families that include the glyphs used in <em>all</em> of the most popular languages. To name a few:</p>
<ul>
<li>English</li>
<li>Chinese</li>
<li>Japanese</li>
<li>Spanish</li>
<li>French</li>
<li>German</li>
<li>Russian</li>
</ul>
<p>Even if your font family does support all of those, what if you ever want to support something more rare like Hindi, Thai, or Sanscrit?</p>
<p>If you have plans of going world-wide, odds are that you’ll need to substitute fonts based on the locale. If your type is in a box, the baseline will move. Why? Different fonts have different font metrics.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="segoevsmincho.png" alt="Segoe UI baseline vs MS Mincho" >
        <figcaption class="post-figure__caption"><p>Font metrics for Segoe UI (left) and MS Mincho (right) for the same font size.</p>
</figcaption>
</figure>

<p>Type in a box makes this a headache. You’d have to have different margins for different fonts. Localizing margins? Yuck! Now, it’s simple. You didn’t position a box, you positioned a baseline. Both fonts will render with the baseline in a visually pleasing location.</p>
<h2 id="prototype-implementation">Prototype implementation</h2>
<p>Bending our UI frameworks to treat type this way isn’t exactly easy. CSS doesn’t expose much about font metrics and unless you’re in a Canvas, JavaScript doesn’t either (although <a href="http://stackoverflow.com/questions/10247132/how-can-i-get-the-height-of-the-baseline-of-a-certain-font">here’s a neat hack</a> that can find the baseline, approximately).</p>
<p>XAML exposes baseline and cap height through the <a href="http://msdn.microsoft.com/en-us/library/windows/apps/xaml/windows.ui.xaml.textlinebounds.aspx">TextLineBounds</a> API. It’s a bit hacky, but you can get a <a href="https://github.com/Cryclops/prototypes-textline">simple implementation</a> stood up quickly using XAML’s <a href="http://msdn.microsoft.com/en-us/library/ms749011(v=vs.110).aspx">attached properties</a>. Here’s a screenshot:</p>
<figure class="post-figure post-figure--img post-figure--nocaption" >
    <img class="post-figure--img__img"  src="prototype.png" alt="Screenshot of Prototype" >
</figure>

<p>The “Page Title” and “Subtitle” are baseline-aligned. This annoying task has been made dead simple:</p>
<pre class="hljs"><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">TextBlock</span>
    <span class="hljs-attr">Text</span>=<span class="hljs-string">"Page Title"</span>
    <span class="hljs-attr">FontSize</span>=<span class="hljs-string">"48"</span>
    <span class="hljs-attr">...</span>
    <span class="hljs-attr">local:TextLine.Mode</span>=<span class="hljs-string">"Baseline"</span>
    <span class="hljs-attr">local:TextLine.Margin</span>=<span class="hljs-string">"120,96,0,0"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">TextBlock</span>
    <span class="hljs-attr">Text</span>=<span class="hljs-string">"Subtitle"</span>
    <span class="hljs-attr">FontSize</span>=<span class="hljs-string">"24"</span>
    <span class="hljs-attr">...</span>
    <span class="hljs-attr">local:TextLine.Mode</span>=<span class="hljs-string">"Baseline"</span>
    <span class="hljs-attr">local:TextLine.Margin</span>=<span class="hljs-string">"15,96,0,0"</span> /&gt;</span></code></pre><p>Note how both have a top <code>TextLine.Margin</code> of 96, even though they’re different font sizes.</p>
<p>Earlier, I mentioned that baseline doesn’t have to be the origin that type grows from. Cap height is another interesting metric because we frequently have to top-align type with images. This situation is illustrated by the red square next to the “This Horrible Herald’s Article” headline:</p>
<pre class="hljs"><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Rectangle</span> <span class="hljs-attr">Width</span>=<span class="hljs-string">"200"</span> <span class="hljs-attr">Height</span>=<span class="hljs-string">"200"</span> <span class="hljs-attr">Fill</span>=<span class="hljs-string">"Red"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">TextBlock</span>
    <span class="hljs-attr">Text</span>=<span class="hljs-string">"This Horrible Herald's Article"</span>
    <span class="hljs-attr">...</span>
    <span class="hljs-attr">local:TextLine.Mode</span>=<span class="hljs-string">"CapHeight"</span> /&gt;</span></code></pre><p>No need for a top margin on either. It just works the way you expect.</p>
<p>Check out the <a href="https://github.com/Cryclops/prototypes-textline">prototype on GitHub</a>. Unfortunately, there are some major issues with this simple implementation:</p>
<ul>
<li>Doesn’t work with multi-line TextBlocks</li>
<li>Grid’s Auto positioning system will clip the TextBlock unnecessarily because we’re changing the Margin late</li>
<li>Only supports the Baseline and CapHeight modes</li>
</ul>
<p>A full implementation is certainly possible if you stop using TextBlock and start using DWrite. Perhaps I’ll write one someday.</p>
<p>That’s it. Let me know what you think in the comments!</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A New Home]]></title>
            <link>http://westonthayer.com/writing/2014/10/05/a-new-home/</link>
            <guid>http://westonthayer.com/writing/2014/10/05/a-new-home/</guid>
            <pubDate>Sun, 05 Oct 2014 00:00:00 GMT</pubDate>
            <description><![CDATA[Switching blog engines.]]></description>
            <content:encoded><![CDATA[<p><em>Update: Jekyll is out, hand-rolled is in! Jekyll is hard enough to install on Windows that I wrote a quick blogging engine with node.js and gulp.</em></p>
<p>Before now, I’ve tended to write in many different locations. From now on, this will be the one-stop-shop for everything. It’s new! It’s fun! It was created using <a href="http://jekyllrb.com/">Jekyll</a>! You can find my previous writings here:</p>
<ul>
<li><a href="http://cryclops.com/">Cryclops Wordpress</a></li>
<li><a href="http://cryclops.quora.com/">Cryclops Quora</a></li>
</ul>
<h2 id="why-the-move">Why the move?</h2>
<p>I was tired of feeling out of control. Wordpress made me fret over how the database was backed up. Quora doesn’t allow me to customize the look. Jekyll was the answer to both of these problems. I got started using <a href="http://joshualande.com/jekyll-github-pages-poole/">Poole via this guide</a> and only had to do a handful of tweaks to the <a href="https://github.com/poole/poole">poole master</a> to get up and running.</p>
<p>Perhaps the only neat trick is a simple batch file that renames all of the <code>*.html</code> files to <code>*.php</code> to allow for PHP execution. This means it isn’t a truely static site, but it was the fastest way to pull in the existing <code>header.php</code> and <code>footer.php</code> look.</p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Case Study: Word on Tablets]]></title>
            <link>http://westonthayer.com/writing/2014/06/18/case-study-word/</link>
            <guid>http://westonthayer.com/writing/2014/06/18/case-study-word/</guid>
            <pubDate>Wed, 18 Jun 2014 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Microsoft Word is historically a <a href="https://en.wikipedia.org/wiki/WIMP_%28computing%29">WIMP</a> application – the UI was heavily optimized for mouse and keyboard input over the years. As the consumer market <a href="http://www.pewinternet.org/2015/04/01/us-smartphone-use-in-2015/">moves beyond the desktop</a> we set out to reimagine the Word experience for a variety of devices and inputs. Our goal was to increase overall user engagement on tablets, especially edits to existing documents.</p>
<p>Working on a small team lead by <a href="http://www.ruthkikin.com/">Ruth kikin-Gil</a>, we designed experiences for text selection, insertion, and the on-screen keyboard optimized for tablets.</p>
<h2 id="research">Research</h2>
<p>I started by reading up on market research from our awesome <a href="https://www.microsoft.com/en-us/usability/default.aspx">usability team</a> to get a sense of who buys tablets, who uses them, who might use them in the future, and <em>how</em> they’re used. Tablets are a fascinating device category with a large potential for growth.</p>
<blockquote>
<p>Customers buy tablets with hopes that they’ll get more done. Unfortunately, they often find the device falls short.</p>
</blockquote>
<p>To find out why there’s this mismatch between productivity expectations and reality, we turned to usability studies. We discovered a huge amount of pain working with text. Even the most basic document editing tasks are worlds more complex than tapping out a text message on your phone. Users were caught in an uncanny valley, attempting to use text interactions they learned on desktop computers, with a mouse and keyboard, with their fingers on a tablet. It rarely worked.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="heatmap.png" alt="Heatmap of the on-screen keyboard" >
        <figcaption class="post-figure__caption"><p>Users also had trouble typing on a tablet. To confirm this, we looked at analytics data. Backspace is the most frequently hit key.</p>
</figcaption>
</figure>

<p>At the time, Word wasn’t available on iPads or Android tablets, so I also looked at what the popular alternatives were on those platforms and took them for a test drive.</p>
<ul>
<li>iA Writer</li>
<li>iOS Notes app</li>
<li>QuickOffice</li>
<li>Google Docs</li>
</ul>
<h2 id="ideation">Ideation</h2>
<p>We did a lot of sketching, talking, and organizing to help identify the biggest areas that we could work on in several group brainstorming sessions.</p>
<figure class="post-figure post-figure--img" >
    <img class="post-figure--img__img"  src="postits.png" alt="Post-it notes with sketches of various ideas" >
        <figcaption class="post-figure__caption"><p>Rapid sketches for a <a href="https://en.wikipedia.org/wiki/Affinity_diagram">affinity diagramming</a> exercise.</p>
</figcaption>
</figure>

<p>The two largest problems that we agreed on were text selection and how annoying the on-screen keyboard was to invoke and dismiss.</p>
<h2 id="prototyping">Prototyping</h2>
<p>I was able to quickly take sketches to high-fidelity interactive prototypes by coding a native Windows app that was a “smoke and mirrors” replica of the real Word (the Ribbon was mostly images, only enabled specific flows).</p>
<figure class="post-figure post-figure--video" >
    <video class="post-figure--video__video" autoplay controls loop="true" poster="/work/word-on-tablets/keyboard-lock.png">
        <source src="/work/word-on-tablets/keyboard-lock.mp4" type="video/mp4">
        Dang, your browser doesn't seem to support HTML5 video. I didn't plan for this!
    </video>
      <figcaption class="post-figure__caption"><p>The prototype allowed text editing and formatting, as well as controlling the real on-screen keyboard.</p>
</figcaption>
</figure>

<p>This allowed us to test the prototype with coworkers and run usability studies where the participants to completed realistic tasks. It took dozens of iterations before we were confident enough in a solution to build it.</p>
<h2 id="telemetry">Telemetry</h2>
<p>While usability studies are a great tool, you haven’t succeeded until the numbers reflect that. In addition to looking at our engagement data, I wrote custom telemetry to determine whether our text selection model was frustrating.</p>
<figure class="post-figure post-figure--video" >
    <video class="post-figure--video__video" autoplay controls loop="" poster="/work/word-on-tablets/selection.png">
        <source src="/work/word-on-tablets/selection.mp4" type="video/mp4">
        Dang, your browser doesn't seem to support HTML5 video. I didn't plan for this!
    </video>
      <figcaption class="post-figure__caption"><p>Double-tap-to-select lets users carry forward their mouse and keyboard intuition to touch. The selection algorithm optimizes for whole words, but still provides character-level selections if you backtrack slightly. Was this frustrating?</p>
</figcaption>
</figure>

<p>The algorithm detected when a users finger was “wiggling” on a word while selecting (ex: they select forwards 3 characters, then backwards 2, then forwards 1 character, then backwards 1). We’d see this type of wiggling in the usability lab frustrating users. While we found a solution that worked in the lab, we weren’t as sure that would hold true for millions of users.</p>
<h2 id="conclusion">Conclusion</h2>
<p>We succeeded at increasing engagement in this iteration. We received positive feedback about the new features – they’re still there today when you try the Word app for tablets.</p>
]]></content:encoded>
        </item>
    </channel>
</rss>